diff options
author | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-20 08:34:43 +0000 |
---|---|---|
committer | jakub <jakub@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-11-20 08:34:43 +0000 |
commit | b4da3347c2a32b39768223194848c0f1c67261fb (patch) | |
tree | b8e399f48378d1d27ec4ce799592476990e6187c /gcc/cselib.c | |
parent | a2555a7f1d85dcbc1fd9a8f538e7baa4814e8902 (diff) | |
download | gcc-b4da3347c2a32b39768223194848c0f1c67261fb.tar.gz |
PR rtl-optimization/54921
* cselib.h (fp_setter_insn): New prototype.
* cselib.c (fp_setter_insn): New function.
(cselib_process_insn): If frame_pointer_needed,
call cselib_invalidate_rtx (stack_pointer_rtx) after
processing a frame pointer setter.
* var-tracking.c (fp_setter): Removed.
(vt_initialize): Use fp_setter_insn instead of fp_setter.
* gcc.dg/pr54921.c: New test.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@193647 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cselib.c')
-rw-r--r-- | gcc/cselib.c | 30 |
1 files changed, 30 insertions, 0 deletions
diff --git a/gcc/cselib.c b/gcc/cselib.c index 92193ba9bcb..28f8d072438 100644 --- a/gcc/cselib.c +++ b/gcc/cselib.c @@ -2593,6 +2593,28 @@ cselib_record_sets (rtx insn) } } +/* Return true if INSN in the prologue initializes hard_frame_pointer_rtx. */ + +bool +fp_setter_insn (rtx insn) +{ + rtx expr, pat = NULL_RTX; + + if (!RTX_FRAME_RELATED_P (insn)) + return false; + + expr = find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX); + if (expr) + pat = XEXP (expr, 0); + if (!modified_in_p (hard_frame_pointer_rtx, pat ? pat : insn)) + return false; + + /* Don't return true for frame pointer restores in the epilogue. */ + if (find_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx)) + return false; + return true; +} + /* Record the effects of INSN. */ void @@ -2651,6 +2673,14 @@ cselib_process_insn (rtx insn) if (GET_CODE (XEXP (x, 0)) == CLOBBER) cselib_invalidate_rtx (XEXP (XEXP (x, 0), 0)); + /* On setter of the hard frame pointer if frame_pointer_needed, + invalidate stack_pointer_rtx, so that sp and {,h}fp based + VALUEs are distinct. */ + if (reload_completed + && frame_pointer_needed + && fp_setter_insn (insn)) + cselib_invalidate_rtx (stack_pointer_rtx); + cselib_current_insn = NULL_RTX; if (n_useless_values > MAX_USELESS_VALUES |