aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClaudiu Zissulescu <claziss@synopsys.com>2017-11-30 15:42:12 +0100
committerClaudiu Zissulescu <claziss@gcc.gnu.org>2017-11-30 15:42:12 +0100
commita09202439b038a7e92900bdbe5aa6488b9409a18 (patch)
tree9ded931435c2d2329430591a7fe9c439880f9238
parent5d4c34aaade8422c8289daa8a5c95fab7830de37 (diff)
downloadgcc-a09202439b038a7e92900bdbe5aa6488b9409a18.zip
gcc-a09202439b038a7e92900bdbe5aa6488b9409a18.tar.gz
gcc-a09202439b038a7e92900bdbe5aa6488b9409a18.tar.bz2
[ARC] Don't allow the last ZOL insn to be in a delay slot.
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
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/config/arc/arc.c6
-rw-r--r--gcc/config/arc/arc.md4
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/arc/loop-3.c27
-rw-r--r--gcc/testsuite/gcc.target/arc/loop-4.c14
6 files changed, 63 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 9454909..ae502ca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,5 +1,12 @@
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
labels number of usages.
diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 57ea502..6b6bf82 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -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. */
diff --git a/gcc/config/arc/arc.md b/gcc/config/arc/arc.md
index faf6698..b39f047 100644
--- a/gcc/config/arc/arc.md
+++ b/gcc/config/arc/arc.md
@@ -471,6 +471,8 @@
(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")
]
@@ -498,6 +500,8 @@
(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")))
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1b5359d..972d1cb 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,5 +1,10 @@
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.
2017-11-30 Claudiu Zissulescu <claziss@synopsys.com>
diff --git a/gcc/testsuite/gcc.target/arc/loop-3.c b/gcc/testsuite/gcc.target/arc/loop-3.c
new file mode 100644
index 0000000..bf7aec9
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/loop-3.c
@@ -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
index 0000000..99a93a7
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/loop-4.c
@@ -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" } } */