loop.c (count_one_set): New static function, broken out of count_loop_regs_set
authorBernd Schmidt <crux@pool.informatik.rwth-aachen.de>
Tue, 6 Oct 1998 20:38:40 +0000 (14:38 -0600)
committerJeff Law <law@gcc.gnu.org>
Tue, 6 Oct 1998 20:38:40 +0000 (14:38 -0600)
* loop.c (count_one_set): New static function, broken out of
count_loop_regs_set
(count_loop_regs_set): Call it.
* global.c (mark_reg_store): Handle clobbers here by not calling
set_preference.
(mark_reg_clobber): Just call mark_reg_store after ensuring SETTER
is in fact a clobber.
* integrate.c (process_reg_param): New function, broken out of
expand_inline_function.
(expand_inline_function): Call it.

From-SVN: r22875

gcc/ChangeLog
gcc/global.c
gcc/integrate.c
gcc/loop.c

index bdb86557458d2dd73a9cd617b9688f609e887533..85d9497c7df53221af91146b06c9c60427fdaf37 100644 (file)
@@ -23,6 +23,18 @@ Tue Oct  6 17:00:42 1998  J"orn Rennecke <amylaar@cygnus.co.uk>
 
 Tue Oct  6 01:36:00 1998  Bernd Schmidt <crux@Pool.Informatik.RWTH-Aachen.DE>
 
+       * loop.c (count_one_set): New static function, broken out of
+       count_loop_regs_set
+       (count_loop_regs_set): Call it.
+       * global.c (mark_reg_store): Handle clobbers here by not calling
+       set_preference.
+       (mark_reg_clobber): Just call mark_reg_store after ensuring SETTER
+       is in fact a clobber.
+       * integrate.c (process_reg_param): New function, broken out of
+       expand_inline_function.
+       (expand_inline_function): Call it.
+
+
        * i386.md (addsidi3_1): Delete unused variable temp.
        (addsidi3_2): Likewise.
        (clstrstrsi): Delete unused variable addr1.
index 04a836c0003b2c9b87b40122b44ad18a6d8fe45c..0bacc2381722a6197fedfa13c5e59d8e0854faad 100644 (file)
@@ -1323,16 +1323,13 @@ record_conflicts (allocno_vec, len)
    if so, we do nothing.
 
    SETTER is 0 if this register was modified by an auto-increment (i.e.,
-   a REG_INC note was found for it).
-
-   CLOBBERs are processed here by calling mark_reg_clobber.  */ 
+   a REG_INC note was found for it).  */
 
 static void
-mark_reg_store (orig_reg, setter)
-     rtx orig_reg, setter;
+mark_reg_store (reg, setter)
+     rtx reg, setter;
 {
   register int regno;
-  register rtx reg = orig_reg;
 
   /* WORD is which word of a multi-register group is being stored.
      For the case where the store is actually into a SUBREG of REG.
@@ -1349,16 +1346,9 @@ mark_reg_store (orig_reg, setter)
   if (GET_CODE (reg) != REG)
     return;
 
-  if (setter && GET_CODE (setter) == CLOBBER)
-    {
-      /* A clobber of a register should be processed here too.  */
-      mark_reg_clobber (orig_reg, setter);
-      return;
-    }
-
   regs_set[n_regs_set++] = reg;
 
-  if (setter)
+  if (setter && GET_CODE (setter) != CLOBBER)
     set_preference (reg, SET_SRC (setter));
 
   regno = REGNO (reg);
