]> gcc.gnu.org Git - gcc.git/commitdiff
common.opt: Add description of the new -fgcse-las flag.
authorMostafa Hagog <mustafa@il.ibm.com>
Fri, 17 Oct 2003 16:16:45 +0000 (16:16 +0000)
committerRoger Sayle <sayle@gcc.gnu.org>
Fri, 17 Oct 2003 16:16:45 +0000 (16:16 +0000)
2003-10-17  Mostafa Hagog  <mustafa@il.ibm.com>

* common.opt: Add description of the new -fgcse-las flag.
* flags.h (flag_gcse_las): Declaration of global flag_gcse_las.
* gcse.c (hash_scan_set): Handle the case of store expression and
insert the memory expression to the hash table, this way we make it
possible to discover redundant loads after stores and remove them.
(pre_insert_copy_insn): moved the call to update_ld_motion_stores,
to pre_insert_copies, it is not the correct place to call it after
adding stores to be in the available expression hash table.
(pre_insert_copies): Added the call to update_ld_motion_stores when
one or more copies were inserted.
* opts.c (common_handle_option): Handle the -fgcse-las flag.
* toplev.c (flag_gcse_las): Initialization of flag_gcse_las.

* doc/invoke.tex: Document new -fgcse-las flag.

From-SVN: r72612

gcc/ChangeLog
gcc/common.opt
gcc/doc/invoke.texi
gcc/flags.h
gcc/gcse.c
gcc/opts.c
gcc/toplev.c

index 5558cc535ba1299c4ff6bdbbd58c933b84afe70a..6cb9af49ec0e723f234c80b01d4c31a40b55dd1a 100644 (file)
@@ -1,3 +1,20 @@
+2003-10-17  Mostafa Hagog  <mustafa@il.ibm.com>
+
+       * common.opt: Add description of the new -fgcse-las flag.
+       * flags.h (flag_gcse_las): Declaration of global flag_gcse_las.
+       * gcse.c (hash_scan_set): Handle the case of store expression and
+       insert the memory expression to the hash table, this way we make it
+       possible to discover redundant loads after stores and remove them.
+       (pre_insert_copy_insn): moved the call to update_ld_motion_stores,
+       to pre_insert_copies, it is not the correct place to call it after
+       adding stores to be in the available expression hash table.
+       (pre_insert_copies): Added the call to update_ld_motion_stores when
+       one or more copies were inserted.
+       * opts.c (common_handle_option): Handle the -fgcse-las flag.
+       * toplev.c (flag_gcse_las): Initialization of flag_gcse_las.
+
+       * doc/invoke.tex: Document new -fgcse-las flag.
+
 2003-10-18  Alan Modra  <amodra@bigpond.net.au>
 
        * config/rs6000/crtsavres.asm: Correct alignment of powerpc64 code
index 26af2806a24d318517fe3712e161ffc38762c1ea..fdf28b214259a1841b498249d4af37e526fbb73b 100644 (file)
@@ -362,6 +362,10 @@ fgcse-sm
 Common
 Perform store motion after global common subexpression elimination
 
+fgcse-las
+Common
+Perform redundant load after store elimination in global common subexpression elimination
+
 fgnu-linker
 Common
 Output GNU ld formatted global initializers
index 474c9b711c714bc3581f8abb1891e034e70c5545..fd2040034a89d61372c844b2a671f2b89d0d79ae 100644 (file)
@@ -270,8 +270,8 @@ in the following sections.
 -fdelayed-branch  -fdelete-null-pointer-checks @gol
 -fexpensive-optimizations  -ffast-math  -ffloat-store @gol
 -fforce-addr  -fforce-mem  -ffunction-sections @gol
--fgcse  -fgcse-lm  -fgcse-sm  -floop-optimize  -fcrossjumping @gol
--fif-conversion  -fif-conversion2 @gol
+-fgcse  -fgcse-lm  -fgcse-sm  -fgcse-las  -floop-optimize @gol
+-fcrossjumping  -fif-conversion  -fif-conversion2 @gol
 -finline-functions  -finline-limit=@var{n}  -fkeep-inline-functions @gol
 -fkeep-static-consts  -fmerge-constants  -fmerge-all-constants @gol
 -fmove-all-movables  -fnew-ra  -fno-branch-count-reg @gol
@@ -3677,10 +3677,10 @@ also turns on the following optimization flags:
 -fstrength-reduce @gol
 -fcse-follow-jumps  -fcse-skip-blocks @gol
 -frerun-cse-after-loop  -frerun-loop-opt @gol
--fgcse   -fgcse-lm   -fgcse-sm @gol
+-fgcse  -fgcse-lm  -fgcse-sm  -fgcse-las @gol
 -fdelete-null-pointer-checks @gol
 -fexpensive-optimizations @gol
--fregmove -@gol
+-fregmove @gol
 -fschedule-insns  -fschedule-insns2 @gol
 -fsched-interblock  -fsched-spec @gol
 -fcaller-saves @gol
