summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-03 10:02:28 +0000
committerrearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4>2003-12-03 10:02:28 +0000
commit9e4a9ceb1f5906291c90701c1d203dbfd13ad8a1 (patch)
tree78a32ee85afcae7c521c74c580db1d4c919b5e2c /gcc
parentebbbf5070b34eae11488a6adbb0ce25bd75e7af2 (diff)
downloadgcc-9e4a9ceb1f5906291c90701c1d203dbfd13ad8a1.tar.gz
* gcse.c (reg_clear_last_set): New function.
(reg_set_info): If data is non-null, treat it as an sbitmap of registers, set the bit for the register being set. (compute_store_table): Allocate last_set_in with xcalloc. Do not memset this array on each iteration. Pass reg_set_in_block[bb->index] to note_stores while computing last_set_in instead of scanning last_set_in after the first pass through the insns. Clear last_set_in using reg_clear_last_set instead of explicitly rescanning after each insn. If checking is enabled, assert that last_set_in is completely zeroed after each bb has been processed. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@74224 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog13
-rw-r--r--gcc/gcse.c73
2 files changed, 71 insertions, 15 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 1ea9b2c6da8..1a51101435b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,16 @@
+2003-12-03 Richard Earnshaw <rearnsha@arm.com>
+
+ * gcse.c (reg_clear_last_set): New function.
+ (reg_set_info): If data is non-null, treat it as an sbitmap of
+ registers, set the bit for the register being set.
+ (compute_store_table): Allocate last_set_in with xcalloc. Do not
+ memset this array on each iteration. Pass reg_set_in_block[bb->index]
+ to note_stores while computing last_set_in instead of scanning
+ last_set_in after the first pass through the insns.
+ Clear last_set_in using reg_clear_last_set instead of explicitly
+ rescanning after each insn. If checking is enabled, assert that
+ last_set_in is completely zeroed after each bb has been processed.
+
2003-12-02 Geoffrey Keating <geoffk@geoffk.org>
* df.c (df_uses_record) <MEM>: The argument of a MEM is read-only,
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 73f293bf24e..4481dc76214 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -679,6 +679,7 @@ static void compute_ld_motion_mems (void);
static void trim_ld_motion_mems (void);
static void update_ld_motion_stores (struct expr *);
static void reg_set_info (rtx, rtx, void *);
+static void reg_clear_last_set (rtx, rtx, void *);
static bool store_ops_ok (rtx, int *);
static rtx extract_mentioned_regs (rtx);
static rtx extract_mentioned_regs_helper (rtx, rtx);
@@ -6921,17 +6922,41 @@ static sbitmap * st_antloc;
/* Global holding the number of store expressions we are dealing with. */
static int num_stores;
-/* Checks to set if we need to mark a register set. Called from note_stores. */
+/* Checks to set if we need to mark a register set. Called from
+ note_stores. */
static void
reg_set_info (rtx dest, rtx setter ATTRIBUTE_UNUSED,
- void *data ATTRIBUTE_UNUSED)
+ void *data)
{
+ sbitmap bb_reg = data;
+
if (GET_CODE (dest) == SUBREG)
dest = SUBREG_REG (dest);
if (GET_CODE (dest) == REG)
- regvec[REGNO (dest)] = INSN_UID (compute_store_table_current_insn);
+ {
+ regvec[REGNO (dest)] = INSN_UID (compute_store_table_current_insn);
+ if (bb_reg)
+ SET_BIT (bb_reg, REGNO (dest));
+ }
+}
+
+/* Clear any mark that says that this insn sets dest. Called from
+ note_stores. */
+
+static void
+reg_clear_last_set (rtx dest, rtx setter ATTRIBUTE_UNUSED,
+ void *data)
+{
+ int *dead_vec = data;
+
+ if (GET_CODE (dest) == SUBREG)
+ dest = SUBREG_REG (dest);
+
+ if (GET_CODE (dest) == REG &&
+ dead_vec[REGNO (dest)] == INSN_UID (compute_store_table_current_insn))
+ dead_vec[REGNO (dest)] = 0;
}
/* Return zero if some of the registers in list X are killed
@@ -7165,14 +7190,13 @@ compute_store_table (void)
max_gcse_regno);
sbitmap_vector_zero (reg_set_in_block, last_basic_block);
pre_ldst_mems = 0;
- last_set_in = xmalloc (sizeof (int) * max_gcse_regno);
+ last_set_in = xcalloc (max_gcse_regno, sizeof (int));
already_set = xmalloc (sizeof (int) * max_gcse_regno);
/* Find all the stores we care about. */
FOR_EACH_BB (bb)
{
/* First compute the registers set in this block. */
- memset (last_set_in, 0, sizeof (int) * max_gcse_regno);
regvec = last_set_in;
for (insn = bb->head;
@@ -7194,19 +7218,17 @@ compute_store_table (void)
for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
if (clobbers_all
|| TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
- last_set_in[regno] = INSN_UID (insn);
+ {
+ last_set_in[regno] = INSN_UID (insn);
+ SET_BIT (reg_set_in_block[bb->index], regno);
+ }
}
pat = PATTERN (insn);
compute_store_table_current_insn = insn;
- note_stores (pat, reg_set_info, NULL);
+ note_stores (pat, reg_set_info, reg_set_in_block[bb->index]);
}
- /* Record the set registers. */
- for (regno = 0; regno < max_gcse_regno; regno++)
- if (last_set_in[regno])
- SET_BIT (reg_set_in_block[bb->index], regno);
-
/* Now find the stores. */
memset (already_set, 0, sizeof (int) * max_gcse_regno);
regvec = already_set;
@@ -7239,11 +7261,32 @@ compute_store_table (void)
find_moveable_store (insn, already_set, last_set_in);
/* Unmark regs that are no longer set. */
- for (regno = 0; regno < max_gcse_regno; regno++)
- if (last_set_in[regno] == INSN_UID (insn))
- last_set_in[regno] = 0;
+ compute_store_table_current_insn = insn;
+ note_stores (pat, reg_clear_last_set, last_set_in);
+ if (GET_CODE (insn) == CALL_INSN)
+ {
+ bool clobbers_all = false;
+#ifdef NON_SAVING_SETJMP
+ if (NON_SAVING_SETJMP
+ && find_reg_note (insn, REG_SETJMP, NULL_RTX))
+ clobbers_all = true;
+#endif
+
+ for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
+ if ((clobbers_all
+ || TEST_HARD_REG_BIT (regs_invalidated_by_call, regno))
+ && last_set_in[regno] == INSN_UID (insn))
+ last_set_in[regno] = 0;
+ }
}
+#ifdef ENABLE_CHECKING
+ /* last_set_in should now be all-zero. */
+ for (regno = 0; regno < max_gcse_regno; regno++)
+ if (last_set_in[regno] != 0)
+ abort ();
+#endif
+
/* Clear temporary marks. */
for (ptr = first_ls_expr (); ptr != NULL; ptr = next_ls_expr (ptr))
{