This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [PATCH] Treat tail calls as scheduling barriers (PR rtl-optimization/48721)


On 11/30/2011 12:54 PM, Jakub Jelinek wrote:
Hi!

As discussed in the PR, I think tail calls are best handled as full
scheduling barriers, scheduling tail calls before other insns effectively
means we remove those other insns, but isn't dead insn removal the job
of other passes instead?
In any case, tail calls need to come up after all restoration of
call saved register, on this testcase GCC wanted to schedule a tail
call before r12 restoring insn.

Bootstrapped/regtested on x86_64-linux and i686-linux, ok for trunk?

2011-11-30 Jakub Jelinek<jakub@redhat.com>

	PR rtl-optimization/48721
	* sched-deps.c (sched_analyze_insn): For SIBLING_CALL_P set
	reg_pending_barrier to TRUE_BARRIER.

* gcc.target/i386/pr48721.c: New test.

--- gcc/sched-deps.c.jj	2011-11-28 17:58:04.000000000 +0100
+++ gcc/sched-deps.c	2011-11-30 14:10:55.117267854 +0100
@@ -2873,7 +2873,11 @@ sched_analyze_insn (struct deps_desc *de
  	  else
  	    sched_analyze_2 (deps, XEXP (link, 0), insn);
  	}
-      if (find_reg_note (insn, REG_SETJMP, NULL))
+      /* Don't schedule anything after a tail call, tail call needs
+	 to use at least all call-saved registers.  */
+      if (SIBLING_CALL_P (insn))
+	reg_pending_barrier = TRUE_BARRIER;
+      else if (find_reg_note (insn, REG_SETJMP, NULL))
  	reg_pending_barrier = MOVE_BARRIER;
      }

--- gcc/testsuite/gcc.target/i386/pr48721.c.jj	2011-11-30 14:14:26.290628842 +0100
+++ gcc/testsuite/gcc.target/i386/pr48721.c	2011-11-30 12:24:06.000000000 +0100
@@ -0,0 +1,51 @@
+/* PR rtl-optimization/48721 */
+/* { dg-do compile } */
+/* { dg-options "-O -foptimize-sibling-calls -fsched2-use-superblocks -fschedule-insns2 -mtune=core2" } */
+
+extern unsigned char a[];
+extern int b[], d[], e[], f[], g[], *h[], m[], *n[], o[];
+extern char c[];
+
+struct S
+{
+  unsigned char s1;
+  int s2, s3, s4, s5, s6, s7, s8;
+};
+
+__attribute__((noinline, noclone)) int
+foo (int x)
+{
+  return 0;
+}
+
+int
+bar (int x, struct S *y)
+{
+  int z;
+  switch (x)
+    {
+    case 1:
+    case 2:
+      {
+	int t2, t4, t5, t6, t7, t8;
+	z = o[y->s8 * 6];
+	t8 = *n[m[x] * 5];
+	t4 = *h[y->s7];
+	t7 = z;
+	z = g[f[x] + y->s6];
+	t6 = e[y->s5];
+	t5 = d[c[x] + y->s3 * 17];
+	if (z)
+	  t2 = b[z];
+	if (a[z] != y->s1)
+	  return foo (x);
+	y->s8 = t8;
+	y->s4 = t4;
+	y->s7 = t7;
+	y->s6 = t6;
+	y->s5 = t5;
+	y->s2 = t2;
+      }
+    }
+  return 0;
+}

Ok, thanks.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]