diff options
author | Richard Henderson <rth@redhat.com> | 2001-07-28 18:13:53 -0700 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-07-28 18:13:53 -0700 |
commit | 91d84fadf41ff75390c74646305773f09d7ce153 (patch) | |
tree | 93cb29635dac9e135fa5e9d2c1464c0b024938bd /gcc | |
parent | 0a02170ffd8463b17026d8e5e5eb7c3708923d14 (diff) | |
download | gcc-91d84fadf41ff75390c74646305773f09d7ce153.zip gcc-91d84fadf41ff75390c74646305773f09d7ce153.tar.gz gcc-91d84fadf41ff75390c74646305773f09d7ce153.tar.bz2 |
flow.c (add_to_mem_set_list): New function.
* flow.c (add_to_mem_set_list): New function.
(init_propagate_block_info): Use it.
(mark_set_1): Likewise.
(insn_dead_p): Canonicalize memory address for dead store
comparison. Allow wider mode stores to kill narrower mode stores.
(invalidate_mems_from_autoinc): Use invalidate_mems_from_set.
(invalidate_mems_from_set): Don't handle MEMs.
From-SVN: r44441
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 10 | ||||
-rw-r--r-- | gcc/flow.c | 136 |
2 files changed, 76 insertions, 70 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 1cc14be..42d3f44 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2001-07-28 Richard Henderson <rth@redhat.com> + + * flow.c (add_to_mem_set_list): New function. + (init_propagate_block_info): Use it. + (mark_set_1): Likewise. + (insn_dead_p): Canonicalize memory address for dead store + comparison. Allow wider mode stores to kill narrower mode stores. + (invalidate_mems_from_autoinc): Use invalidate_mems_from_set. + (invalidate_mems_from_set): Don't handle MEMs. + 2001-07-28 Kazu Hirata <kazu@hxi.com> * config/h8300/h8300.h: Fix formatting. @@ -449,6 +449,8 @@ static void print_rtl_and_abort_fcn PARAMS ((const char *, int, const char *)) ATTRIBUTE_NORETURN; +static void add_to_mem_set_list PARAMS ((struct propagate_block_info *, + rtx)); static void invalidate_mems_from_autoinc PARAMS ((struct propagate_block_info *, rtx)); static void invalidate_mems_from_set PARAMS ((struct propagate_block_info *, @@ -1797,8 +1799,7 @@ try_redirect_by_replacing_jump (e, target) When emmiting jump to redirect an fallthru edge, it should always appear after the LOOP_BEG notes, as loop optimizer expect loop to eighter start by fallthru edge or jump following the LOOP_BEG note - jumping to the loop exit test. - */ + jumping to the loop exit test. */ rtx last_loop_beg_note (insn) rtx insn; @@ -5441,23 +5442,7 @@ init_propagate_block_info (bb, live, local_set, cond_local_set, flags) || (GET_CODE (XEXP (canon_mem, 0)) == PLUS && XEXP (XEXP (canon_mem, 0), 0) == frame_pointer_rtx && GET_CODE (XEXP (XEXP (canon_mem, 0), 1)) == CONST_INT)) - { -#ifdef AUTO_INC_DEC - /* Store a copy of mem, otherwise the address may be scrogged - by find_auto_inc. This matters because insn_dead_p uses - an rtx_equal_p check to determine if two addresses are - the same. This works before find_auto_inc, but fails - after find_auto_inc, causing discrepencies between the - set of live registers calculated during the - calculate_global_regs_live phase and what actually exists - after flow completes, leading to aborts. */ - if (flags & PROP_AUTOINC) - mem = shallow_copy_rtx (mem); -#endif - pbi->mem_set_list = alloc_EXPR_LIST (0, mem, pbi->mem_set_list); - if (++pbi->mem_set_list_len >= MAX_MEM_SET_LIST_LEN) - break; - } + add_to_mem_set_list (pbi, canon_mem); } } @@ -5614,11 +5599,13 @@ insn_dead_p (pbi, x, call_ok, notes) if (GET_CODE (r) == MEM) { - rtx temp; + rtx temp, canon_r; - if (MEM_VOLATILE_P (r)) + if (MEM_VOLATILE_P (r) || GET_MODE (r) == BLKmode) return 0; + canon_r = canon_rtx (r); + /* Walk the set of memory locations we are currently tracking and see if one is an identical match to this memory location. If so, this memory write is dead (remember, we're walking @@ -5630,8 +5617,11 @@ insn_dead_p (pbi, x, call_ok, notes) { rtx mem = XEXP (temp, 0); - if (rtx_equal_p (mem, r)) + if (rtx_equal_p (XEXP (canon_r, 0), XEXP (mem, 0)) + && (GET_MODE_SIZE (GET_MODE (canon_r)) + <= GET_MODE_SIZE (GET_MODE (mem)))) return 1; + #ifdef AUTO_INC_DEC /* Check if memory reference matches an auto increment. Only post increment/decrement or modify are valid. */ @@ -5837,6 +5827,53 @@ regno_clobbered_at_setjmp (regno) && REGNO_REG_SET_P (regs_live_at_setjmp, regno)); } +/* Add MEM to PBI->MEM_SET_LIST. MEM should be canonical. Respect the + maximal list size; look for overlaps in mode and select the largest. */ +static void +add_to_mem_set_list (pbi, mem) + struct propagate_block_info *pbi; + rtx mem; +{ + rtx i; + + /* We don't know how large a BLKmode store is, so we must not + take them into consideration. */ + if (GET_MODE (mem) == BLKmode) + return; + + for (i = pbi->mem_set_list; i ; i = XEXP (i, 1)) + { + rtx e = XEXP (i, 0); + if (rtx_equal_p (XEXP (mem, 0), XEXP (e, 0))) + { + if (GET_MODE_SIZE (GET_MODE (mem)) > GET_MODE_SIZE (GET_MODE (e))) + { +#ifdef AUTO_INC_DEC + /* If we must store a copy of the mem, we can just modify + the mode of the stored copy. */ + if (pbi->flags & PROP_AUTOINC) + PUT_MODE (e, GET_MODE (mem)); + else +#endif + XEXP (i, 0) = mem; + } + return; + } + } + + if (pbi->mem_set_list_len < MAX_MEM_SET_LIST_LEN) + { +#ifdef AUTO_INC_DEC + /* Store a copy of mem, otherwise the address may be + scrogged by find_auto_inc. */ + if (pbi->flags & PROP_AUTOINC) + mem = shallow_copy_rtx (mem); +#endif + pbi->mem_set_list = alloc_EXPR_LIST (0, mem, pbi->mem_set_list); + pbi->mem_set_list_len++; + } +} + /* INSN references memory, possibly using autoincrement addressing modes. Find any entries on the mem_set_list that need to be invalidated due to an address change. */ @@ -5848,36 +5885,11 @@ invalidate_mems_from_autoinc (pbi, insn) { rtx note = REG_NOTES (insn); for (note = REG_NOTES (insn); note; note = XEXP (note, 1)) - { - if (REG_NOTE_KIND (note) == REG_INC) - { - rtx temp = pbi->mem_set_list; - rtx prev = NULL_RTX; - rtx next; - - while (temp) - { - next = XEXP (temp, 1); - if (reg_overlap_mentioned_p (XEXP (note, 0), XEXP (temp, 0))) - { - /* Splice temp out of list. */ - if (prev) - XEXP (prev, 1) = next; - else - pbi->mem_set_list = next; - free_EXPR_LIST_node (temp); - pbi->mem_set_list_len--; - } - else - prev = temp; - temp = next; - } - } - } + if (REG_NOTE_KIND (note) == REG_INC) + invalidate_mems_from_set (pbi, XEXP (note, 0)); } -/* EXP is either a MEM or a REG. Remove any dependant entries - from pbi->mem_set_list. */ +/* EXP is a REG. Remove any dependant entries from pbi->mem_set_list. */ static void invalidate_mems_from_set (pbi, exp) @@ -5891,10 +5903,7 @@ invalidate_mems_from_set (pbi, exp) while (temp) { next = XEXP (temp, 1); - if ((GET_CODE (exp) == MEM - && output_dependence (XEXP (temp, 0), exp)) - || (GET_CODE (exp) == REG - && reg_overlap_mentioned_p (exp, XEXP (temp, 0)))) + if (reg_overlap_mentioned_p (exp, XEXP (temp, 0))) { /* Splice this entry out of the list. */ if (prev) @@ -6091,7 +6100,7 @@ mark_set_1 (pbi, code, reg, cond, insn, flags) If this set is a REG, then it kills any MEMs which use the reg. */ if (optimize && (flags & PROP_SCAN_DEAD_CODE)) { - if (GET_CODE (reg) == MEM || GET_CODE (reg) == REG) + if (GET_CODE (reg) == REG) invalidate_mems_from_set (pbi, reg); /* If the memory reference had embedded side effects (autoincrement @@ -6100,27 +6109,14 @@ mark_set_1 (pbi, code, reg, cond, insn, flags) if (insn && GET_CODE (reg) == MEM) invalidate_mems_from_autoinc (pbi, insn); - if (pbi->mem_set_list_len < MAX_MEM_SET_LIST_LEN - && GET_CODE (reg) == MEM && ! side_effects_p (reg) + if (GET_CODE (reg) == MEM && ! side_effects_p (reg) /* ??? With more effort we could track conditional memory life. */ && ! cond - /* We do not know the size of a BLKmode store, so we do not track - them for redundant store elimination. */ - && GET_MODE (reg) != BLKmode /* There are no REG_INC notes for SP, so we can't assume we'll see everything that invalidates it. To be safe, don't eliminate any stores though SP; none of them should be redundant anyway. */ && ! reg_mentioned_p (stack_pointer_rtx, reg)) - { -#ifdef AUTO_INC_DEC - /* Store a copy of mem, otherwise the address may be - scrogged by find_auto_inc. */ - if (flags & PROP_AUTOINC) - reg = shallow_copy_rtx (reg); -#endif - pbi->mem_set_list = alloc_EXPR_LIST (0, reg, pbi->mem_set_list); - pbi->mem_set_list_len++; - } + add_to_mem_set_list (pbi, canon_rtx (reg)); } if (GET_CODE (reg) == REG |