OSDN Git Service

* gcse.c: Include cselib.h
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 20 Jul 2002 22:56:05 +0000 (22:56 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Sat, 20 Jul 2002 22:56:05 +0000 (22:56 +0000)
(constptop_register): Break out from ...
(cprop_insn): ... here; kill basic_block argument.
(do_local_cprop, local_cprop_pass): New functions.
(one_cprop_pass): Call local_cprop_pass.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@55615 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/gcse.c

index 833b857..42cf042 100644 (file)
@@ -1,3 +1,11 @@
+Sun Jul 21 00:54:54 CEST 2002  Jan Hubicka  <jh@suse.cz>
+
+       * gcse.c: Include cselib.h
+       (constptop_register): Break out from ...
+       (cprop_insn): ... here; kill basic_block argument.
+       (do_local_cprop, local_cprop_pass): New functions.
+       (one_cprop_pass): Call local_cprop_pass.
+
 2002-07-20  Roger Sayle  <roger@eyesopen.com>
 
        * simplify-rtx.c (simplify_relational_operation): Optimize
index bb36211..d46f81b 100644 (file)
@@ -162,6 +162,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "except.h"
 #include "ggc.h"
 #include "params.h"
+#include "cselib.h"
 
 #include "obstack.h"
 #define obstack_chunk_alloc gmalloc
@@ -613,9 +614,10 @@ static int cprop_jump              PARAMS ((basic_block, rtx, rtx, rtx, rtx));
 static void mems_conflict_for_gcse_p PARAMS ((rtx, rtx, void *));
 static int load_killed_in_block_p    PARAMS ((basic_block, int, rtx, int));
 static void canon_list_insert        PARAMS ((rtx, rtx, void *));
-static int cprop_insn          PARAMS ((basic_block, rtx, int));
+static int cprop_insn          PARAMS ((rtx, int));
 static int cprop               PARAMS ((int));
 static int one_cprop_pass      PARAMS ((int, int));
+static bool constprop_register PARAMS ((rtx, rtx, rtx, int));
 static struct expr *find_bypass_set PARAMS ((int, int));
 static int bypass_block                    PARAMS ((basic_block, rtx, rtx));
 static int bypass_conditional_jumps PARAMS ((void));
@@ -701,6 +703,8 @@ 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));
+static bool do_local_cprop             PARAMS ((rtx, rtx, int));
+static void local_cprop_pass           PARAMS ((int));
 \f
 /* Entry point for global common subexpression elimination.
    F is the first instruction in the function.  */
@@ -4152,12 +4156,48 @@ cprop_jump (bb, setcc, jump, from, src)
   return 1;
 }
 
+static bool
+constprop_register (insn, from, to, alter_jumps)
+     rtx insn;
+     rtx from;
+     rtx to;
+     int alter_jumps;
+{
+  rtx sset;
+
+  /* Check for reg or cc0 setting instructions followed by
+     conditional branch instructions first.  */
+  if (alter_jumps
+      && (sset = single_set (insn)) != NULL
+      && any_condjump_p (NEXT_INSN (insn)) && onlyjump_p (NEXT_INSN (insn)))
+    {
+      rtx dest = SET_DEST (sset);
+      if ((REG_P (dest) || CC0_P (dest))
+         && cprop_jump (BLOCK_FOR_INSN (insn), insn, NEXT_INSN (insn), from, to))
+       return 1;
+    }
+
+  /* Handle normal insns next.  */
+  if (GET_CODE (insn) == INSN
+      && try_replace_reg (from, to, insn))
+    return 1;
+
+  /* Try to propagate a CONST_INT into a conditional jump.
+     We're pretty specific about what we will handle in this
+     code, we can extend this as necessary over time.
+
+     Right now the insn in question must look like
+     (set (pc) (if_then_else ...))  */
+  else if (alter_jumps && any_condjump_p (insn) && onlyjump_p (insn))
+    return cprop_jump (BLOCK_FOR_INSN (insn), NULL, insn, from, to);
+  return 0;
+}
+
 /* Perform constant and copy propagation on INSN.
    The result is non-zero if a change was made.  */
 
 static int
