aboutsummaryrefslogtreecommitdiff
path: root/gcc/cgraph.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2016-04-16 20:54:49 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2016-04-16 18:54:49 +0000
commitcc950f9882d404b66cecae04519bb42a3c13d7f3 (patch)
tree309f864360341cd70502972284de03b9c4215fe3 /gcc/cgraph.c
parentf13fe18b5b4881a457c2176214349d322b61e187 (diff)
downloadgcc-cc950f9882d404b66cecae04519bb42a3c13d7f3.zip
gcc-cc950f9882d404b66cecae04519bb42a3c13d7f3.tar.gz
gcc-cc950f9882d404b66cecae04519bb42a3c13d7f3.tar.bz2
re PR c++/70018 (Possible issue around IPO and C++ comdats discovered as pure/const)
PR ipa/70018 * cgraph.c (cgraph_set_const_flag_1): Only set as pure if function does not bind to current def. * ipa-pure-const.c (worse_state): Add FROM and TO parameters; handle conservatively calls to functions that does not need to bind to current def. (check_call): Update call of worse_state. (ignore_edge_for_nothrow): Update. (ignore_edge_for_pure_const): Likewise. (propagate_pure_const): Update calls to worse_state. (skip_function_for_local_pure_const): Reformat comments. * g++.dg/ipa/pure-const-1.C: New testcase. * g++.dg/ipa/pure-const-2.C: New testcase. * g++.dg/ipa/pure-const-3.C: New testcase. From-SVN: r235065
Diffstat (limited to 'gcc/cgraph.c')
-rw-r--r--gcc/cgraph.c30
1 files changed, 29 insertions, 1 deletions
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 0ced2db..c43adb9 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -2393,7 +2393,35 @@ cgraph_set_const_flag_1 (cgraph_node *node, void *data)
if (DECL_STATIC_DESTRUCTOR (node->decl))
DECL_STATIC_DESTRUCTOR (node->decl) = 0;
}
- TREE_READONLY (node->decl) = data != NULL;
+
+ /* Consider function:
+
+ bool a(int *p)
+ {
+ return *p==*p;
+ }
+
+ During early optimization we will turn this into:
+
+ bool a(int *p)
+ {
+ return true;
+ }
+
+ Now if this function will be detected as CONST however when interposed it
+ may end up being just pure. We always must assume the worst scenario here.
+ */
+ if (TREE_READONLY (node->decl))
+ ;
+ else if (node->binds_to_current_def_p ())
+ TREE_READONLY (node->decl) = data != NULL;
+ else
+ {
+ if (dump_file && (dump_flags & TDF_DETAILS))
+ fprintf (dump_file, "Dropping state to PURE because function does "
+ "not bind to current def.\n");
+ DECL_PURE_P (node->decl) = data != NULL;
+ }
DECL_LOOPING_CONST_OR_PURE_P (node->decl) = ((size_t)data & 2) != 0;
return false;
}