@@ -1396,55 +1386,8 @@ static void
 mark_reg_clobber (reg, setter)
      rtx reg, setter;
 {
-  register int regno;
-
-  /* WORD is which word of a multi-register group is being stored.
-     For the case where the store is actually into a SUBREG of REG.
-     Except we don't use it; I believe the entire REG needs to be
-     made live.  */
-  int word = 0;
-
-  if (GET_CODE (setter) != CLOBBER)
-    return;
-
-  if (GET_CODE (reg) == SUBREG)
-    {
-      word = SUBREG_WORD (reg);
-      reg = SUBREG_REG (reg);
-    }
-
-  if (GET_CODE (reg) != REG)
-    return;
-
-  regs_set[n_regs_set++] = reg;
-
-  regno = REGNO (reg);
-
-  /* Either this is one of the max_allocno pseudo regs not allocated,
-     or it is or has a hardware reg.  First handle the pseudo-regs.  */
-  if (regno >= FIRST_PSEUDO_REGISTER)
-    {
-      if (reg_allocno[regno] >= 0)
-       {
-         SET_ALLOCNO_LIVE (reg_allocno[regno]);
-         record_one_conflict (regno);
-       }
-    }
-
-  if (reg_renumber[regno] >= 0)
-    regno = reg_renumber[regno] /* + word */;
-
-  /* Handle hardware regs (and pseudos allocated to hard regs).  */
-  if (regno < FIRST_PSEUDO_REGISTER && ! fixed_regs[regno])
-    {
-      register int last = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
-      while (regno < last)
-       {
-         record_one_conflict (regno);
-         SET_HARD_REG_BIT (hard_regs_live, regno);
-         regno++;
-       }
-    }
+  if (GET_CODE (setter) == CLOBBER)
+    mark_reg_store (reg, setter);
 }
 
 /* Record that REG has conflicts with all the regs currently live.
index db82e322b064af339d30805c37bad3cf152a244f..76ccf5f59b51a71820162d83d79bbace73641bcd 100644 (file)
@@ -59,25 +59,31 @@ extern struct obstack *function_maybepermanent_obstack;
    : (8 * (8 + list_length (DECL_ARGUMENTS (DECL)))))
 #endif
 \f
-static rtx initialize_for_inline PROTO((tree, int, int, int, int));
-static void finish_inline      PROTO((tree, rtx));
-static void adjust_copied_decl_tree PROTO((tree));
-static tree copy_decl_list     PROTO((tree));
-static tree copy_decl_tree     PROTO((tree));
-static void copy_decl_rtls     PROTO((tree));
-static void save_constants     PROTO((rtx *));
-static void note_modified_parmregs PROTO((rtx, rtx));
-static rtx copy_for_inline     PROTO((rtx));
-static void integrate_parm_decls PROTO((tree, struct inline_remap *, rtvec));
-static void integrate_decl_tree        PROTO((tree, int, struct inline_remap *));
+static rtx initialize_for_inline       PROTO((tree, int, int, int, int));
+static void finish_inline              PROTO((tree, rtx));
+static void adjust_copied_decl_tree    PROTO((tree));
+static tree copy_decl_list             PROTO((tree));
+static tree copy_decl_tree             PROTO((tree));
+static void copy_decl_rtls             PROTO((tree));
+static void save_constants             PROTO((rtx *));
+static void note_modified_parmregs     PROTO((rtx, rtx));
+static rtx copy_for_inline             PROTO((rtx));
+static void integrate_parm_decls       PROTO((tree, struct inline_remap *,
+                                              rtvec));
+static void integrate_decl_tree                PROTO((tree, int,
+                                              struct inline_remap *));
 static void save_constants_in_decl_trees PROTO ((tree));
-static void subst_constants    PROTO((rtx *, rtx, struct inline_remap *));
-static void restore_constants  PROTO((rtx *));
-static void set_block_origin_self PROTO((tree));
-static void set_decl_origin_self PROTO((tree));
-static void set_block_abstract_flags PROTO((tree, int));
+static void subst_constants            PROTO((rtx *, rtx,
+                                              struct inline_remap *));
+static void restore_constants          PROTO((rtx *));
+static void set_block_origin_self      PROTO((tree));
+static void set_decl_origin_self       PROTO((tree));
+static void set_block_abstract_flags   PROTO((tree, int));
+static void process_reg_param          PROTO((struct inline_remap *, rtx,
+                                              rtx));
 
-void set_decl_abstract_flags   PROTO((tree, int));
+
+void set_decl_abstract_flags           PROTO((tree, int));
 static tree copy_and_set_decl_abstract_origin PROTO((tree));
 \f
 /* Returns the Ith entry in the label_map contained in MAP.  If the
@@ -1300,6 +1306,38 @@ int global_const_equiv_map_size;
    && REGNO (XEXP (X, 0)) >= FIRST_VIRTUAL_REGISTER            \
    && REGNO (XEXP (X, 0)) <= LAST_VIRTUAL_REGISTER)
 
+/* Called to set up a mapping for the case where a parameter is in a
+   register.  If it is read-only and our argument is a constant, set up the
+   constant equivalence.
+
+   If LOC is REG_USERVAR_P, the usual case, COPY must also have that flag set
+   if it is a register.
+
+   Also, don't allow hard registers here; they might not be valid when
+   substituted into insns.  */
+static void
+process_reg_param (map, loc, copy)
+     struct inline_remap *map;
+     rtx loc, copy;
+{
+  if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
+      || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
+         && ! REG_USERVAR_P (copy))
+      || (GET_CODE (copy) == REG
+         && REGNO (copy) < FIRST_PSEUDO_REGISTER))
+    {
+      rtx temp = copy_to_mode_reg (GET_MODE (loc), copy);
+      REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
+      if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
+         && REGNO (temp) < map->const_equiv_map_size)
+       {
+         map->const_equiv_map[REGNO (temp)] = copy;
+         map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
+       }
+      copy = temp;
+    }
+  map->reg_map[REGNO (loc)] = copy;
+}
 /* Integrate the procedure defined by FNDECL.  Note that this function
    may wind up calling itself.  Since the static variables are not
    reentrant, we do not assign them until after the possibility
@@ -1610,87 +1648,16 @@ expand_inline_function (fndecl, parms, target, ignore, type,
          ;
        }
       else if (GET_CODE (loc) == REG)
-       {
-         /* This is the good case where the parameter is in a register.
-            If it is read-only and our argument is a constant, set up the
-            constant equivalence.
-
-            If LOC is REG_USERVAR_P, the usual case, COPY must also have
-            that flag set if it is a register.
-
-            Also, don't allow hard registers here; they might not be valid
-            when substituted into insns.  */
-
-         if ((GET_CODE (copy) != REG && GET_CODE (copy) != SUBREG)
-             || (GET_CODE (copy) == REG && REG_USERVAR_P (loc)
-                 && ! REG_USERVAR_P (copy))
-             || (GET_CODE (copy) == REG
-                 && REGNO (copy) < FIRST_PSEUDO_REGISTER))
-           {
-             temp = copy_to_mode_reg (GET_MODE (loc), copy);
-             REG_USERVAR_P (temp) = REG_USERVAR_P (loc);
-             if ((CONSTANT_P (copy) || FIXED_BASE_PLUS_P (copy))
-                 && REGNO (temp) < map->const_equiv_map_size)
-               {
-                 map->const_equiv_map[REGNO (temp)] = copy;
-                 map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
-               }
-             copy = temp;
-           }
-         map->reg_map[REGNO (loc)] = copy;
-       }
+       process_reg_param (map, loc, copy);
       else if (GET_CODE (loc) == CONCAT)
        {
-         /* This is the good case where the parameter is in a
-            pair of separate pseudos.
-            If it is read-only and our argument is a constant, set up the
-            constant equivalence.
-
-            If LOC is REG_USERVAR_P, the usual case, COPY must also have
-            that flag set if it is a register.
-
-            Also, don't allow hard registers here; they might not be valid
-            when substituted into insns.  */
          rtx locreal = gen_realpart (GET_MODE (XEXP (loc, 0)), loc);
          rtx locimag = gen_imagpart (GET_MODE (XEXP (loc, 0)), loc);
          rtx copyreal = gen_realpart (GET_MODE (locreal), copy);
          rtx copyimag = gen_imagpart (GET_MODE (locimag), copy);
 
-         if ((GET_CODE (copyreal) != REG && GET_CODE (copyreal) != SUBREG)
-             || (GET_CODE (copyreal) == REG && REG_USERVAR_P (locreal)
-                 && ! REG_USERVAR_P (copyreal))
-             || (GET_CODE (copyreal) == REG
-                 && REGNO (copyreal) < FIRST_PSEUDO_REGISTER))
-           {
-             temp = copy_to_mode_reg (GET_MODE (locreal), copyreal);
-             REG_USERVAR_P (temp) = REG_USERVAR_P (locreal);
-             if ((CONSTANT_P (copyreal) || FIXED_BASE_PLUS_P (copyreal))
-                 && REGNO (temp) < map->const_equiv_map_size)
-               {
-                 map->const_equiv_map[REGNO (temp)] = copyreal;
-                 map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
-               }
-             copyreal = temp;
-           }
-         map->reg_map[REGNO (locreal)] = copyreal;
-
-         if ((GET_CODE (copyimag) != REG && GET_CODE (copyimag) != SUBREG)
-             || (GET_CODE (copyimag) == REG && REG_USERVAR_P (locimag)
-                 && ! REG_USERVAR_P (copyimag))
-             || (GET_CODE (copyimag) == REG
-                 && REGNO (copyimag) < FIRST_PSEUDO_REGISTER))
-           {
-             temp = copy_to_mode_reg (GET_MODE (locimag), copyimag);
-             REG_USERVAR_P (temp) = REG_USERVAR_P (locimag);
-             if ((CONSTANT_P (copyimag) || FIXED_BASE_PLUS_P (copyimag))
-                 && REGNO (temp) < map->const_equiv_map_size)
-               {
-                 map->const_equiv_map[REGNO (temp)] = copyimag;
-                 map->const_age_map[REGNO (temp)] = CONST_AGE_PARM;
-               }
-             copyimag = temp;
-           }
-         map->reg_map[REGNO (locimag)] = copyimag;
+         process_reg_param (map, locreal, copyreal);
+         process_reg_param (map, locimag, copyimag);
        }
       else
        abort ();
