diff options
-rw-r--r-- | gcc/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/ipa-pure-const.c | 30 | ||||
-rw-r--r-- | gcc/ipa-utils.c | 2 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 7 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/pr33826.c | 40 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/20030714-1.c | 7 |
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" } } */ |