aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2011-02-03 09:29:03 +0100
committerJakub Jelinek <jakub@gcc.gnu.org>2011-02-03 09:29:03 +0100
commit89843f5dfbb0b867f42c7743a8691ebe5bb35682 (patch)
tree4ee13b18ac1af831b910bd634daf1a77e1ed061b
parent996c0cb05f747d94ff4d6e9329e702414f46f700 (diff)
downloadgcc-89843f5dfbb0b867f42c7743a8691ebe5bb35682.zip
gcc-89843f5dfbb0b867f42c7743a8691ebe5bb35682.tar.gz
gcc-89843f5dfbb0b867f42c7743a8691ebe5bb35682.tar.bz2
re PR target/47564 (internal compiler error in memory_address_addr_space, at explow.c:504)
PR target/47564 * toplev.c (target_reinit): Save and restore *crtl and regno_reg_rtx around backend_init_target and lang_dependent_init_target calls. * cgraphunit.c (cgraph_debug_gimple_stmt): New function. (verify_cgraph_node): Don't call set_cfun here. Use cgraph_debug_gimple_stmt instead of debug_gimple_stmt. Set error_found for incorrectly represented calls to thunks. * gcc.target/i386/pr47564.c: New test. From-SVN: r169784
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/cgraphunit.c29
-rw-r--r--gcc/testsuite/ChangeLog5
-rw-r--r--gcc/testsuite/gcc.target/i386/pr47564.c42
-rw-r--r--gcc/toplev.c26
5 files changed, 99 insertions, 13 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 90e257b..bf62fca 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+2011-02-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/47564
+ * toplev.c (target_reinit): Save and restore *crtl and regno_reg_rtx
+ around backend_init_target and lang_dependent_init_target calls.
+ * cgraphunit.c (cgraph_debug_gimple_stmt): New function.
+ (verify_cgraph_node): Don't call set_cfun here. Use
+ cgraph_debug_gimple_stmt instead of debug_gimple_stmt.
+ Set error_found for incorrectly represented calls to thunks.
+
2011-02-03 Alexandre Oliva <aoliva@redhat.com>
PR debug/43092
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 848eba6..f6fe2724 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -440,13 +440,22 @@ verify_edge_count_and_frequency (struct cgraph_edge *e)
return error_found;
}
+/* Switch to THIS_CFUN if needed and print STMT to stderr. */
+static void
+cgraph_debug_gimple_stmt (struct function *this_cfun, gimple stmt)
+{
+ /* debug_gimple_stmt needs correct cfun */
+ if (cfun != this_cfun)
+ set_cfun (this_cfun);
+ debug_gimple_stmt (stmt);
+}
+
/* Verify cgraph nodes of given cgraph node. */
DEBUG_FUNCTION void
verify_cgraph_node (struct cgraph_node *node)
{
struct cgraph_edge *e;
struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
- struct function *saved_cfun = cfun;
basic_block this_block;
gimple_stmt_iterator gsi;
bool error_found = false;
@@ -455,8 +464,6 @@ verify_cgraph_node (struct cgraph_node *node)
return;
timevar_push (TV_CGRAPH_VERIFY);
- /* debug_generic_stmt needs correct cfun */
- set_cfun (this_cfun);
for (e = node->callees; e; e = e->next_callee)
if (e->aux)
{
@@ -499,7 +506,7 @@ verify_cgraph_node (struct cgraph_node *node)
error ("An indirect edge from %s is not marked as indirect or has "
"associated indirect_info, the corresponding statement is: ",
identifier_to_locale (cgraph_node_name (e->caller)));
- debug_gimple_stmt (e->call_stmt);
+ cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
error_found = true;
}
}
@@ -642,7 +649,7 @@ verify_cgraph_node (struct cgraph_node *node)
if (e->aux)
{
error ("shared call_stmt:");
- debug_gimple_stmt (stmt);
+ cgraph_debug_gimple_stmt (this_cfun, stmt);
error_found = true;
}
if (!e->indirect_unknown_callee)
@@ -676,7 +683,8 @@ verify_cgraph_node (struct cgraph_node *node)
{
error ("a call to thunk improperly represented "
"in the call graph:");
- debug_gimple_stmt (stmt);
+ cgraph_debug_gimple_stmt (this_cfun, stmt);
+ error_found = true;
}
}
else if (decl)
@@ -685,14 +693,14 @@ verify_cgraph_node (struct cgraph_node *node)
"corresponding to a call_stmt with "
"a known declaration:");
error_found = true;
- debug_gimple_stmt (e->call_stmt);
+ cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
}
e->aux = (void *)1;
}
else if (decl)
{
error ("missing callgraph edge for call stmt:");
- debug_gimple_stmt (stmt);
+ cgraph_debug_gimple_stmt (this_cfun, stmt);
error_found = true;
}
}
@@ -710,7 +718,7 @@ verify_cgraph_node (struct cgraph_node *node)
error ("edge %s->%s has no corresponding call_stmt",
identifier_to_locale (cgraph_node_name (e->caller)),
identifier_to_locale (cgraph_node_name (e->callee)));
- debug_gimple_stmt (e->call_stmt);
+ cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
error_found = true;
}
e->aux = 0;
@@ -721,7 +729,7 @@ verify_cgraph_node (struct cgraph_node *node)
{
error ("an indirect edge from %s has no corresponding call_stmt",
identifier_to_locale (cgraph_node_name (e->caller)));
- debug_gimple_stmt (e->call_stmt);
+ cgraph_debug_gimple_stmt (this_cfun, e->call_stmt);
error_found = true;
}
e->aux = 0;
@@ -732,7 +740,6 @@ verify_cgraph_node (struct cgraph_node *node)
dump_cgraph_node (stderr, node);
internal_error ("verify_cgraph_node failed");
}
- set_cfun (saved_cfun);
timevar_pop (TV_CGRAPH_VERIFY);
}
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 69da9d6..001d604 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2011-02-03 Jakub Jelinek <jakub@redhat.com>
+
+ PR target/47564
+ * gcc.target/i386/pr47564.c: New test.
+
2011-02-03 Alexandre Oliva <aoliva@redhat.com>
PR tree-optimization/45122
diff --git a/gcc/testsuite/gcc.target/i386/pr47564.c b/gcc/testsuite/gcc.target/i386/pr47564.c
new file mode 100644
index 0000000..5d3f25d
--- /dev/null
+++ b/gcc/testsuite/gcc.target/i386/pr47564.c
@@ -0,0 +1,42 @@
+/* PR target/47564 */
+/* { dg-do compile } */
+/* { dg-options "-O2 -msse2" } */
+
+static inline unsigned long long
+foo (const unsigned char *p)
+{
+ return 1;
+}
+
+__attribute__ ((__target__ ("sse4"))) void
+bar (unsigned long long *x, const void *b, long long m)
+{
+ const unsigned char *p = (const unsigned char *) b;
+ const unsigned char *e = p + m;
+ unsigned int l = *x;
+ unsigned long long n = l;
+
+ if ((e - p) >= 8192)
+ {
+ while ((e - p) >= 128)
+ {
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ }
+ }
+
+ while ((e - p) >= 16)
+ {
+ n = __builtin_ia32_crc32di (n, foo (p));
+ n = __builtin_ia32_crc32di (n, foo (p));
+ }
+ l = n;
+ *x = l;
+}
diff --git a/gcc/toplev.c b/gcc/toplev.c
index 082c842..64af112 100644
--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -1,7 +1,7 @@
/* Top level of GCC compilers (cc1, cc1plus, etc.)
Copyright (C) 1987, 1988, 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998,
- 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
- Free Software Foundation, Inc.
+ 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
+ 2011 Free Software Foundation, Inc.
This file is part of GCC.
@@ -1780,11 +1780,33 @@ lang_dependent_init (const char *name)
void
target_reinit (void)
{
+ struct rtl_data saved_x_rtl;
+ rtx *saved_regno_reg_rtx;
+
+ /* Save *crtl and regno_reg_rtx around the reinitialization
+ to allow target_reinit being called even after prepare_function_start. */
+ saved_regno_reg_rtx = regno_reg_rtx;
+ if (saved_regno_reg_rtx)
+ {
+ saved_x_rtl = *crtl;
+ memset (crtl, '\0', sizeof (*crtl));
+ regno_reg_rtx = NULL;
+ }
+
/* Reinitialize RTL backend. */
backend_init_target ();
/* Reinitialize lang-dependent parts. */
lang_dependent_init_target ();
+
+ /* And restore it at the end, as free_after_compilation from
+ expand_dummy_function_end clears it. */
+ if (saved_regno_reg_rtx)
+ {
+ *crtl = saved_x_rtl;
+ regno_reg_rtx = saved_regno_reg_rtx;
+ saved_regno_reg_rtx = NULL;
+ }
}
void