index 24f1b6d747986193e36bdcda209d972e3453f6db..f9a7d2e0a47cb1b0859bb704bf493902ed9414dc 100644 (file)
@@ -3313,6 +3313,51 @@ find_single_use_in_loop (insn, x, usage)
       }
 }
 \f
+/* Count and record any set in X which is contained in INSN.  Update
+   MAY_NOT_MOVE and LAST_SET for any register set in X.  */
+
+static void
+count_one_set (insn, x, may_not_move, last_set)
+     rtx insn, x;
+     varray_type may_not_move;
+     rtx *last_set;
+{
+  if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG)
+    /* Don't move a reg that has an explicit clobber.
+       It's not worth the pain to try to do it correctly.  */
+    VARRAY_CHAR (may_not_move, REGNO (XEXP (x, 0))) = 1;
+
+  if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
+    {
+      rtx dest = SET_DEST (x);
+      while (GET_CODE (dest) == SUBREG
+            || GET_CODE (dest) == ZERO_EXTRACT
+            || GET_CODE (dest) == SIGN_EXTRACT
+            || GET_CODE (dest) == STRICT_LOW_PART)
+       dest = XEXP (dest, 0);
+      if (GET_CODE (dest) == REG)
+       {
+         register int regno = REGNO (dest);
+         /* If this is the first setting of this reg
+            in current basic block, and it was set before,
+            it must be set in two basic blocks, so it cannot
+            be moved out of the loop.  */
+         if (VARRAY_INT (n_times_set, regno) > 0 
+             && last_set[regno] == 0)
+           VARRAY_CHAR (may_not_move, regno) = 1;
+         /* If this is not first setting in current basic block,
+            see if reg was used in between previous one and this.
+            If so, neither one can be moved.  */
+         if (last_set[regno] != 0
+             && reg_used_between_p (dest, last_set[regno], insn))
+           VARRAY_CHAR (may_not_move, regno) = 1;
+         if (VARRAY_INT (n_times_set, regno) < 127)
+           ++VARRAY_INT (n_times_set, regno);
+         last_set[regno] = insn;
+       }
+    }
+}
+
 /* Increment N_TIMES_SET at the index of each register
    that is modified by an insn between FROM and TO.
    If the value of an element of N_TIMES_SET becomes 127 or more,
@@ -3359,76 +3404,15 @@ count_loop_regs_set (from, to, may_not_move, single_usage, count_ptr, nregs)
                find_single_use_in_loop (insn, REG_NOTES (insn), single_usage);
            }
 
-         if (GET_CODE (PATTERN (insn)) == CLOBBER
-             && GET_CODE (XEXP (PATTERN (insn), 0)) == REG)
-           /* Don't move a reg that has an explicit clobber.
-              We might do so sometimes, but it's not worth the pain.  */
-           VARRAY_CHAR (may_not_move, REGNO (XEXP (PATTERN (insn), 0))) = 1;
-
          if (GET_CODE (PATTERN (insn)) == SET
              || GET_CODE (PATTERN (insn)) == CLOBBER)
