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: -fuse-caller-save - Collect register usage information


On 19-06-14 21:45, Richard Henderson wrote:
On 06/19/2014 12:36 PM, Jan Hubicka wrote:
On 06/19/2014 09:06 AM, Tom de Vries wrote:

2014-06-19  Tom de Vries  <tom@codesourcery.com>

	* final.c (collect_fn_hard_reg_usage): Don't save function_used_regs if
	it contains all call_used_regs.

Ok.

When we now have way to represent different reg usages for functions, what would be best
way to make local functions to default into saving some SSE registers on x86/x86-64?

I wouldn't do that at all.  Leave all sse registers call-clobbered.  This way
you don't need to have different entry points (or one possibly less efficient
entry point) when a function is used both locally and globally.

What I would investigate is how to use this hard reg usage data in the register
allocator.  If we know that the callee only uses xmm0-xmm4, then we can keep
xmm5-xmm15 live across the call.


AFAIU, what you describe here already works. This patch contains a version of the fuse-caller-save test with xmm registers. The callee bar only uses xmm0, and caller foo keeps xmm1 live across the call.

OK for trunk?

Thanks,
- Tom

2014-07-13  Tom de Vries  <tom@codesourcery.com>

	* gcc.target/i386/fuse-caller-save-xmm-run.c: New test.
	* gcc.target/i386/fuse-caller-save-xmm.c: New test.

diff --git a/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm-run.c b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm-run.c
new file mode 100644
index 0000000..17385fa
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm-run.c
@@ -0,0 +1,34 @@
+/* { dg-do run } */
+/* { dg-options "-O2 -msse -fuse-caller-save" } */
+
+typedef double v2df __attribute__((vector_size (16)));
+
+static v2df __attribute__((noinline))
+bar (v2df a)
+{ 
+  return a + (v2df){ 3.0, 3.0 };
+}
+
+v2df __attribute__((noinline))
+foo (v2df y)
+{
+  return y + bar (y);
+}
+
+int
+main (void)
+{
+  int success;
+  union {
+    v2df v;
+    double d[2];
+  } u;
+
+  u.v = foo ((v2df){ 5.0, 5.0});
+  success = (u.d[0] == 13.0
+	     && u.d[1] == 13.0);
+
+  return !success;
+}
+
+
diff --git a/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm.c b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm.c
new file mode 100644
index 0000000..de1ca63
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/fuse-caller-save-xmm.c
@@ -0,0 +1,38 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse -fuse-caller-save" } */
+
+typedef double v2df __attribute__((vector_size (16)));
+
+static v2df __attribute__((noinline))
+bar (v2df a)
+{ 
+  return a + (v2df){ 3.0, 3.0 };
+}
+
+v2df __attribute__((noinline))
+foo (v2df y)
+{
+  return y + bar (y);
+}
+
+int
+main (void)
+{
+  int success;
+  union {
+    v2df v;
+    double d[2];
+  } u;
+
+  u.v = foo ((v2df){ 5.0, 5.0});
+  success = (u.d[0] == 13.0
+	     && u.d[1] == 13.0);
+
+  return !success;
+}
+
+/* { dg-final { scan-assembler-not "movaps\t%xmm1, \\(%rsp\\)" } } */
+/* { dg-final { scan-assembler-not "movapd\t\\(%rsp\\), %xmm1" } } */
+/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 16" 1 } } */
+/* { dg-final { scan-assembler-times ".cfi_def_cfa_offset 32" 1 } } */
+

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