sanity check ic target

From-SVN: r172276
This commit is contained in:
Xinliang David Li 2011-04-11 20:37:57 +00:00 committed by Xinliang David Li
parent 6075765d8c
commit 26e0228f56
5 changed files with 55 additions and 14 deletions

View File

@ -1,3 +1,10 @@
2011-04-11 Xinliang David Li <davidxl@google.com>
* value-profile.c (check_ic_target): New function.
(gimple_ic_transform): Sanity check indirect call target.
* gimple-low.c (gimple_check_call_args): Interface change.
(gimple_check_call_matching_types): New function.
* tree-inline.c (tree_can_inline_p): Call new function.
2011-04-11 Basile Starynkevitch <basile@starynkevitch.net>

View File

@ -208,20 +208,20 @@ struct gimple_opt_pass pass_lower_cf =
};
/* Verify if the type of the argument matches that of the function
declaration. If we cannot verify this or there is a mismatch,
return false. */
bool
gimple_check_call_args (gimple stmt)
static bool
gimple_check_call_args (gimple stmt, tree fndecl)
{
tree fndecl, parms, p;
tree parms, p;
unsigned int i, nargs;
nargs = gimple_call_num_args (stmt);
/* Get argument types for verification. */
fndecl = gimple_call_fndecl (stmt);
if (fndecl)
parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
else
@ -272,6 +272,25 @@ gimple_check_call_args (gimple stmt)
return true;
}
/* Verify if the type of the argument and lhs of CALL_STMT matches
that of the function declaration CALLEE.
If we cannot verify this or there is a mismatch, return false. */
bool
gimple_check_call_matching_types (gimple call_stmt, tree callee)
{
tree lhs;
if ((DECL_RESULT (callee)
&& !DECL_BY_REFERENCE (DECL_RESULT (callee))
&& (lhs = gimple_call_lhs (call_stmt)) != NULL_TREE
&& !useless_type_conversion_p (TREE_TYPE (DECL_RESULT (callee)),
TREE_TYPE (lhs))
&& !fold_convertible_p (TREE_TYPE (DECL_RESULT (callee)), lhs))
|| !gimple_check_call_args (call_stmt, callee))
return false;
return true;
}
/* Lower sequence SEQ. Unlike gimplification the statements are not relowered
when they are changed -- if this has to be done, the lowering routine must

View File

@ -515,7 +515,7 @@ extern void record_vars_into (tree, tree);
extern void record_vars (tree);
extern bool gimple_seq_may_fallthru (gimple_seq);
extern bool gimple_stmt_may_fallthru (gimple);
extern bool gimple_check_call_args (gimple);
extern bool gimple_check_call_matching_types (gimple, tree);
/* In tree-ssa.c */

View File

@ -5326,7 +5326,7 @@ tree_can_inline_p (struct cgraph_edge *e)
return false;
}
#endif
tree caller, callee, lhs;
tree caller, callee;
caller = e->caller->decl;
callee = e->callee->decl;
@ -5353,13 +5353,7 @@ tree_can_inline_p (struct cgraph_edge *e)
/* Do not inline calls where we cannot triviall work around mismatches
in argument or return types. */
if (e->call_stmt
&& ((DECL_RESULT (callee)
&& !DECL_BY_REFERENCE (DECL_RESULT (callee))
&& (lhs = gimple_call_lhs (e->call_stmt)) != NULL_TREE
&& !useless_type_conversion_p (TREE_TYPE (DECL_RESULT (callee)),
TREE_TYPE (lhs))
&& !fold_convertible_p (TREE_TYPE (DECL_RESULT (callee)), lhs))
|| !gimple_check_call_args (e->call_stmt)))
&& !gimple_check_call_matching_types (e->call_stmt, callee))
{
e->inline_failed = CIF_MISMATCHED_ARGUMENTS;
if (e->call_stmt)

View File

@ -1090,6 +1090,25 @@ find_func_by_pid (int pid)
return pid_map [pid];
}
/* Perform sanity check on the indirect call target. Due to race conditions,
false function target may be attributed to an indirect call site. If the
call expression type mismatches with the target function's type, expand_call
may ICE. Here we only do very minimal sanity check just to make compiler happy.
Returns true if TARGET is considered ok for call CALL_STMT. */
static bool
check_ic_target (gimple call_stmt, struct cgraph_node *target)
{
location_t locus;
if (gimple_check_call_matching_types (call_stmt, target->decl))
return true;
locus = gimple_location (call_stmt);
inform (locus, "Skipping target %s with mismatching types for icall ",
cgraph_node_name (target));
return false;
}
/* Do transformation
if (actual_callee_address == address_of_most_common_function/method)
@ -1268,6 +1287,9 @@ gimple_ic_transform (gimple stmt)
if (direct_call == NULL)
return false;
if (!check_ic_target (stmt, direct_call))
return false;
modify = gimple_ic (stmt, direct_call, prob, count, all);
if (dump_file)
@ -1748,4 +1770,3 @@ gimple_find_values_to_profile (histogram_values *values)
}
}
}