-cprop_insn (bb, insn, alter_jumps)
-     basic_block bb;
+cprop_insn (insn, alter_jumps)
      rtx insn;
      int alter_jumps;
 {
@@ -4210,56 +4250,18 @@ cprop_insn (bb, insn, alter_jumps)
       /* Constant propagation.  */
       if (CONSTANT_P (src))
        {
-         rtx sset;
-
-         /* Check for reg or cc0 setting instructions followed by
-            conditional branch instructions first.  */
-         if (alter_jumps
-             && (sset = single_set (insn)) != NULL
-             && any_condjump_p (NEXT_INSN (insn))
-             && onlyjump_p (NEXT_INSN (insn)))
-           {
-             rtx dest = SET_DEST (sset);
-             if ((REG_P (dest) || CC0_P (dest))
-                 && cprop_jump (bb, insn, NEXT_INSN (insn),
-                                reg_used->reg_rtx, src))
-               {
-                 changed = 1;
-                 break;
-               }
-           }
-
-         /* Handle normal insns next.  */
-         if (GET_CODE (insn) == INSN
-             && try_replace_reg (reg_used->reg_rtx, src, insn))
+          if (constprop_register (insn, reg_used->reg_rtx, src, alter_jumps))
            {
              changed = 1;
              const_prop_count++;
              if (gcse_file != NULL)
                {
-                 fprintf (gcse_file, "CONST-PROP: Replacing reg %d in ",
-                          regno);
-                 fprintf (gcse_file, "insn %d with constant ",
-                          INSN_UID (insn));
+                 fprintf (gcse_file, "GLOBAL CONST-PROP: Replacing reg %d in ", regno);
+                 fprintf (gcse_file, "insn %d with constant ", INSN_UID (insn));
                  print_rtl (gcse_file, src);
                  fprintf (gcse_file, "\n");
                }
-
-             /* The original insn setting reg_used may or may not now be
-                deletable.  We leave the deletion to flow.  */
            }
-
-         /* Try to propagate a CONST_INT into a conditional jump.
-            We're pretty specific about what we will handle in this
-            code, we can extend this as necessary over time.
-
-            Right now the insn in question must look like
-            (set (pc) (if_then_else ...))  */
-         else if (alter_jumps
-                  && any_condjump_p (insn)
-                  && onlyjump_p (insn))
-           changed |= cprop_jump (bb, NULL, insn, reg_used->reg_rtx, src);
-
        }
       else if (GET_CODE (src) == REG
               && REGNO (src) >= FIRST_PSEUDO_REGISTER
@@ -4271,7 +4273,7 @@ cprop_insn (bb, insn, alter_jumps)
              copy_prop_count++;
              if (gcse_file != NULL)
                {
-                 fprintf (gcse_file, "COPY-PROP: Replacing reg %d in insn %d",
+                 fprintf (gcse_file, "GLOBAL COPY-PROP: Replacing reg %d in insn %d",
                           regno, INSN_UID (insn));
                  fprintf (gcse_file, " with reg %d\n", REGNO (src));
                }
@@ -4288,6 +4290,96 @@ cprop_insn (bb, insn, alter_jumps)
   return changed;
 }
 
+static bool
+do_local_cprop (x, insn, alter_jumps)
+     rtx x;
+     rtx insn;
+     int alter_jumps;
+{
+  rtx newreg = NULL, newcnst = NULL;
+
+  /* Rule out USE instructions and ASM statements as we don't want to change the hard
+     registers mentioned.  */
+  if (GET_CODE (x) == REG
+      && (REGNO (x) >= FIRST_PSEUDO_REGISTER
+          || (GET_CODE (PATTERN (insn)) != USE && asm_noperands (PATTERN (insn)) < 0)))
+    {
+      cselib_val *val = cselib_lookup (x, GET_MODE (x), 0);
+      struct elt_loc_list *l;
+
+      if (!val)
+       return false;
+      for (l = val->locs; l; l = l->next)
+       {
+         rtx this_rtx = l->loc;
+         if (CONSTANT_P (this_rtx))
+           newcnst = this_rtx;
+         if (REG_P (this_rtx) && REGNO (this_rtx) >= FIRST_PSEUDO_REGISTER)
+           newreg = this_rtx;
+       }
+      if (newcnst && constprop_register (insn, x, newcnst, alter_jumps))
+       {
+         if (gcse_file != NULL)
+           {
+             fprintf (gcse_file, "LOCAL CONST-PROP: Replacing reg %d in ",
+                      REGNO (x));
+             fprintf (gcse_file, "insn %d with constant ",
+                      INSN_UID (insn));
+             print_rtl (gcse_file, newcnst);
+             fprintf (gcse_file, "\n");
+           }
+         const_prop_count++;
+         return true;
+       }
+      else if (newreg && newreg != x && try_replace_reg (x, newreg, insn))
+       {
+         if (gcse_file != NULL)
+           {
+             fprintf (gcse_file,
+                      "LOCAL COPY-PROP: Replacing reg %d in insn %d",
+                      REGNO (x), INSN_UID (insn));
+             fprintf (gcse_file, " with reg %d\n", REGNO (newreg));
+           }
+         copy_prop_count++;
+         return true;
+       }
+    }
+  return false;
+}
+
+static void
+local_cprop_pass (alter_jumps)
+     int alter_jumps;
+{
+  rtx insn;
+  struct reg_use *reg_used;
+
+  cselib_init ();
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    {
+      if (INSN_P (insn))
+       {
+         rtx note = find_reg_equal_equiv_note (insn);
+
+         do
+           {
+             reg_use_count = 0;
+             note_uses (&PATTERN (insn), find_used_regs, NULL);
+             if (note)
+               find_used_regs (&XEXP (note, 0), NULL);
+
+             for (reg_used = &reg_use_table[0]; reg_use_count > 0;
+                  reg_used++, reg_use_count--)
+               if (do_local_cprop (reg_used->reg_rtx, insn, alter_jumps))
+                 break;
+           }
+         while (reg_use_count);
+       }
+      cselib_process_insn (insn);
+    }
+  cselib_finish ();
+}
+
 /* Forward propagate copies.  This includes copies and constants.  Return
    non-zero if a change was made.  */
 
@@ -4319,7 +4411,7 @@ cprop (alter_jumps)
           insn = NEXT_INSN (insn))
        if (INSN_P (insn))
          {
-           changed |= cprop_insn (bb, insn, alter_jumps);
+           changed |= cprop_insn (insn, alter_jumps);
 
            /* Keep track of everything modified by this insn.  */
            /* ??? Need to be careful w.r.t. mods done to INSN.  Don't
@@ -4349,6 +4441,8 @@ one_cprop_pass (pass, alter_jumps)
   const_prop_count = 0;
   copy_prop_count = 0;
 
+  local_cprop_pass (alter_jumps);
+
   alloc_set_hash_table (max_cuid);
   compute_set_hash_table ();
   if (gcse_file)