@@ -3996,10 +3996,19 @@ Enabled by default when gcse is enabled.
 
 @item -fgcse-sm
 @opindex fgcse-sm
-When @option{-fgcse-sm} is enabled, A store motion pass is run after global common
-subexpression elimination.  This pass will attempt to move stores out of loops.
-When used in conjunction with @option{-fgcse-lm}, loops containing a load/store sequence
-can be changed to a load before the loop and a store after the loop.
+When @option{-fgcse-sm} is enabled, a store motion pass is run after
+global common subexpression elimination.  This pass will attempt to move
+stores out of loops.  When used in conjunction with @option{-fgcse-lm},
+loops containing a load/store sequence can be changed to a load before
+the loop and a store after the loop.
+
+Enabled by default when gcse is enabled.
+
+@item -fgcse-las
+@opindex fgcse-las
+When @option{-fgcse-las} is enabled, the global common subexpression
+elimination pass eliminates redundant loads that come after stores to the
+same memory location (both partial and full redundacies).
 
 Enabled by default when gcse is enabled.
 
index 93600fbd15fdb875cb01728c5863958575cb9904..2a1a10ff679df803232f9b2e336d7c649e8fa9ff 100644 (file)
@@ -675,6 +675,11 @@ extern int flag_gcse_lm;
 
 extern int flag_gcse_sm;
 
+/* Nonzero if we want to perform redundant load-after-store elimination
+   in gcse.  */
+
+extern int flag_gcse_las;
+
 /* Perform branch target register optimization before prologue / epilogue
    threading.  */
 
index 84524b37d198005b46695ac4e7d847b9ec1e9be6..3e09f02252bb9bb7168219f14186fea4f228a5cb 100644 (file)
@@ -2205,6 +2205,49 @@ hash_scan_set (rtx pat, rtx insn, struct hash_table *table)
                       && oprs_available_p (pat, tmp))))
        insert_set_in_table (pat, insn, table);
     }
+  /* In case of store we want to consider the memory value as avaiable in
+     the REG stored in that memory. This makes it possible to remove
+     redundant loads from due to stores to the same location.  */
+  else if (flag_gcse_las && GET_CODE (src) == REG && GET_CODE (dest) == MEM)
+      {
+        unsigned int regno = REGNO (src);
+
+        /* Do not do this for constant/copy propagation.  */
+        if (! table->set_p
+            /* Only record sets of pseudo-regs in the hash table.  */
+           && regno >= FIRST_PSEUDO_REGISTER
+          /* Don't GCSE something if we can't do a reg/reg copy.  */
+          && can_copy_p (GET_MODE (src))
+          /* GCSE commonly inserts instruction after the insn.  We can't
+             do that easily for EH_REGION notes so disable GCSE on these
+             for now.  */
+          && ! find_reg_note (insn, REG_EH_REGION, NULL_RTX)
+          /* Is SET_DEST something we want to gcse?  */
+          && want_to_gcse_p (dest)
+          /* Don't CSE a nop.  */
+          && ! set_noop_p (pat)
+          /* Don't GCSE if it has attached REG_EQUIV note.
+             At this point this only function parameters should have
+             REG_EQUIV notes and if the argument slot is used somewhere
+             explicitly, it means address of parameter has been taken,
+             so we should not extend the lifetime of the pseudo.  */
+          && ((note = find_reg_note (insn, REG_EQUIV, NULL_RTX)) == 0
+              || GET_CODE (XEXP (note, 0)) != MEM))
+             {
+               /* Stores are never anticipatable.  */
+               int antic_p = 0;
+              /* An expression is not available if its operands are
+                 subsequently modified, including this insn.  It's also not
+                 available if this is a branch, because we can't insert
+                 a set after the branch.  */
+               int avail_p = oprs_available_p (dest, insn)
+                            && ! JUMP_P (insn);
+
+              /* Record the memory expression (DEST) in the hash table.  */
+              insert_expr_in_table (dest, GET_MODE (dest), insn,
+                                    antic_p, avail_p, table);
+             }
+      }
 }
 
 static void
@@ -5360,7 +5403,13 @@ pre_edge_insert (struct edge_list *edge_list, struct expr **index_map)
      reaching_reg <- expr
      old_reg      <- reaching_reg
    because this way copy propagation can discover additional PRE
-   opportunities.  But if this fails, we try the old way.  */
+   opportunities.  But if this fails, we try the old way.
+   When "expr" is a store, i.e.
+   given "MEM <- old_reg", instead of adding after it
+     reaching_reg <- old_reg
+   it's better to add it before as follows:
+     reaching_reg <- old_reg
+     MEM          <- reaching_reg.  */
 
 static void
 pre_insert_copy_insn (struct expr *expr, rtx insn)
@@ -5395,22 +5444,38 @@ pre_insert_copy_insn (struct expr *expr, rtx insn)
   else
     abort ();
 
