diff options
author | Alan Modra <amodra@gmail.com> | 2012-04-13 07:56:24 +0930 |
---|---|---|
committer | Alan Modra <amodra@gcc.gnu.org> | 2012-04-13 07:56:24 +0930 |
commit | e8e029df92f4c7e313dfff56efb71614f99ba10e (patch) | |
tree | 6640c5144f749e378fc48a81bdb1a2b777ec9629 | |
parent | 1ede5f2c24b169223b884bfbbd198edc61d057ce (diff) | |
download | gcc-e8e029df92f4c7e313dfff56efb71614f99ba10e.zip gcc-e8e029df92f4c7e313dfff56efb71614f99ba10e.tar.gz gcc-e8e029df92f4c7e313dfff56efb71614f99ba10e.tar.bz2 |
re PR target/52828 (powerpc -m32 -Os writes register saves below stack)
PR target/52828
* config/rs6000/rs6000.c (rs6000_emit_stack_tie): Rewrite with
tie regs on destination of sets. Delete forward declaration.
(rs6000_emit_stack_reset): Update rs6000_emit_stack_tie calls.
(rs6000_emit_prologue): Likewise.
(rs6000_emit_epilogue): Likewise. Use in place of gen_frame_tie
and gen_stack_tie.
(is_mem_ref): Use tie_operand to recognise stack ties.
* config/rs6000/predicates.md (tie_operand): New.
* config/rs6000/rs6000.md (restore_stack_block): Generate new
stack tie rtl.
(restore_stack_nonlocal): Likewise.
(stack_tie): Update.
(frame_tie): Delete.
From-SVN: r186397
-rw-r--r-- | gcc/ChangeLog | 17 | ||||
-rw-r--r-- | gcc/config/rs6000/predicates.md | 10 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 49 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.md | 38 |
4 files changed, 73 insertions, 41 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a0b7aa7..3c0bb61 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,20 @@ +2012-04-13 Alan Modra <amodra@gmail.com> + + PR target/52828 + * config/rs6000/rs6000.c (rs6000_emit_stack_tie): Rewrite with + tie regs on destination of sets. Delete forward declaration. + (rs6000_emit_stack_reset): Update rs6000_emit_stack_tie calls. + (rs6000_emit_prologue): Likewise. + (rs6000_emit_epilogue): Likewise. Use in place of gen_frame_tie + and gen_stack_tie. + (is_mem_ref): Use tie_operand to recognise stack ties. + * config/rs6000/predicates.md (tie_operand): New. + * config/rs6000/rs6000.md (restore_stack_block): Generate new + stack tie rtl. + (restore_stack_nonlocal): Likewise. + (stack_tie): Update. + (frame_tie): Delete. + 2012-04-12 Bill Schmidt <wschmidt@linux.vnet.ibm.com> * tree-ssa-reassoc.c (attempt_builtin_powi_stats): Change %ld to diff --git a/gcc/config/rs6000/predicates.md b/gcc/config/rs6000/predicates.md index 29dd18d..232773d 100644 --- a/gcc/config/rs6000/predicates.md +++ b/gcc/config/rs6000/predicates.md @@ -1451,3 +1451,13 @@ return 1; }) + +;; Return 1 if OP is a stack tie operand. +(define_predicate "tie_operand" + (match_code "parallel") +{ + return (GET_CODE (XVECEXP (op, 0, 0)) == SET + && GET_CODE (XEXP (XVECEXP (op, 0, 0), 0)) == MEM + && GET_MODE (XEXP (XVECEXP (op, 0, 0), 0)) == BLKmode + && XEXP (XVECEXP (op, 0, 0), 1) == const0_rtx); +}) diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index d053931..ceb6448 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -925,7 +925,6 @@ static const char *rs6000_invalid_within_doloop (const_rtx); static bool rs6000_legitimate_address_p (enum machine_mode, rtx, bool); static bool rs6000_debug_legitimate_address_p (enum machine_mode, rtx, bool); static rtx rs6000_generate_compare (rtx, enum machine_mode); -static void rs6000_emit_stack_tie (void); static bool spe_func_has_64bit_regs_p (void); static rtx gen_frame_mem_offset (enum machine_mode, rtx, int); static unsigned rs6000_hash_constant (rtx); @@ -18505,12 +18504,29 @@ rs6000_aix_asm_output_dwarf_table_ref (char * frame_table_label) and the change to the stack pointer. */ static void -rs6000_emit_stack_tie (void) +rs6000_emit_stack_tie (rtx fp, bool hard_frame_needed) { - rtx mem = gen_frame_mem (BLKmode, - gen_rtx_REG (Pmode, STACK_POINTER_REGNUM)); + rtvec p; + int i; + rtx regs[3]; + + i = 0; + regs[i++] = gen_rtx_REG (Pmode, STACK_POINTER_REGNUM); + if (hard_frame_needed) + regs[i++] = gen_rtx_REG (Pmode, HARD_FRAME_POINTER_REGNUM); + if (!(REGNO (fp) == STACK_POINTER_REGNUM + || (hard_frame_needed + && REGNO (fp) == HARD_FRAME_POINTER_REGNUM))) + regs[i++] = fp; - emit_insn (gen_stack_tie (mem)); + p = rtvec_alloc (i); + while (--i >= 0) + { + rtx mem = gen_frame_mem (BLKmode, regs[i]); + RTVEC_ELT (p, i) = gen_rtx_SET (VOIDmode, mem, const0_rtx); + } + + emit_insn (gen_stack_tie (gen_rtx_PARALLEL (VOIDmode, p))); } /* Emit the correct code for allocating stack space, as insns. @@ -19130,7 +19146,7 @@ rs6000_emit_stack_reset (rs6000_stack_t *info, || (TARGET_SPE_ABI && info->spe_64bit_regs_used != 0 && info->first_gp_reg_save != 32)) - rs6000_emit_stack_tie (); + rs6000_emit_stack_tie (frame_reg_rtx, frame_pointer_needed); if (frame_reg_rtx != sp_reg_rtx) { @@ -19350,7 +19366,7 @@ rs6000_emit_prologue (void) } rs6000_emit_allocate_stack (info->total_size, copy_reg); if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (); + rs6000_emit_stack_tie (frame_reg_rtx, false); } /* Handle world saves specially here. */ @@ -19854,7 +19870,7 @@ rs6000_emit_prologue (void) sp_offset = info->total_size; rs6000_emit_allocate_stack (info->total_size, copy_reg); if (frame_reg_rtx != sp_reg_rtx) - rs6000_emit_stack_tie (); + rs6000_emit_stack_tie (frame_reg_rtx, false); } /* Set frame pointer, if needed. */ @@ -20425,13 +20441,7 @@ rs6000_emit_epilogue (int sibcall) /* Prevent reordering memory accesses against stack pointer restore. */ else if (cfun->calls_alloca || offset_below_red_zone_p (-info->total_size)) - { - rtx mem1 = gen_rtx_MEM (BLKmode, hard_frame_pointer_rtx); - rtx mem2 = gen_rtx_MEM (BLKmode, sp_reg_rtx); - MEM_NOTRAP_P (mem1) = 1; - MEM_NOTRAP_P (mem2) = 1; - emit_insn (gen_frame_tie (mem1, mem2)); - } + rs6000_emit_stack_tie (frame_reg_rtx, true); insn = emit_insn (gen_add3_insn (frame_reg_rtx, hard_frame_pointer_rtx, GEN_INT (info->total_size))); @@ -20444,11 +20454,7 @@ rs6000_emit_epilogue (int sibcall) /* Prevent reordering memory accesses against stack pointer restore. */ if (cfun->calls_alloca || offset_below_red_zone_p (-info->total_size)) - { - rtx mem = gen_rtx_MEM (BLKmode, sp_reg_rtx); - MEM_NOTRAP_P (mem) = 1; - emit_insn (gen_stack_tie (mem)); - } + rs6000_emit_stack_tie (frame_reg_rtx, false); insn = emit_insn (gen_add3_insn (sp_reg_rtx, sp_reg_rtx, GEN_INT (info->total_size))); sp_offset = 0; @@ -22835,8 +22841,7 @@ is_mem_ref (rtx pat) bool ret = false; /* stack_tie does not produce any real memory traffic. */ - if (GET_CODE (pat) == UNSPEC - && XINT (pat, 1) == UNSPEC_TIE) + if (tie_operand (pat, VOIDmode)) return false; if (GET_CODE (pat) == MEM) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index 1f5085d..3d27169 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -73,7 +73,6 @@ (define_c_enum "unspec" [UNSPEC_FRSP ; frsp for POWER machines UNSPEC_PROBE_STACK ; probe stack memory reference - UNSPEC_TIE ; tie stack contents and stack pointer UNSPEC_TOCPTR ; address of a word pointing to the TOC UNSPEC_TOC ; address of the TOC (more-or-less) UNSPEC_MOVSI_GOT @@ -11989,17 +11988,23 @@ (define_expand "restore_stack_block" [(set (match_dup 2) (match_dup 3)) (set (match_dup 4) (match_dup 2)) - (set (match_dup 5) (unspec:BLK [(match_dup 5)] UNSPEC_TIE)) + (match_dup 5) (set (match_operand 0 "register_operand" "") (match_operand 1 "register_operand" ""))] "" " { + rtvec p; + operands[1] = force_reg (Pmode, operands[1]); operands[2] = gen_reg_rtx (Pmode); operands[3] = gen_frame_mem (Pmode, operands[0]); operands[4] = gen_frame_mem (Pmode, operands[1]); - operands[5] = gen_frame_mem (BLKmode, operands[0]); + p = rtvec_alloc (1); + RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode, + gen_frame_mem (BLKmode, operands[0]), + const0_rtx); + operands[5] = gen_rtx_PARALLEL (VOIDmode, p); }") (define_expand "save_stack_nonlocal" @@ -12022,12 +12027,13 @@ [(set (match_dup 2) (match_operand 1 "memory_operand" "")) (set (match_dup 3) (match_dup 4)) (set (match_dup 5) (match_dup 2)) - (set (match_dup 6) (unspec:BLK [(match_dup 6)] UNSPEC_TIE)) + (match_dup 6) (set (match_operand 0 "register_operand" "") (match_dup 3))] "" " { int units_per_word = (TARGET_32BIT) ? 4 : 8; + rtvec p; /* Restore the backchain from the first word, sp from the second. */ operands[2] = gen_reg_rtx (Pmode); @@ -12035,7 +12041,11 @@ operands[1] = adjust_address_nv (operands[1], Pmode, 0); operands[4] = adjust_address_nv (operands[1], Pmode, units_per_word); operands[5] = gen_frame_mem (Pmode, operands[3]); - operands[6] = gen_frame_mem (BLKmode, operands[0]); + p = rtvec_alloc (1); + RTVEC_ELT (p, 0) = gen_rtx_SET (VOIDmode, + gen_frame_mem (BLKmode, operands[0]), + const0_rtx); + operands[6] = gen_rtx_PARALLEL (VOIDmode, p); }") ;; TOC register handling. @@ -15899,25 +15909,15 @@ [(set_attr "type" "branch") (set_attr "length" "4")]) -; These are to explain that changes to the stack pointer should -; not be moved over stores to stack memory. +; This is to explain that changes to the stack pointer should +; not be moved over loads from or stores to stack memory. (define_insn "stack_tie" - [(set (match_operand:BLK 0 "memory_operand" "+m") - (unspec:BLK [(match_dup 0)] UNSPEC_TIE))] - "" - "" - [(set_attr "length" "0")]) - -; Like stack_tie, but depend on both fp and sp based memory. -(define_insn "frame_tie" - [(set (match_operand:BLK 0 "memory_operand" "+m") - (unspec:BLK [(match_dup 0) - (match_operand:BLK 1 "memory_operand" "m")] UNSPEC_TIE))] + [(match_parallel 0 "tie_operand" + [(set (mem:BLK (reg 1)) (const_int 0))])] "" "" [(set_attr "length" "0")]) - (define_expand "epilogue" [(use (const_int 0))] "" |