[ARC] Don't allow the last ZOL insn to be in a delay slot.
authorClaudiu Zissulescu <claziss@synopsys.com>
Thu, 30 Nov 2017 14:42:12 +0000 (15:42 +0100)
committerClaudiu Zissulescu <claziss@gcc.gnu.org>
Thu, 30 Nov 2017 14:42:12 +0000 (15:42 +0100)
The ARC ZOL implementation doesn't allow the last instruction to be a
control instruction or part of a delay slot.  Thus, we add a note to
the last ZOL instruction which will prevent it to finish into a delay
slot.

2017-10-20  Claudiu Zissulescu  <claziss@synopsys.com>

* config/arc/arc.c (hwloop_optimize): Prevent the last
        ZOL instruction to end into a delay slot.
* config/arc/arc.md (cond_delay_insn): Check if the instruction
can be placed into a delay slot against reg_note.
(in_delay_slot): Likewise.

testsuite/
2017-10-20  Claudiu Zissulescu  <claziss@synopsys.com>

* gcc.target/arc/loop-3.c: New test.
* gcc.target/arc/loop-4.c: Likewise.

[FIX][ZOL] fix checking for jumps

From-SVN: r255275

gcc/ChangeLog
gcc/config/arc/arc.c
gcc/config/arc/arc.md
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/arc/loop-3.c [new file with mode: 0644]
gcc/testsuite/gcc.target/arc/loop-4.c [new file with mode: 0644]

index 945490947dfec44a1945184da589c549ce299170..ae502ca2b6a51cc4a6a49d14f5100d7b731e13c2 100644 (file)
@@ -1,3 +1,10 @@
+2017-11-30  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * config/arc/arc.c (hwloop_optimize): Prevent the last ZOL
+       instruction to end into a delay slot.
+       * config/arc/arc.md (cond_delay_insn): Check if the instruction
+       can be placed into a delay slot against reg_note.
+
 2017-11-30  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * config/arc/arc.c (hwloop_optimize): Update hw-loop's end/start
index 57ea502db4a0d6f9e35a2ff733c5cfdd4b5cd1b1..6b6bf8224e6831f363dbd03b93effe03f795da48 100644 (file)
@@ -7408,6 +7408,12 @@ hwloop_optimize (hwloop_info loop)
                 loop->loop_no);
       last_insn = emit_insn_after (gen_nopv (), last_insn);
     }
+
+  /* SAVE_NOTE is used by haifa scheduler.  However, we are after it
+     and we can use it to indicate the last ZOL instruction cannot be
+     part of a delay slot.  */
+  add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
+
   loop->last_insn = last_insn;
 
   /* Get the loop iteration register.  */
index faf66985afffdd04c227d66da4e60f48ad1ba65a..b39f04771c9a55ce19566a510f3c65a5637fbaa1 100644 (file)
             (symbol_ref "(arc_hazard (prev_active_insn (insn), insn)
                           + arc_hazard (insn, next_active_insn (insn)))"))
         (const_string "false")
+        (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
+        (const_string "false")
         (eq_attr "iscompact" "maybe") (const_string "true")
         ]
 
   (cond [(eq_attr "cond" "!canuse") (const_string "no")
         (eq_attr "type" "call,branch,uncond_branch,jump,brcc")
         (const_string "no")
+        (match_test "find_reg_note (insn, REG_SAVE_NOTE, GEN_INT (2))")
+        (const_string "no")
         (eq_attr "length" "2,4") (const_string "yes")]
        (const_string "no")))
 
index 1b5359d319e1eb3371936806002a496f1279bfaf..972d1cbe6ef3b0e5f1b2cefaae36423728fb1400 100644 (file)
@@ -1,3 +1,8 @@
+2017-11-30  Claudiu Zissulescu  <claziss@synopsys.com>
+
+       * gcc.target/arc/loop-3.c: New test.
+       * gcc.target/arc/loop-4.c: Likewise.
+
 2017-11-30  Claudiu Zissulescu  <claziss@synopsys.com>
 
        * gcc.target/arc/loop-2.cpp: New test.
diff --git a/gcc/testsuite/gcc.target/arc/loop-3.c b/gcc/testsuite/gcc.target/arc/loop-3.c
new file mode 100644 (file)
index 0000000..bf7aec9
--- /dev/null
@@ -0,0 +1,27 @@
+/* { dg-do assemble } */
+/* { dg-do compile } */
+/* { dg-options "-O2 -mno-sdata" } *
+
+/* This example will fail to assemble if the last instruction is a
+   branch with delay slot.  */
+int d;
+extern char * fn2 (void);
+
+void fn1(void)
+{
+  char *a = fn2();
+  for (;;) {
+    long long b;
+    int e = 8;
+    for (; e <= 63; e += 7) {
+      long c = *a++;
+      b += c & e;
+      if (c & 28)
+        break;
+    }
+    d = b;
+  }
+}
+
+/* { dg-final { scan-assembler "bne_s @.L2" } } */
+/* { dg-final { scan-assembler-not "add.eq" } } */
diff --git a/gcc/testsuite/gcc.target/arc/loop-4.c b/gcc/testsuite/gcc.target/arc/loop-4.c
new file mode 100644 (file)
index 0000000..99a93a7
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do assemble } */
+/* { dg-do compile } */
+/* { dg-options "-Os" } */
+
+
+void fn1(void *p1, int p2, int p3)
+{
+  char *d = p1;
+  do
+    *d++ = p2;
+  while (--p3);
+}
+
+/* { dg-final { scan-assembler "lp_count" } } */