aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authoramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-22 10:35:06 +0000
committeramonakov <amonakov@138bc75d-0d04-0410-961f-82ee72b054a4>2010-11-22 10:35:06 +0000
commit0cfef6c5572d909b1b2fcd28df32132a8dba1e0a (patch)
treee9e9c058158ad6ffd6c71ebc44e91416cfc12a90 /gcc
parent8fda32621c0fa3d39858a5fabe8ca5d7a17ee385 (diff)
PR rtl-optimization/45652
* alias.c (get_reg_base_value): New. * rtl.h (get_reg_base_value): Add prototype. * sel-sched.c (init_regs_for_mode): Use it. Don't use registers with non-null REG_BASE_VALUE for renaming. testsuite: * gcc.dg/pr45652.c: New. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@167025 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/alias.c8
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/sel-sched.c3
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.dg/pr45652.c39
6 files changed, 63 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index b9063309f5d..89e3109760e 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2010-11-22 Alexander Monakov <amonakov@ispras.ru>
+
+ PR rtl-optimization/45652
+ * alias.c (get_reg_base_value): New.
+ * rtl.h (get_reg_base_value): Add prototype.
+ * sel-sched.c (init_regs_for_mode): Use it. Don't use registers with
+ non-null REG_BASE_VALUE for renaming.
2010-11-22 Jeremie Salvucci <jeremie.salvucci@free.fr>
Basile Starynkevitch <basile@starynkevitch.net>
diff --git a/gcc/alias.c b/gcc/alias.c
index 2a877979417..5b04f85791c 100644
--- a/gcc/alias.c
+++ b/gcc/alias.c
@@ -1291,6 +1291,14 @@ record_set (rtx dest, const_rtx set, void *data ATTRIBUTE_UNUSED)
reg_seen[regno] = 1;
}
+/* Return REG_BASE_VALUE for REGNO. Selective scheduler uses this to avoid
+ using hard registers with non-null REG_BASE_VALUE for renaming. */
+rtx
+get_reg_base_value (unsigned int regno)
+{
+ return VEC_index (rtx, reg_base_value, regno);
+}
+
/* If a value is known for REGNO, return it. */
rtx
diff --git a/gcc/rtl.h b/gcc/rtl.h
index ab215d6ea48..d5a674898f3 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -2510,6 +2510,7 @@ extern rtx find_base_term (rtx);
extern rtx gen_hard_reg_clobber (enum machine_mode, unsigned int);
extern rtx get_reg_known_value (unsigned int);
extern bool get_reg_known_equiv_p (unsigned int);
+extern rtx get_reg_base_value (unsigned int);
#ifdef STACK_REGS
extern int stack_regs_mentioned (const_rtx insn);
diff --git a/gcc/sel-sched.c b/gcc/sel-sched.c
index cb3c379524e..3b5603c7efa 100644
--- a/gcc/sel-sched.c
+++ b/gcc/sel-sched.c
@@ -1139,6 +1139,9 @@ init_regs_for_mode (enum machine_mode mode)
/* Can't use regs which aren't saved by
the prologue. */
|| !TEST_HARD_REG_BIT (sel_hrd.regs_ever_used, cur_reg + i)
+ /* Can't use regs with non-null REG_BASE_VALUE, because adjusting
+ it affects aliasing globally and invalidates all AV sets. */
+ || get_reg_base_value (cur_reg + i)
#ifdef LEAF_REGISTERS
/* We can't use a non-leaf register if we're in a
leaf function. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 0f889d83720..4458ab75c2d 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2010-11-22 Alexander Monakov <amonakov@ispras.ru>
+
+ PR rtl-optimization/45652
+ * gcc.dg/pr45652.c: New.
+
2010-11-21 Richard Henderson <rth@redhat.com>
PR rtl-optimization/46571
diff --git a/gcc/testsuite/gcc.dg/pr45652.c b/gcc/testsuite/gcc.dg/pr45652.c
new file mode 100644
index 00000000000..8f55f0c8cb1
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr45652.c
@@ -0,0 +1,39 @@
+/* { dg-do run { target powerpc*-*-* ia64-*-* x86_64-*-* } } */
+/* { dg-options "-O2 -fselective-scheduling2" } */
+
+struct S {
+ double i[2];
+};
+
+void __attribute__ ((noinline)) checkcd (struct S x)
+{
+ if (x.i[0] != 7.0 || x.i[1] != 8.0)
+ __builtin_abort ();
+}
+
+void __attribute__ ((noinline)) testvacd (int n, ...)
+{
+ int i;
+ __builtin_va_list ap;
+ __builtin_va_start (ap, n);
+ for (i = 0; i < n; i++)
+ {
+ struct S t = __builtin_va_arg (ap, struct S);
+ checkcd (t);
+ }
+ __builtin_va_end (ap);
+}
+
+void
+testitcd (void)
+{
+ struct S x = { { 7.0, 8.0 } };
+ testvacd (2, x, x);
+}
+
+int
+main ()
+{
+ testitcd ();
+ return 0;
+}