gcse.c (gcse_emit_move_after): New.
authorJan Hubicka <jh@suse.cz>
Fri, 31 May 2002 11:43:18 +0000 (13:43 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Fri, 31 May 2002 11:43:18 +0000 (11:43 +0000)
* gcse.c (gcse_emit_move_after): New.
(pre_delete, hoist_store): Use it.

* reload1.c (emit_input_reload_insns): Use constrain_operands
instead of constraint_accepts_reg_p to verify optimization.
(constraint_accepts_reg_p): Kill

* reload1.c (reload_cse_delete_noop_set): Kill.
(reload_cse_simplify): use delte_insn_and_edges.

From-SVN: r54105

gcc/ChangeLog
gcc/gcse.c
gcc/gengenrtl.c
gcc/reload1.c

index b2027582869173fa24a41e94184fc184cc75cbfe..77386f33af3d5382a1d502e4bb362ce65b6a58dc 100644 (file)
@@ -1,3 +1,15 @@
+Fri May 31 13:37:54 CEST 2002  Jan Hubicka  <jh@suse.cz>
+
+       * gcse.c (gcse_emit_move_after): New.
+       (pre_delete, hoist_store): Use it.
+
+       * reload1.c (emit_input_reload_insns): Use constrain_operands
+       instead of constraint_accepts_reg_p to verify optimization.
+       (constraint_accepts_reg_p): Kill
+
+       * reload1.c (reload_cse_delete_noop_set): Kill.
+       (reload_cse_simplify): use delte_insn_and_edges.
+
 2002-05-31  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>
 
        * cfgloop.c (flow_loops_find): Initialize first and last fields
index f279dde90af08baba2914cda7d5ed933909b9f0c..4d7c154113327b56839ebceaea10a5fcce6deeff 100644 (file)
@@ -700,6 +700,7 @@ static void store_motion            PARAMS ((void));
 static void free_insn_expr_list_list   PARAMS ((rtx *));
 static void clear_modify_mem_tables    PARAMS ((void));
 static void free_modify_mem_tables     PARAMS ((void));
+static rtx gcse_emit_move_after                PARAMS ((rtx, rtx, rtx));
 \f
 /* Entry point for global common subexpression elimination.
    F is the first instruction in the function.  */
@@ -4948,6 +4949,33 @@ pre_insert_copies ()
       }
 }
 
+/* Emit move from SRC to DEST noting the equivalence with expression computed
+   in INSN.  */
+static rtx
+gcse_emit_move_after (src, dest, insn)
+     rtx src, dest, insn;
+{
+  rtx new;
+  rtx set = single_set (insn);
+  rtx note;
+  rtx eqv;
+
+  /* This should never fail since we're creating a reg->reg copy
+     we've verified to be valid.  */
+
+  new = emit_insn_after (gen_rtx_SET (VOIDmode, dest, src), insn);
+
+  /* Note the equivalence for local CSE pass.  */
+  if ((note = find_reg_equal_equiv_note (insn)))
+    eqv = XEXP (note, 0);
+  else
+    eqv = SET_SRC (set);
+
+  set_unique_reg_note (new, REG_EQUAL, copy_insn_1 (src));
+
+  return new;
+}
+
 /* Delete redundant computations.
    Deletion is done by changing the insn to copy the `reaching_reg' of
    the expression into the result of the SET.  It is left to later passes
@@ -4991,21 +5019,12 @@ pre_delete ()
                  expr->reaching_reg
                    = gen_reg_rtx (GET_MODE (SET_DEST (set)));
 
-               /* In theory this should never fail since we're creating
-                  a reg->reg copy.
-
-                  However, on the x86 some of the movXX patterns actually
-                  contain clobbers of scratch regs.  This may cause the
-                  insn created by validate_change to not match any pattern
-                  and thus cause validate_change to fail.  */
-               if (validate_change (insn, &SET_SRC (set),
-                                    expr->reaching_reg, 0))
-                 {
-                   occr->deleted_p = 1;
-                   SET_BIT (pre_redundant_insns, INSN_CUID (insn));
-                   changed = 1;
-                   gcse_subst_count++;
-                 }
+               gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
+               delete_insn (insn);
+               occr->deleted_p = 1;
+               SET_BIT (pre_redundant_insns, INSN_CUID (insn));
+               changed = 1;
+               gcse_subst_count++;
 
                if (gcse_file)
                  {
@@ -5827,23 +5846,13 @@ hoist_code ()
                        expr->reaching_reg
                          = gen_reg_rtx (GET_MODE (SET_DEST (set)));
 
-                     /* In theory this should never fail since we're creating
-                        a reg->reg copy.
-
-                        However, on the x86 some of the movXX patterns
-                        actually contain clobbers of scratch regs.  This may
-                        cause the insn created by validate_change to not
-                        match any pattern and thus cause validate_change to
-                        fail.  */
-                     if (validate_change (insn, &SET_SRC (set),
-                                          expr->reaching_reg, 0))
+                     gcse_emit_move_after (expr->reaching_reg, SET_DEST (set), insn);
+                     delete_insn (insn);
+                     occr->deleted_p = 1;
+                     if (!insn_inserted_p)
                        {
-                         occr->deleted_p = 1;
-                         if (!insn_inserted_p)
-                           {
-                             insert_insn_end_bb (index_map[i], bb, 0);
-                             insn_inserted_p = 1;
-                           }
+                         insert_insn_end_bb (index_map[i], bb, 0);
+                         insn_inserted_p = 1;
                        }
                    }
                }
