[ARC] Emit blockage regardless to avoid delay slot scheduling.
authorClaudiu Zissulescu <claziss@synopsys.com>
Tue, 16 Apr 2019 10:20:40 +0000 (12:20 +0200)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Tue, 16 Apr 2019 10:20:40 +0000 (12:20 +0200)
1.The delay slot scheduler can reschedule some of the frame related
instructions resulting in having incorect CFI information. This patch
introduces a schedule blockage to avoid this problem.

2.There are cases when an interrupt may happen and not all the current
function stack operations are done, which may result in stack
corruption. Such an example is accessing an returning a local
structure members, which members are allocated on stack. The stack
adjustment and the accessing of the struct member can be reorder as
they may not use both the SP register for the access.

3.Also, do not save/restore SP when in interrupt. The SP is switch by
the core IRQ machinery.

gcc/
xxxx-xx-xx  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc.c (arc_expand_prologue): Emit blockage regardless
to avoid delay slot scheduling.
(arc_must_save_register): Don't save SP.
* config/arc/arc.md (stack_tie): Remove.
(UNSPEC_ARC_STKTIE): Likewise.

From-SVN: r270384

gcc/ChangeLog
gcc/config/arc/arc.c
gcc/config/arc/arc.md

index 610a25f3fe1596ba3c6769ac0459ced5ac933292..0c53e72689d0580031bf08c63d1d3b414075c7e8 100644 (file)
@@ -1,3 +1,11 @@
+2019-04-16  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc.c (arc_expand_prologue): Emit blockage regardless
+       to avoid delay slot scheduling.
+       (arc_must_save_register): Don't save SP.
+       * config/arc/arc.md (stack_tie): Remove.
+       (UNSPEC_ARC_STKTIE): Likewise.
+
 2019-04-16  Kito Cheng  <kito.cheng@gmail.com>
            Shiva Chen  <shiva0217@gmail.com>
 
index 578c42679cb5dd0b000520e3a533d4fb893aa97c..33156eaece7b712bdf2faab821d5f7cab8a74d6b 100644 (file)
@@ -2571,13 +2571,12 @@ arc_compute_function_type (struct function *fun)
 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
 
-/* Tell prologue and epilogue if register REGNO should be saved / restored.
-   The return address and frame pointer are treated separately.
-   Don't consider them here.
-   Addition for pic: The gp register needs to be saved if the current
-   function changes it to access gotoff variables.
-   FIXME: This will not be needed if we used some arbitrary register
-   instead of r26.  */
+/* Tell prologue and epilogue if register REGNO should be saved /
+   restored.  The return address, stack pointer and frame pointer are
+   treated separately.  Don't consider them here.  Addition for pic:
+   The gp register needs to be saved if the current function changes
+   it to access gotoff variables.  FIXME: This will not be needed if
+   we used some arbitrary register instead of r26.  */
 
 static bool
 arc_must_save_register (int regno, struct function *func)
@@ -2610,6 +2609,7 @@ arc_must_save_register (int regno, struct function *func)
 
   if ((regno) != RETURN_ADDR_REGNUM
       && (regno) != FRAME_POINTER_REGNUM
+      && (regno) != STACK_POINTER_REGNUM
       && df_regs_ever_live_p (regno)
       && (!call_used_regs[regno]
          || ARC_INTERRUPT_P (fn_type))
@@ -3683,14 +3683,10 @@ arc_expand_prologue (void)
 
   /* Allocate the stack frame.  */
   if (frame_size_to_allocate > 0)
-    {
-      frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
-      /* If the frame pointer is needed, emit a special barrier that
-        will prevent the scheduler from moving stores to the frame
-        before the stack adjustment.  */
-      if (arc_frame_pointer_needed ())
-       emit_insn (gen_stack_tie (stack_pointer_rtx, hard_frame_pointer_rtx));
-    }
+    frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
+
+  /* Emit a blockage to avoid delay slot scheduling.  */
+  emit_insn (gen_blockage ());
 }
 
 /* Do any necessary cleanup after a function to restore stack, frame,
@@ -3727,6 +3723,10 @@ arc_expand_epilogue (int sibcall_p)
   if (!can_trust_sp_p)
     gcc_assert (arc_frame_pointer_needed ());
 
+  /* Emit a blockage to avoid/flush all pending sp operations.  */
+  if (size)
+    emit_insn (gen_blockage ());
+
   if (TARGET_CODE_DENSITY
       && TARGET_CODE_DENSITY_FRAME
       && !ARC_AUTOFP_IRQ_P (fn_type)
index e682983048a4b17b9979fe2842fdbe2bf0a21458..5aafd9df6676356afc90dae45091a3deba93e30f 100644 (file)
   UNSPEC_ARC_VMAC2HU
   UNSPEC_ARC_VMPY2H
   UNSPEC_ARC_VMPY2HU
-  UNSPEC_ARC_STKTIE
 
   VUNSPEC_ARC_RTIE
   VUNSPEC_ARC_SYNC
@@ -6300,18 +6299,6 @@ core_3, archs4x, archs4xd, archs4xd_slow"
   (set_attr "predicable" "yes,no,no,yes,no")
   (set_attr "cond" "canuse,nocond,nocond,canuse_limm,nocond")])
 
-(define_insn "stack_tie"
-  [(set (mem:BLK (scratch))
-       (unspec:BLK [(match_operand:SI 0 "register_operand" "r")
-                    (match_operand:SI 1 "register_operand" "r")]
-                   UNSPEC_ARC_STKTIE))]
-  ""
-  ""
-  [(set_attr "length" "0")
-   (set_attr "iscompact" "false")
-   (set_attr "type" "block")]
-  )
-
 (define_insn "*add_shift"
   [(set (match_operand:SI 0 "register_operand" "=q,r,r")
        (plus:SI (ashift:SI (match_operand:SI 1 "register_operand" "q,r,r")