aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gcc/ChangeLog7
-rw-r--r--gcc/ipa-pure-const.c30
-rw-r--r--gcc/ipa-utils.c2
-rw-r--r--gcc/testsuite/ChangeLog7
-rw-r--r--gcc/testsuite/gcc.dg/pr33826.c40
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c7
6 files changed, 85 insertions, 8 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index c42ff43..d68ef6b 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,10 @@
+2007-11-07 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ PR middle-end/33826
+ * ipa-pure-const (static_execute): Added code to keep recursive
+ functions from being marked as pure or const.
+ * ipa-utils (searchc): Fixed comment.
+
2007-11-08 Tom Tromey <tromey@redhat.com>
* common.opt (fshow-column): Default to 0.
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index d3b880a..eb4262a 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -644,6 +644,7 @@ static_execute (void)
for (i = 0; i < order_pos; i++ )
{
enum pure_const_state_e pure_const_state = IPA_CONST;
+ int count = 0;
node = order[i];
/* Find the worst state for any node in the cycle. */
@@ -660,11 +661,40 @@ static_execute (void)
if (!w_l->state_set_in_source)
{
struct cgraph_edge *e;
+ count++;
+
+ /* FIXME!!! Because of pr33826, we cannot have either
+ immediate or transitive recursive functions marked as
+ pure or const because dce can delete a function that
+ is in reality an infinite loop. A better solution
+ than just outlawing them is to add another bit the
+ functions to distinguish recursive from non recursive
+ pure and const function. This would allow the
+ recursive ones to be cse'd but not dce'd. In this
+ same vein, we could allow functions with loops to
+ also be cse'd but not dce'd.
+
+ Unfortunately we are late in stage 3, and the fix
+ described above is is not appropriate. */
+ if (count > 1)
+ {
+ pure_const_state = IPA_NEITHER;
+ break;
+ }
+
for (e = w->callees; e; e = e->next_callee)
{
struct cgraph_node *y = e->callee;
/* Only look at the master nodes and skip external nodes. */
y = cgraph_master_clone (y);
+
+ /* Check for immediate recursive functions. See the
+ FIXME above. */
+ if (w == y)
+ {
+ pure_const_state = IPA_NEITHER;
+ break;
+ }
if (y)
{
funct_state y_l = get_function_state (y);
diff --git a/gcc/ipa-utils.c b/gcc/ipa-utils.c
index b8e25bb..2a95629 100644
--- a/gcc/ipa-utils.c
+++ b/gcc/ipa-utils.c
@@ -76,7 +76,7 @@ struct searchc_env {
has been customized for cgraph_nodes. The env parameter is because
it is recursive and there are no nested functions here. This
function should only be called from itself or
- cgraph_reduced_inorder. ENV is a stack env and would be
+ ipa_utils_reduced_inorder. ENV is a stack env and would be
unnecessary if C had nested functions. V is the node to start
searching from. */
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index b07ada0..386301c 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,10 @@
+2007-11-08 Kenneth Zadeck <zadeck@naturalbridge.com>
+
+ PR middle-end/33826
+ * gcc.dg/pr33826.c: New.
+ * gcc.dg/tree-ssa/20030714-1.c: Removed two tests that depend on
+ recursive functions being marked pure or const.
+
2007-11-08 Tobias Burnus <burnus@net-b.de>
PR fortran/33917
diff --git a/gcc/testsuite/gcc.dg/pr33826.c b/gcc/testsuite/gcc.dg/pr33826.c
new file mode 100644
index 0000000..a0cfd45
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/pr33826.c
@@ -0,0 +1,40 @@
+/* Regression test for PR middle-end/33826 */
+/* Verify that recursive functions cannot be pure or const. */
+
+/* { dg-do compile } */
+/* { dg-options "-O1 -fdump-ipa-pure-const" } */
+
+int recurese1 (int i)
+{
+ return recurse1 (i+1);
+}
+
+int recurse2a (int i)
+{
+ return recurse2b (i+1);
+}
+
+int recurse2b (int i)
+{
+ return recurse2a (i+1);
+}
+
+int norecurse1a (int i)
+{
+ return norecurse1b (i+1);
+}
+
+int norecurse1b (int i)
+{
+ return i+1;
+}
+
+/* { dg-final { scan-ipa-dump "found to be const: norecurse1a" "pure-const" } } */
+/* { dg-final { scan-ipa-dump "found to be const: norecurse1b" "pure-const" } } */
+/* { dg-final { scan-ipa-dump-not "found to be pure: recurse1" "pure-const" } } */
+/* { dg-final { scan-ipa-dump-not "found to be pure: recurse2a" "pure-const" } } */
+/* { dg-final { scan-ipa-dump-not "found to be pure: recurse2b" "pure-const" } } */
+/* { dg-final { scan-ipa-dump-not "found to be const: recurse1" "pure-const" } } */
+/* { dg-final { scan-ipa-dump-not "found to be const: recurse2a" "pure-const" } } */
+/* { dg-final { scan-ipa-dump-not "found to be const: recurse2b" "pure-const" } } */
+/* { dg-final { cleanup-ipa-dump "pure-const" } } */
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c
index 34fb266..a48cfdb 100644
--- a/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c
@@ -34,13 +34,6 @@ find_base_value (src)
}
-/* There should be four IF conditionals. */
-/* { dg-final { scan-tree-dump-times "if " 4 "dom3"} } */
-
/* There should be no casts to short unsigned int. */
/* { dg-final { scan-tree-dump-times "\\(short unsigned int\\)" 0 "dom3"} } */
-/* There should be two loads of ->code. */
-/* { dg-final { scan-tree-dump-times "->code" 2 "dom3"} } */
-
-/* { dg-final { cleanup-tree-dump "dom3" } } */