diff options
author | Yiran Wang <yiran@google.com> | 2015-07-08 09:44:03 -0700 |
---|---|---|
committer | Yiran Wang <yiran@google.com> | 2015-07-08 09:59:16 -0700 |
commit | 5ae0308a147ec3f6502fd321860524e634a647a6 (patch) | |
tree | 91cf8eebe473431852889fc0ee7fcaa2127e8e80 /gcc-4.9/gcc/config | |
parent | 1d9fec7937f45dde5e04cac966a2d9a12f2fc15a (diff) | |
download | toolchain_gcc-5ae0308a147ec3f6502fd321860524e634a647a6.tar.gz toolchain_gcc-5ae0308a147ec3f6502fd321860524e634a647a6.tar.bz2 toolchain_gcc-5ae0308a147ec3f6502fd321860524e634a647a6.zip |
cherry-pick gcc r217091.
This change is re-based and modified to work with the older context, as the
context code is changed a lot in GCC trunk.
It is about to insert some barriers on stack-pointer register, so that the
adjust-stack-pointer code does not get scheduled before any code in the
fuction epilogue, which may access some stack space without explicit use of
stack pointer.
Examples are a load from an auto array and some access to an area of alloca.
Anyway, the barriers would make all such alias dependences not violated.
For more details, please refer to GCC bug 63293.
(Personally I think there may be a bit too many barriers generated.)
Change-Id: I61ea54e500b6965feab69a62165d10b6c3a21c20
Diffstat (limited to 'gcc-4.9/gcc/config')
-rw-r--r-- | gcc-4.9/gcc/config/aarch64/aarch64.c | 12 |
1 files changed, 12 insertions, 0 deletions
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.c b/gcc-4.9/gcc/config/aarch64/aarch64.c index 029c54ca3..6b2717471 100644 --- a/gcc-4.9/gcc/config/aarch64/aarch64.c +++ b/gcc-4.9/gcc/config/aarch64/aarch64.c @@ -2204,6 +2204,9 @@ aarch64_expand_epilogue (bool for_sibcall) HOST_WIDE_INT fp_offset; rtx insn; rtx cfa_reg; + /* We need to add memory barrier to prevent read from deallocated stack. */ + bool need_barrier_p = (get_frame_size () != 0 + || cfun->machine->saved_varargs_size); aarch64_layout_frame (); original_frame_size = get_frame_size () + cfun->machine->saved_varargs_size; @@ -2245,6 +2248,9 @@ aarch64_expand_epilogue (bool for_sibcall) if (frame_pointer_needed && (crtl->outgoing_args_size || cfun->calls_alloca)) { + if (cfun->calls_alloca) + emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx)); + insn = emit_insn (gen_add3_insn (stack_pointer_rtx, hard_frame_pointer_rtx, GEN_INT (- fp_offset))); @@ -2258,6 +2264,9 @@ aarch64_expand_epilogue (bool for_sibcall) aarch64_save_or_restore_callee_save_registers (fp_offset + cfun->machine->frame.hardfp_offset, 1); + if (need_barrier_p) + emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx)); + /* Restore the frame pointer and lr if the frame pointer is needed. */ if (offset > 0) { @@ -2355,6 +2364,9 @@ aarch64_expand_epilogue (bool for_sibcall) if (frame_size > -1) { + if (need_barrier_p) + emit_insn (gen_stack_tie (stack_pointer_rtx, stack_pointer_rtx)); + if (frame_size >= 0x1000000) { rtx op0 = gen_rtx_REG (Pmode, IP0_REGNUM); |