index 07de2170f4ab7f8d872f894e5c380af1564d6560..31e5910f2377e4efb36a4d64d654c86e5fb3b1e1 100644 (file)
@@ -119,6 +119,9 @@ accessor_from_format (c)
 
     case 'B':
       return "XBBDEF";
+
+    default:
+      abort ();
     }
 }
 
index 685957023c4dcd5addcd4f466bc18aadaed17b18..1ce3199cd9800eac72e645bf283390b6f516a834 100644 (file)
@@ -440,7 +440,6 @@ static void delete_output_reload    PARAMS ((rtx, int, int));
 static void delete_address_reloads     PARAMS ((rtx, rtx));
 static void delete_address_reloads_1   PARAMS ((rtx, rtx, rtx));
 static rtx inc_for_reload              PARAMS ((rtx, rtx, rtx, int));
-static int constraint_accepts_reg_p    PARAMS ((const char *, rtx));
 static void reload_cse_regs_1          PARAMS ((rtx));
 static int reload_cse_noop_set_p       PARAMS ((rtx));
 static int reload_cse_simplify_set     PARAMS ((rtx, rtx));
@@ -458,7 +457,6 @@ static HOST_WIDE_INT sext_for_mode  PARAMS ((enum machine_mode,
                                                 HOST_WIDE_INT));
 static void failed_reload              PARAMS ((rtx, int));
 static int set_reload_reg              PARAMS ((int, int));
-static void reload_cse_delete_noop_set PARAMS ((rtx, rtx));
 static void reload_cse_simplify                PARAMS ((rtx));
 void fixup_abnormal_edges              PARAMS ((void));
 extern void dump_needs                 PARAMS ((struct insn_chain *));
@@ -6383,38 +6381,43 @@ emit_input_reload_insns (chain, rl, old, j)
          && SET_DEST (PATTERN (temp)) == old
          /* Make sure we can access insn_operand_constraint.  */
          && asm_noperands (PATTERN (temp)) < 0
-         /* This is unsafe if prev insn rejects our reload reg.  */
-         && constraint_accepts_reg_p (insn_data[recog_memoized (temp)].operand[0].constraint,
-                                      reloadreg)
          /* This is unsafe if operand occurs more than once in current
             insn.  Perhaps some occurrences aren't reloaded.  */
