aboutsummaryrefslogtreecommitdiff
path: root/gcc/ipa-pure-const.c
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-06-11 15:12:48 +0000
committerJan Hubicka <jh@suse.cz>2010-06-11 15:12:48 +0000
commitf80c6efbd98c8a79b51738c3eb2e2972a155165d (patch)
tree16ca667e2dfda5b37d37f56cf98736d96c7b23a2 /gcc/ipa-pure-const.c
parent105f84a8d8482c13c022076e81caa725f9c1dfc5 (diff)
* ipa-pure-const.c (special_builtlin_state): New function.
(check_call): Use it instead of special casign BUILT_IN_RETURN. (propagate_pure_const): Use it. * gcc.dg/ipa/pure-const-2.c: New testcase. git-svn-id: https://gcc.gnu.org/svn/gcc/trunk@160615 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/ipa-pure-const.c')
-rw-r--r--gcc/ipa-pure-const.c53
1 files changed, 48 insertions, 5 deletions
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index da8d442107b..8678663ed6c 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -420,6 +420,40 @@ worse_state (enum pure_const_state_e *state, bool *looping,
*looping = MAX (*looping, looping2);
}
+/* Recognize special cases of builtins that are by themself not pure or const
+ but function using them is. */
+static bool
+special_builtlin_state (enum pure_const_state_e *state, bool *looping,
+ tree callee)
+{
+ if (DECL_BUILT_IN_CLASS (callee) == BUILT_IN_NORMAL)
+ switch (DECL_FUNCTION_CODE (callee))
+ {
+ case BUILT_IN_RETURN:
+ case BUILT_IN_UNREACHABLE:
+ case BUILT_IN_ALLOCA:
+ case BUILT_IN_STACK_SAVE:
+ case BUILT_IN_STACK_RESTORE:
+ case BUILT_IN_EH_POINTER:
+ case BUILT_IN_EH_FILTER:
+ case BUILT_IN_UNWIND_RESUME:
+ case BUILT_IN_CXA_END_CLEANUP:
+ case BUILT_IN_EH_COPY_VALUES:
+ case BUILT_IN_FRAME_ADDRESS:
+ case BUILT_IN_APPLY:
+ case BUILT_IN_APPLY_ARGS:
+ case BUILT_IN_ARGS_INFO:
+ *looping = false;
+ *state = IPA_CONST;
+ return true;
+ case BUILT_IN_PREFETCH:
+ *looping = true;
+ *state = IPA_CONST;
+ return true;
+ }
+ return false;
+}
+
/* Check the parameters of a function call to CALL_EXPR to see if
there are any references in the parameters that are not allowed for
pure or const functions. Also check to see if this is either an
@@ -470,9 +504,15 @@ check_call (funct_state local, gimple call, bool ipa)
graph. */
if (callee_t)
{
- /* built_in_return is really just an return statemnt. */
- if (gimple_call_builtin_p (call, BUILT_IN_RETURN))
- return;
+ enum pure_const_state_e call_state;
+ bool call_looping;
+
+ if (special_builtlin_state (&call_state, &call_looping, callee_t))
+ {
+ worse_state (&local->pure_const_state, &local->looping,
+ call_state, call_looping);
+ return;
+ }
/* When bad things happen to bad functions, they cannot be const
or pure. */
if (setjmp_call_p (callee_t))
@@ -1153,10 +1193,13 @@ propagate_pure_const (void)
edge_looping = y_l->looping;
}
}
+ else if (special_builtlin_state (&edge_state, &edge_looping,
+ y->decl))
+ ;
else
state_from_flags (&edge_state, &edge_looping,
- flags_from_decl_or_type (y->decl),
- cgraph_edge_cannot_lead_to_return (e));
+ flags_from_decl_or_type (y->decl),
+ cgraph_edge_cannot_lead_to_return (e));
/* Merge the results with what we already know. */
better_state (&edge_state, &edge_looping,