-           {
-             dest = SET_DEST (PATTERN (insn));
-             while (GET_CODE (dest) == SUBREG
-                    || GET_CODE (dest) == ZERO_EXTRACT
-                    || GET_CODE (dest) == SIGN_EXTRACT
-                    || GET_CODE (dest) == STRICT_LOW_PART)
-               dest = XEXP (dest, 0);
-             if (GET_CODE (dest) == REG)
-               {
-                 register int regno = REGNO (dest);
-                 /* If this is the first setting of this reg
-                    in current basic block, and it was set before,
-                    it must be set in two basic blocks, so it cannot
-                    be moved out of the loop.  */
-                 if (VARRAY_INT (n_times_set, regno) > 0
-                     && last_set[regno] == 0)
-                   VARRAY_CHAR (may_not_move, regno) = 1;
-                 /* If this is not first setting in current basic block,
-                    see if reg was used in between previous one and this.
-                    If so, neither one can be moved.  */
-                 if (last_set[regno] != 0
-                     && reg_used_between_p (dest, last_set[regno], insn))
-                   VARRAY_CHAR (may_not_move, regno) = 1;
-                 if (VARRAY_INT (n_times_set, regno) < 127)
-                   ++VARRAY_INT (n_times_set, regno);
-                 last_set[regno] = insn;
-               }
-           }
+           count_one_set (insn, PATTERN (insn), may_not_move, last_set);
          else if (GET_CODE (PATTERN (insn)) == PARALLEL)
            {
              register int i;
              for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
-               {
-                 register rtx x = XVECEXP (PATTERN (insn), 0, i);
-                 if (GET_CODE (x) == CLOBBER && GET_CODE (XEXP (x, 0)) == REG)
-                   /* Don't move a reg that has an explicit clobber.
-                      It's not worth the pain to try to do it correctly.  */
-                   VARRAY_CHAR (may_not_move, REGNO (XEXP (x, 0))) = 1;
-
-                 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
-                   {
-                     dest = SET_DEST (x);
-                     while (GET_CODE (dest) == SUBREG
-                            || GET_CODE (dest) == ZERO_EXTRACT
-                            || GET_CODE (dest) == SIGN_EXTRACT
-                            || GET_CODE (dest) == STRICT_LOW_PART)
-                       dest = XEXP (dest, 0);
-                     if (GET_CODE (dest) == REG)
-                       {
-                         register int regno = REGNO (dest);
-                         if (VARRAY_INT (n_times_set, regno) > 0 
-                             && last_set[regno] == 0)
-                           VARRAY_CHAR (may_not_move, regno) = 1;
-                         if (last_set[regno] != 0
-                             && reg_used_between_p (dest, last_set[regno], insn))
-                           VARRAY_CHAR (may_not_move, regno) = 1;
-                         if (VARRAY_INT (n_times_set, regno) < 127)
-                           ++VARRAY_INT (n_times_set, regno);
-                         last_set[regno] = insn;
-                       }
-                   }
-               }
+               count_one_set (insn, XVECEXP (PATTERN (insn), 0, i),
+                              may_not_move, last_set);
            }
        }