return;
}
else if (t
- && INDIRECT_REF_P (t)
+ && (INDIRECT_REF_P (t) || TREE_CODE (t) == MEM_REF)
&& TREE_CODE (TREE_OPERAND (t, 0)) == SSA_NAME
&& !ptr_deref_may_alias_global_p (TREE_OPERAND (t, 0)))
{
*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
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))
node = csi_node (csi);
if (node->analyzed && has_function_state (node))
{
- struct bitpack_d *bp;
+ struct bitpack_d bp;
funct_state fs;
int node_ref;
lto_cgraph_encoder_t encoder;
/* Note that flags will need to be read in the opposite
order as we are pushing the bitflags into FLAGS. */
- bp = bitpack_create ();
- bp_pack_value (bp, fs->pure_const_state, 2);
- bp_pack_value (bp, fs->state_previously_known, 2);
- bp_pack_value (bp, fs->looping_previously_known, 1);
- bp_pack_value (bp, fs->looping, 1);
- bp_pack_value (bp, fs->can_throw, 1);
- lto_output_bitpack (ob->main_stream, bp);
- bitpack_delete (bp);
+ bp = bitpack_create (ob->main_stream);
+ bp_pack_value (&bp, fs->pure_const_state, 2);
+ bp_pack_value (&bp, fs->state_previously_known, 2);
+ bp_pack_value (&bp, fs->looping_previously_known, 1);
+ bp_pack_value (&bp, fs->looping, 1);
+ bp_pack_value (&bp, fs->can_throw, 1);
+ lto_output_bitpack (&bp);
}
}
{
unsigned int index;
struct cgraph_node *node;
- struct bitpack_d *bp;
+ struct bitpack_d bp;
funct_state fs;
lto_cgraph_encoder_t encoder;
pushed into FLAGS). */
bp = lto_input_bitpack (ib);
fs->pure_const_state
- = (enum pure_const_state_e) bp_unpack_value (bp, 2);
+ = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
fs->state_previously_known
- = (enum pure_const_state_e) bp_unpack_value (bp, 2);
- fs->looping_previously_known = bp_unpack_value (bp, 1);
- fs->looping = bp_unpack_value (bp, 1);
- fs->can_throw = bp_unpack_value (bp, 1);
+ = (enum pure_const_state_e) bp_unpack_value (&bp, 2);
+ fs->looping_previously_known = bp_unpack_value (&bp, 1);
+ fs->looping = bp_unpack_value (&bp, 1);
+ fs->can_throw = bp_unpack_value (&bp, 1);
if (dump_file)
{
int flags = flags_from_decl_or_type (node->decl);
if (fs->can_throw)
fprintf (dump_file," function is locally throwing\n");
}
- bitpack_delete (bp);
}
lto_destroy_simple_input_block (file_data,
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,