-  old_reg = SET_DEST (set);
-
-  /* Check if we can modify the set destination in the original insn.  */
-  if (validate_change (insn, &SET_DEST (set), reg, 0))
+  if (GET_CODE (SET_DEST (set)) == REG)
     {
-      new_insn = gen_move_insn (old_reg, reg);
-      new_insn = emit_insn_after (new_insn, insn);
+      old_reg = SET_DEST (set);
+      /* Check if we can modify the set destination in the original insn.  */
+      if (validate_change (insn, &SET_DEST (set), reg, 0))
+        {
+          new_insn = gen_move_insn (old_reg, reg);
+          new_insn = emit_insn_after (new_insn, insn);
 
-      /* Keep register set table up to date.  */
-      replace_one_set (REGNO (old_reg), insn, new_insn);
-      record_one_set (regno, insn);
+          /* Keep register set table up to date.  */
+          replace_one_set (REGNO (old_reg), insn, new_insn);
+          record_one_set (regno, insn);
+        }
+      else
+        {
+          new_insn = gen_move_insn (reg, old_reg);
+          new_insn = emit_insn_after (new_insn, insn);
+
+          /* Keep register set table up to date.  */
+          record_one_set (regno, new_insn);
+        }
     }
-  else
+  else /* This is possible only in case of a store to memory.  */
     {
+      old_reg = SET_SRC (set);
       new_insn = gen_move_insn (reg, old_reg);
-      new_insn = emit_insn_after (new_insn, insn);
+
+      /* Check if we can modify the set source in the original insn.  */
+      if (validate_change (insn, &SET_SRC (set), reg, 0))
+        new_insn = emit_insn_before (new_insn, insn);
+      else
+        new_insn = emit_insn_after (new_insn, insn);
 
       /* Keep register set table up to date.  */
       record_one_set (regno, new_insn);
@@ -5423,7 +5488,6 @@ pre_insert_copy_insn (struct expr *expr, rtx insn)
             "PRE: bb %d, insn %d, copy expression %d in insn %d to reg %d\n",
              BLOCK_NUM (insn), INSN_UID (new_insn), indx,
              INSN_UID (insn), regno);
-  update_ld_motion_stores (expr);
 }
 
 /* Copy available expressions that reach the redundant expression
@@ -5432,7 +5496,7 @@ pre_insert_copy_insn (struct expr *expr, rtx insn)
 static void
 pre_insert_copies (void)
 {
-  unsigned int i;
+  unsigned int i, added_copy;
   struct expr *expr;
   struct occr *occr;
   struct occr *avail;
@@ -5453,6 +5517,9 @@ pre_insert_copies (void)
           expression wasn't deleted anywhere.  */
        if (expr->reaching_reg == NULL)
          continue;
+       
+       /* Set when we add a copy for that expression.  */
+       added_copy = 0; 
 
        for (occr = expr->antic_occr; occr != NULL; occr = occr->next)
          {
@@ -5477,11 +5544,16 @@ pre_insert_copies (void)
                                               BLOCK_FOR_INSN (occr->insn)))
                  continue;
 
+                added_copy = 1;
+
                /* Copy the result of avail to reaching_reg.  */
                pre_insert_copy_insn (expr, insn);
                avail->copied_p = 1;
              }
          }
+
+         if (added_copy)
+            update_ld_motion_stores (expr);
       }
 }
 
index 9da64d543bb04ec79cd0dacee416340be572b0a9..8418d1a96c2e3936923537fa5ab5b68d86588696 100644 (file)
@@ -1019,6 +1019,10 @@ common_handle_option (size_t scode, const char *arg,
       flag_gcse_sm = value;
       break;
 
+    case OPT_fgcse_las:
+      flag_gcse_las = value;
+      break;
+
     case OPT_fgnu_linker:
       flag_gnu_linker = value;
       break;
index e711135476ae96a8b185e842916ea2e68a30f2f9..c1a05f6e26ded1862f21e599ed4db3ec525741e7 100644 (file)
@@ -697,6 +697,11 @@ int flag_gcse_lm = 1;
 
 int flag_gcse_sm = 1;
 
+/* Nonzero if we want to perfrom redundant load after store elimination
+   in gcse.  */
+
+int flag_gcse_las = 1;
+
 /* Perform target register optimization before prologue / epilogue
    threading.  */
 
@@ -1075,6 +1080,7 @@ static const lang_independent_options f_options[] =
   {"gcse", &flag_gcse, 1 },
   {"gcse-lm", &flag_gcse_lm, 1 },
   {"gcse-sm", &flag_gcse_sm, 1 },
+  {"gcse-las", &flag_gcse_las, 1 },
   {"branch-target-load-optimize", &flag_branch_target_load_optimize, 1 },
   {"branch-target-load-optimize2", &flag_branch_target_load_optimize2, 1 },
   {"loop-optimize", &flag_loop_optimize, 1 },
This page took 0.094604 seconds and 5 git commands to generate.