-         && count_occurrences (PATTERN (insn), old, 0) == 1
-         /* Don't risk splitting a matching pair of operands.  */
-         && ! reg_mentioned_p (old, SET_SRC (PATTERN (temp))))
+         && count_occurrences (PATTERN (insn), old, 0) == 1)
        {
+         rtx old = SET_DEST (PATTERN (temp));
          /* Store into the reload register instead of the pseudo.  */
          SET_DEST (PATTERN (temp)) = reloadreg;
 
-         /* If the previous insn is an output reload, the source is
-            a reload register, and its spill_reg_store entry will
-            contain the previous destination.  This is now
-            invalid.  */
-         if (GET_CODE (SET_SRC (PATTERN (temp))) == REG
-             && REGNO (SET_SRC (PATTERN (temp))) < FIRST_PSEUDO_REGISTER)
+         /* Verify that resulting insn is valid.  */
+         extract_insn (temp);
+         if (constrain_operands (1))
            {
-             spill_reg_store[REGNO (SET_SRC (PATTERN (temp)))] = 0;
-             spill_reg_stored_to[REGNO (SET_SRC (PATTERN (temp)))] = 0;
-           }
+             /* If the previous insn is an output reload, the source is
+                a reload register, and its spill_reg_store entry will
+                contain the previous destination.  This is now
+                invalid.  */
+             if (GET_CODE (SET_SRC (PATTERN (temp))) == REG
+                 && REGNO (SET_SRC (PATTERN (temp))) < FIRST_PSEUDO_REGISTER)
+               {
+                 spill_reg_store[REGNO (SET_SRC (PATTERN (temp)))] = 0;
+                 spill_reg_stored_to[REGNO (SET_SRC (PATTERN (temp)))] = 0;
+               }
 
-         /* If these are the only uses of the pseudo reg,
-            pretend for GDB it lives in the reload reg we used.  */
-         if (REG_N_DEATHS (REGNO (old)) == 1
-             && REG_N_SETS (REGNO (old)) == 1)
+             /* If these are the only uses of the pseudo reg,
+                pretend for GDB it lives in the reload reg we used.  */
+             if (REG_N_DEATHS (REGNO (old)) == 1
+                 && REG_N_SETS (REGNO (old)) == 1)
+               {
+                 reg_renumber[REGNO (old)] = REGNO (rl->reg_rtx);
+                 alter_reg (REGNO (old), -1);
+               }
+             special = 1;
+           }
+         else
            {
-             reg_renumber[REGNO (old)] = REGNO (rl->reg_rtx);
-             alter_reg (REGNO (old), -1);
+             SET_DEST (PATTERN (temp)) = old;
            }
-         special = 1;
        }
     }
 
@@ -7980,75 +7983,6 @@ inc_for_reload (reloadreg, in, value, inc_amount)
   return store;
 }
 \f
-/* Return 1 if we are certain that the constraint-string STRING allows
-   the hard register REG.  Return 0 if we can't be sure of this.  */
-
-static int
-constraint_accepts_reg_p (string, reg)
-     const char *string;
-     rtx reg;
-{
-  int value = 0;
-  int regno = true_regnum (reg);
-  int c;
-
-  /* Initialize for first alternative.  */
-  value = 0;
-  /* Check that each alternative contains `g' or `r'.  */
-  while (1)
-    switch (c = *string++)
-      {
-      case 0:
-       /* If an alternative lacks `g' or `r', we lose.  */
-       return value;
-      case ',':
-       /* If an alternative lacks `g' or `r', we lose.  */
-       if (value == 0)
-         return 0;
-       /* Initialize for next alternative.  */
-       value = 0;
-       break;
-      case 'g':
-      case 'r':
-       /* Any general reg wins for this alternative.  */
-       if (TEST_HARD_REG_BIT (reg_class_contents[(int) GENERAL_REGS], regno))
-         value = 1;
-       break;
-      default:
-       /* Any reg in specified class wins for this alternative.  */
-       {
-         enum reg_class class = REG_CLASS_FROM_LETTER (c);
-
-         if (TEST_HARD_REG_BIT (reg_class_contents[(int) class], regno))
-           value = 1;
-       }
-      }
-}
-\f
-/* INSN is a no-op; delete it.
-   If this sets the return value of the function, we must keep a USE around,
-   in case this is in a different basic block than the final USE.  Otherwise,
-   we could loose important register lifeness information on
-   SMALL_REGISTER_CLASSES machines, where return registers might be used as
-   spills:  subsequent passes assume that spill registers are dead at the end
-   of a basic block.
-   VALUE must be the return value in such a case, NULL otherwise.  */
-static void
-reload_cse_delete_noop_set (insn, value)
-     rtx insn, value;
-{
-  bool purge = BLOCK_FOR_INSN (insn)->end == insn;
-  if (value)
-    {
-      PATTERN (insn) = gen_rtx_USE (VOIDmode, value);
-      INSN_CODE (insn) = -1;
-      REG_NOTES (insn) = NULL_RTX;
-    }
-  else
-    delete_insn (insn);
-  if (purge)
-    purge_dead_edges (BLOCK_FOR_INSN (insn));
-}
 
 /* See whether a single set SET is a noop.  */
 static int
@@ -8082,7 +8016,7 @@ reload_cse_simplify (insn)
          if (REG_P (value)
              && ! REG_FUNCTION_VALUE_P (value))
            value = 0;
-         reload_cse_delete_noop_set (insn, value);
+         delete_insn_and_edges (insn);
          return;
        }
 
@@ -8119,7 +8053,7 @@ reload_cse_simplify (insn)
 
       if (i < 0)
        {
-         reload_cse_delete_noop_set (insn, value);
+         delete_insn_and_edges (insn);
          /* We're done with this insn.  */
          return;
        }