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
diff --git a/gcc-4.9/gcc/ChangeLog b/gcc-4.9/gcc/ChangeLog
index a6c51d3..c8a6ad1 100644
--- a/gcc-4.9/gcc/ChangeLog
+++ b/gcc-4.9/gcc/ChangeLog
@@ -836,6 +836,13 @@
 	(write_dependence_p): Ditto.
 	(may_alias_p): Ditto.
 
+2014-11-04  Jiong Wang  <jiong.wang@arm.com>
+2014-11-04  Wilco Dijkstra  <wilco.dijkstra@arm.com>
+
+	PR target/63293
+	* config/aarch64/aarch64.c (aarch64_expand_epiloue): Add barriers before
+	stack adjustment.
+
 2014-10-31  DJ Delorie  <dj@redhat.com>
 
 	* expmed.c (strict_volatile_bitfield_p): Fix off-by-one error.
diff --git a/gcc-4.9/gcc/config/aarch64/aarch64.c b/gcc-4.9/gcc/config/aarch64/aarch64.c
index 029c54c..6b27174 100644
--- a/gcc-4.9/gcc/config/aarch64/aarch64.c
+++ b/gcc-4.9/gcc/config/aarch64/aarch64.c
@@ -2204,6 +2204,9 @@
   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 @@
   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_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 @@
 
   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);