diff options
author | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-12-03 10:02:28 +0000 |
---|---|---|
committer | rearnsha <rearnsha@138bc75d-0d04-0410-961f-82ee72b054a4> | 2003-12-03 10:02:28 +0000 |
commit | 9e4a9ceb1f5906291c90701c1d203dbfd13ad8a1 (patch) | |
tree | 78a32ee85afcae7c521c74c580db1d4c919b5e2c /gcc/gcse.c | |
parent | ebbbf5070b34eae11488a6adbb0ce25bd75e7af2 (diff) | |
download | gcc-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/gcse.c')
-rw-r--r-- | gcc/gcse.c | 73 |
1 files changed, 58 insertions, 15 deletions
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)) { |