diff options
author | Jan Hubicka <jh@suse.cz> | 2001-05-01 01:27:22 +0200 |
---|---|---|
committer | Richard Henderson <rth@gcc.gnu.org> | 2001-04-30 16:27:22 -0700 |
commit | 595c2290274554b0164229642206fc5e8a7bfb2f (patch) | |
tree | b5e2deb5406973fb7e6c37c3bdf2a9c4ef77598b | |
parent | dad362764fe456881661e192c595a6774794eb82 (diff) | |
download | gcc-595c2290274554b0164229642206fc5e8a7bfb2f.zip gcc-595c2290274554b0164229642206fc5e8a7bfb2f.tar.gz gcc-595c2290274554b0164229642206fc5e8a7bfb2f.tar.bz2 |
regmove.c (try_apply_stack_adjustment): Remove now redundant sanity checks.
* regmove.c (try_apply_stack_adjustment): Remove now redundant
sanity checks.
(combine_stack_adjustments_for_block): Don't combine stack
allocation followed by deallocations. Handle grow-up stacks.
Co-Authored-By: Richard Henderson <rth@redhat.com>
From-SVN: r41707
-rw-r--r-- | gcc/ChangeLog | 8 | ||||
-rw-r--r-- | gcc/regmove.c | 98 |
2 files changed, 68 insertions, 38 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index b50c9c9..ba3fc47 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,11 @@ +2001-04-30 Jan Hubicka <jh@suse.cz> + Richard Henderson <rth@redhat.com> + + * regmove.c (try_apply_stack_adjustment): Remove now redundant + sanity checks. + (combine_stack_adjustments_for_block): Don't combine stack + allocation followed by deallocations. Handle grow-up stacks. + 2001-04-30 Mark Mitchell <mark@codesourcery.com> * fdl.texi: New file. diff --git a/gcc/regmove.c b/gcc/regmove.c index bb22700..a151d6f 100644 --- a/gcc/regmove.c +++ b/gcc/regmove.c @@ -42,6 +42,15 @@ Boston, MA 02111-1307, USA. */ #include "toplev.h" #include "reload.h" + +/* Turn STACK_GROWS_DOWNWARD into a boolean. */ +#ifdef STACK_GROWS_DOWNWARD +#undef STACK_GROWS_DOWNWARD +#define STACK_GROWS_DOWNWARD 1 +#else +#define STACK_GROWS_DOWNWARD 0 +#endif + static int perhaps_ends_bb_p PARAMS ((rtx)); static int optimize_reg_copy_1 PARAMS ((rtx, rtx, rtx)); static void optimize_reg_copy_2 PARAMS ((rtx, rtx, rtx)); @@ -2231,14 +2240,6 @@ try_apply_stack_adjustment (insn, memlist, new_adjust, delta) struct csa_memlist *ml; rtx set; - /* We know INSN matches single_set_for_csa, because that's what we - recognized earlier. However, if INSN is not single_set, it is - doing double duty as a barrier for frame pointer memory accesses, - which we are not recording. Therefore, an adjust insn that is not - single_set may not have a positive delta applied. */ - - if (delta > 0 && ! single_set (insn)) - return 0; set = single_set_for_csa (insn); validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1); @@ -2248,13 +2249,6 @@ try_apply_stack_adjustment (insn, memlist, new_adjust, delta) rtx new = gen_rtx_MEM (GET_MODE (*ml->mem), plus_constant (stack_pointer_rtx, c)); - /* Don't reference memory below the stack pointer. */ - if (c < 0) - { - cancel_changes (0); - return 0; - } - MEM_COPY_ATTRIBUTES (new, *ml->mem); validate_change (ml->insn, ml->mem, new, 1); } @@ -2369,35 +2363,63 @@ combine_stack_adjustments_for_block (bb) /* If not all recorded memrefs can be adjusted, or the adjustment is now too large for a constant addition, - we cannot merge the two stack adjustments. */ - if (! try_apply_stack_adjustment (last_sp_set, memlist, - last_sp_adjust + this_adjust, - this_adjust)) + we cannot merge the two stack adjustments. + + Also we need to be carefull to not move stack pointer + such that we create stack accesses outside the allocated + area. We can combine an allocation into the first insn, + or a deallocation into the second insn. We can not + combine an allocation followed by a deallocation. + + The only somewhat frequent ocurrence of the later is when + a function allocates a stack frame but does not use it. + For this case, we would need to analyze rtl stream to be + sure that allocated area is really unused. This means not + only checking the memory references, but also all registers + or global memory references possibly containing a stack + frame address. + + Perhaps the best way to address this problem is to teach + gcc not to allocate stack for objects never used. */ + + /* Combine an allocation into the first instruction. */ + if (STACK_GROWS_DOWNWARD ? this_adjust <= 0 : this_adjust >= 0) { - free_csa_memlist (memlist); - memlist = NULL; - last_sp_set = insn; - last_sp_adjust = this_adjust; - goto processed; + if (try_apply_stack_adjustment (last_sp_set, memlist, + last_sp_adjust + this_adjust, + this_adjust)) + { + /* It worked! */ + pending_delete = insn; + last_sp_adjust += this_adjust; + goto processed; + } } - /* It worked! */ - pending_delete = insn; - last_sp_adjust += this_adjust; - - /* If, by some accident, the adjustments cancel out, - delete both insns and start from scratch. */ - if (last_sp_adjust == 0) + /* Otherwise we have a deallocation. Do not combine with + a previous allocation. Combine into the second insn. */ + else if (STACK_GROWS_DOWNWARD + ? last_sp_adjust >= 0 : last_sp_adjust <= 0) { - if (last_sp_set == bb->head) - bb->head = NEXT_INSN (last_sp_set); - flow_delete_insn (last_sp_set); - - free_csa_memlist (memlist); - memlist = NULL; - last_sp_set = NULL_RTX; + if (try_apply_stack_adjustment (insn, memlist, + last_sp_adjust + this_adjust, + -last_sp_adjust)) + { + /* It worked! */ + flow_delete_insn (last_sp_set); + last_sp_set = insn; + last_sp_adjust += this_adjust; + free_csa_memlist (memlist); + memlist = NULL; + goto processed; + } } + /* Combination failed. Restart processing from here. */ + free_csa_memlist (memlist); + memlist = NULL; + last_sp_set = insn; + last_sp_adjust = this_adjust; goto processed; } |