aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMostafa Hagog <mustafa@il.ibm.com>2003-09-04 02:10:32 +0000
committerRichard Henderson <rth@gcc.gnu.org>2003-09-03 19:10:32 -0700
commitb885908b11b9952ec25251e56ab7000d9349c163 (patch)
tree707ffa5fd1ad06d1035bb2d6960ade72bcd2659e /gcc
parentbcfb807527a1ae01d056ce4a7e70ca0b4b86b35e (diff)
downloadgcc-b885908b11b9952ec25251e56ab7000d9349c163.zip
gcc-b885908b11b9952ec25251e56ab7000d9349c163.tar.gz
gcc-b885908b11b9952ec25251e56ab7000d9349c163.tar.bz2
gcse.c (replace_one_set): New function.
* gcse.c (replace_one_set): New function. (pre_insert_copy_insn): Change the order of copying to make copy propagation discover additional PRE opportunities. From-SVN: r71047
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/gcse.c43
2 files changed, 46 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index d432719..bd78801 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2003-09-03 Mostafa Hagog <mustafa@il.ibm.com>
+
+ * gcse.c (replace_one_set): New function.
+ (pre_insert_copy_insn): Change the order of copying
+ to make copy propagation discover additional PRE opportunities.
+
2003-09-03 Roger Sayle <roger@eyesopen.com>
PR optimization/11700.
diff --git a/gcc/gcse.c b/gcc/gcse.c
index c7cd485..9779663 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -559,6 +559,7 @@ static void alloc_reg_set_mem (int);
static void free_reg_set_mem (void);
static int get_bitmap_width (int, int, int);
static void record_one_set (int, rtx);
+static void replace_one_set (int, rtx, rtx);
static void record_set_info (rtx, rtx, void *);
static void compute_sets (rtx);
static void hash_scan_insn (rtx, struct hash_table *, int);
@@ -1176,6 +1177,24 @@ free_reg_set_mem (void)
obstack_free (&reg_set_obstack, NULL);
}
+/* An OLD_INSN that used to set REGNO was replaced by NEW_INSN.
+ Update the corresponding `reg_set_table' entry accordingly.
+ We assume that NEW_INSN is not already recorded in reg_set_table[regno]. */
+
+static void
+replace_one_set (int regno, rtx old_insn, rtx new_insn)
+{
+ struct reg_set *reg_info;
+ if (regno >= reg_set_table_size)
+ return;
+ for (reg_info = reg_set_table[regno]; reg_info; reg_info = reg_info->next)
+ if (reg_info->insn == old_insn)
+ {
+ reg_info->insn = new_insn;
+ break;
+ }
+}
+
/* Record REGNO in the reg_set table. */
static void
@@ -5327,7 +5346,14 @@ pre_edge_insert (struct edge_list *edge_list, struct expr **index_map)
return did_insert;
}
-/* Copy the result of INSN to REG. INDX is the expression number. */
+/* Copy the result of INSN to REG. INDX is the expression number.
+ Given "old_reg <- expr" (INSN), instead of adding after it
+ reaching_reg <- old_reg
+ it's better to do the following:
+ reaching_reg <- expr
+ old_reg <- reaching_reg
+ because this way copy propagation can discover additional PRE
+ opportunuties. */
static void
pre_insert_copy_insn (struct expr *expr, rtx insn)
@@ -5337,14 +5363,25 @@ pre_insert_copy_insn (struct expr *expr, rtx insn)
int indx = expr->bitmap_index;
rtx set = single_set (insn);
rtx new_insn;
+ rtx new_set;
+ rtx old_reg;
if (!set)
abort ();
- new_insn = emit_insn_after (gen_move_insn (reg, copy_rtx (SET_DEST (set))), insn);
+ old_reg = SET_DEST (set);
+ new_insn = emit_insn_after (gen_move_insn (old_reg,
+ reg),
+ insn);
+ new_set = single_set (new_insn);
+
+ if (!new_set)
+ abort();
+ SET_DEST (set) = reg;
/* Keep register set table up to date. */
- record_one_set (regno, new_insn);
+ replace_one_set (REGNO (old_reg), insn, new_insn);
+ record_one_set (regno, insn);
gcse_create_count++;