Commit 73136074 by Martin Jambor Committed by Martin Jambor

Remove gimple_call_types_likely_match_p (PR 70929)

2019-11-07  Martin Jambor  <mjambor@suse.cz>

	PR lto/70929
	* cif-code.def (MISMATCHED_ARGUMENTS): Removed.
	* cgraph.h (gimple_check_call_matching_types): Remove
	* cgraph.c (gimple_check_call_args): Likewise.
	(gimple_check_call_matching_types): Likewise.
	(symbol_table::create_edge): Do not call
	gimple_check_call_matching_types.
	(cgraph_edge::make_direct): Likewise.
	(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
	* value-prof.h (check_ic_target): Remove.
	* value-prof.c (check_ic_target): Remove.
	(gimple_ic_transform): Do nat call check_ic_target.
	* auto-profile.c (function_instance::find_icall_target_map): Likewise.
	(afdo_indirect_call): Likewise.
	* ipa-prop.c (update_indirect_edges_after_inlining): Do not call
	gimple_check_call_matching_types.
	* ipa-inline.c (early_inliner): Likewise.

	testsuite/
	* g++.dg/lto/pr70929_[01].C: New test.
	* gcc.dg/winline-10.c: Adjust for the fact that inlining happens.

From-SVN: r277920
parent 0775830a
2019-11-07 Martin Jambor <mjambor@suse.cz>
PR lto/70929
* cif-code.def (MISMATCHED_ARGUMENTS): Removed.
* cgraph.h (gimple_check_call_matching_types): Remove
* cgraph.c (gimple_check_call_args): Likewise.
(gimple_check_call_matching_types): Likewise.
(symbol_table::create_edge): Do not call
gimple_check_call_matching_types.
(cgraph_edge::make_direct): Likewise.
(cgraph_edge::redirect_call_stmt_to_callee): Likewise.
* value-prof.h (check_ic_target): Remove.
* value-prof.c (check_ic_target): Remove.
(gimple_ic_transform): Do nat call check_ic_target.
* auto-profile.c (function_instance::find_icall_target_map): Likewise.
(afdo_indirect_call): Likewise.
* ipa-prop.c (update_indirect_edges_after_inlining): Do not call
gimple_check_call_matching_types.
* ipa-inline.c (early_inliner): Likewise.
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* config/arm/arm.md (arm_<simd32_op>): New define_expand. * config/arm/arm.md (arm_<simd32_op>): New define_expand.
...@@ -606,8 +606,6 @@ function_instance::find_icall_target_map (gcall *stmt, ...@@ -606,8 +606,6 @@ function_instance::find_icall_target_map (gcall *stmt,
get_identifier (afdo_string_table->get_name (callee))); get_identifier (afdo_string_table->get_name (callee)));
if (node == NULL) if (node == NULL)
continue; continue;
if (!check_ic_target (stmt, node))
continue;
(*map)[callee] = iter->second->total_count (); (*map)[callee] = iter->second->total_count ();
ret += iter->second->total_count (); ret += iter->second->total_count ();
} }
...@@ -1034,7 +1032,7 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map, ...@@ -1034,7 +1032,7 @@ afdo_indirect_call (gimple_stmt_iterator *gsi, const icall_target_map &map,
print_generic_expr (dump_file, direct_call->decl, TDF_SLIM); print_generic_expr (dump_file, direct_call->decl, TDF_SLIM);
} }
if (direct_call == NULL || !check_ic_target (stmt, direct_call)) if (direct_call == NULL)
{ {
if (dump_file) if (dump_file)
fprintf (dump_file, " not transforming\n"); fprintf (dump_file, " not transforming\n");
......
...@@ -881,19 +881,8 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee, ...@@ -881,19 +881,8 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
edge->can_throw_external edge->can_throw_external
= call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl), = call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl),
call_stmt) : false; call_stmt) : false;
if (call_stmt edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
&& callee && callee->decl edge->call_stmt_cannot_inline_p = false;
&& !gimple_check_call_matching_types (call_stmt, callee->decl,
false))
{
edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
edge->call_stmt_cannot_inline_p = true;
}
else
{
edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
edge->call_stmt_cannot_inline_p = false;
}
if (opt_for_fn (edge->caller->decl, flag_devirtualize) if (opt_for_fn (edge->caller->decl, flag_devirtualize)
&& call_stmt && DECL_STRUCT_FUNCTION (caller->decl)) && call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
...@@ -1255,13 +1244,6 @@ cgraph_edge::make_direct (cgraph_node *callee) ...@@ -1255,13 +1244,6 @@ cgraph_edge::make_direct (cgraph_node *callee)
/* Insert to callers list of the new callee. */ /* Insert to callers list of the new callee. */
edge->set_callee (callee); edge->set_callee (callee);
if (call_stmt
&& !gimple_check_call_matching_types (call_stmt, callee->decl, false))
{
call_stmt_cannot_inline_p = true;
inline_failed = CIF_MISMATCHED_ARGUMENTS;
}
/* We need to re-determine the inlining status of the edge. */ /* We need to re-determine the inlining status of the edge. */
initialize_inline_failed (edge); initialize_inline_failed (edge);
return edge; return edge;
...@@ -1290,28 +1272,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void) ...@@ -1290,28 +1272,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
substitution), forget about speculating. */ substitution), forget about speculating. */
if (decl) if (decl)
e = e->resolve_speculation (decl); e = e->resolve_speculation (decl);
/* If types do not match, speculation was likely wrong.
The direct edge was possibly redirected to the clone with a different
signature. We did not update the call statement yet, so compare it
with the reference that still points to the proper type. */
else if (!gimple_check_call_matching_types (e->call_stmt,
ref->referred->decl,
true))
{
if (dump_file)
fprintf (dump_file, "Not expanding speculative call of %s -> %s\n"
"Type mismatch.\n",
e->caller->dump_name (),
e->callee->dump_name ());
e = e->resolve_speculation ();
/* We are producing the final function body and will throw away the
callgraph edges really soon. Reset the counts/frequencies to
keep verifier happy in the case of roundoff errors. */
e->count = gimple_bb (e->call_stmt)->count;
}
/* Expand speculation into GIMPLE code. */
else else
{ {
/* Expand speculation into GIMPLE code. */
if (dump_file) if (dump_file)
{ {
fprintf (dump_file, fprintf (dump_file,
...@@ -3638,102 +3601,6 @@ cgraph_node::get_fun () const ...@@ -3638,102 +3601,6 @@ cgraph_node::get_fun () const
return fun; return fun;
} }
/* 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. */
static bool
gimple_check_call_args (gimple *stmt, tree fndecl, bool args_count_match)
{
tree parms, p;
unsigned int i, nargs;
/* Calls to internal functions always match their signature. */
if (gimple_call_internal_p (stmt))
return true;
nargs = gimple_call_num_args (stmt);
/* Get argument types for verification. */
if (fndecl)
parms = TYPE_ARG_TYPES (TREE_TYPE (fndecl));
else
parms = TYPE_ARG_TYPES (gimple_call_fntype (stmt));
/* 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. */
if (fndecl && DECL_ARGUMENTS (fndecl))
{
for (i = 0, p = DECL_ARGUMENTS (fndecl);
i < nargs;
i++, p = DECL_CHAIN (p))
{
tree arg;
/* We cannot distinguish a varargs function from the case
of excess parameters, still deferring the inlining decision
to the callee is possible. */
if (!p)
break;
arg = gimple_call_arg (stmt, i);
if (p == error_mark_node
|| DECL_ARG_TYPE (p) == error_mark_node
|| arg == error_mark_node
|| (!types_compatible_p (DECL_ARG_TYPE (p), TREE_TYPE (arg))
&& !fold_convertible_p (DECL_ARG_TYPE (p), arg)))
return false;
}
if (args_count_match && p)
return false;
}
else if (parms)
{
for (i = 0, p = parms; i < nargs; i++, p = TREE_CHAIN (p))
{
tree arg;
/* If this is a varargs function defer inlining decision
to callee. */
if (!p)
break;
arg = gimple_call_arg (stmt, i);
if (TREE_VALUE (p) == error_mark_node
|| arg == error_mark_node
|| TREE_CODE (TREE_VALUE (p)) == VOID_TYPE
|| (!types_compatible_p (TREE_VALUE (p), TREE_TYPE (arg))
&& !fold_convertible_p (TREE_VALUE (p), arg)))
return false;
}
}
else
{
if (nargs != 0)
return false;
}
return true;
}
/* Verify if the type of the argument and lhs of CALL_STMT matches
that of the function declaration CALLEE. If ARGS_COUNT_MATCH is
true, the arg count needs to be the same.
If we cannot verify this or there is a mismatch, return false. */
bool
gimple_check_call_matching_types (gimple *call_stmt, tree callee,
bool args_count_match)
{
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, args_count_match))
return false;
return true;
}
/* Reset all state within cgraph.c so that we can rerun the compiler /* Reset all state within cgraph.c so that we can rerun the compiler
within the same process. For use by toplev::finalize. */ within the same process. For use by toplev::finalize. */
......
...@@ -2445,8 +2445,6 @@ bool cgraph_function_possibly_inlined_p (tree); ...@@ -2445,8 +2445,6 @@ bool cgraph_function_possibly_inlined_p (tree);
const char* cgraph_inline_failed_string (cgraph_inline_failed_t); const char* cgraph_inline_failed_string (cgraph_inline_failed_t);
cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t); cgraph_inline_failed_type_t cgraph_inline_failed_type (cgraph_inline_failed_t);
extern bool gimple_check_call_matching_types (gimple *, tree, bool);
/* In cgraphunit.c */ /* In cgraphunit.c */
void cgraphunit_c_finalize (void); void cgraphunit_c_finalize (void);
......
...@@ -96,10 +96,6 @@ DEFCIFCODE(NOT_DECLARED_INLINED, CIF_FINAL_NORMAL, ...@@ -96,10 +96,6 @@ DEFCIFCODE(NOT_DECLARED_INLINED, CIF_FINAL_NORMAL,
N_("function not declared inline and code size would grow")) N_("function not declared inline and code size would grow"))
/* Caller and callee disagree on the arguments. */ /* Caller and callee disagree on the arguments. */
DEFCIFCODE(MISMATCHED_ARGUMENTS, CIF_FINAL_ERROR,
N_("mismatched arguments"))
/* Caller and callee disagree on the arguments. */
DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR, DEFCIFCODE(LTO_MISMATCHED_DECLARATIONS, CIF_FINAL_ERROR,
N_("mismatched declarations during linktime optimization")) N_("mismatched declarations during linktime optimization"))
......
...@@ -2913,14 +2913,6 @@ early_inliner (function *fun) ...@@ -2913,14 +2913,6 @@ early_inliner (function *fun)
= estimate_num_insns (edge->call_stmt, &eni_size_weights); = estimate_num_insns (edge->call_stmt, &eni_size_weights);
es->call_stmt_time es->call_stmt_time
= estimate_num_insns (edge->call_stmt, &eni_time_weights); = estimate_num_insns (edge->call_stmt, &eni_time_weights);
if (edge->callee->decl
&& !gimple_check_call_matching_types (
edge->call_stmt, edge->callee->decl, false))
{
edge->inline_failed = CIF_MISMATCHED_ARGUMENTS;
edge->call_stmt_cannot_inline_p = true;
}
} }
if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1) if (iterations < PARAM_VALUE (PARAM_EARLY_INLINER_MAX_ITERATIONS) - 1)
ipa_update_overall_fn_summary (node); ipa_update_overall_fn_summary (node);
......
...@@ -3492,11 +3492,6 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs, ...@@ -3492,11 +3492,6 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
else if (new_direct_edge) else if (new_direct_edge)
{ {
new_direct_edge->indirect_inlining_edge = 1; new_direct_edge->indirect_inlining_edge = 1;
if (new_direct_edge->call_stmt)
new_direct_edge->call_stmt_cannot_inline_p
= !gimple_check_call_matching_types (
new_direct_edge->call_stmt,
new_direct_edge->callee->decl, false);
if (new_edges) if (new_edges)
{ {
new_edges->safe_push (new_direct_edge); new_edges->safe_push (new_direct_edge);
......
2019-11-07 Martin Jambor <mjambor@suse.cz>
PR lto/70929
* g++.dg/lto/pr70929_[01].C: New test.
* gcc.dg/winline-10.c: Adjust for the fact that inlining happens.
2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com> 2019-11-07 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/arm/acle/simd32.c: Update test. * gcc.target/arm/acle/simd32.c: Update test.
......
// { dg-lto-do run }
// { dg-lto-options { "-O3 -flto" } }
struct s
{
int a;
s() {a=1;}
~s() {}
};
int t(struct s s);
int main()
{
s s;
int v=t(s);
if (!__builtin_constant_p (v))
__builtin_abort ();
return 0;
}
struct s
{
int a;
s() {a=1;}
~s() {}
};
int t(struct s s)
{
return s.a;
}
/* { dg-do compile } */ /* { dg-do compile } */
/* { dg-options "-O2 -Winline" } */ /* { dg-options "-O2 -Winline -fopt-info-optimized-inline=stderr" } */
struct s { int a; }; struct s { int a; };
inline void f (x) /* { dg-warning "inlining .* mismatched arg" } */ inline void f (x)
int x; int x;
{ {
asm (""); asm ("");
...@@ -11,7 +11,7 @@ inline void f (x) /* { dg-warning "inlining .* mismatched arg" } */ ...@@ -11,7 +11,7 @@ inline void f (x) /* { dg-warning "inlining .* mismatched arg" } */
void g (struct s x) void g (struct s x)
{ {
f (x); /* { dg-message "called from here" } */ f (x); /* { dg-optimized "Inlining f.* into g" } */
} }
void f (int x); /* { dg-warning "follows non-prototype definition" } */ void f (int x); /* { dg-warning "follows non-prototype definition" } */
...@@ -1245,25 +1245,6 @@ find_func_by_profile_id (int profile_id) ...@@ -1245,25 +1245,6 @@ find_func_by_profile_id (int profile_id)
return NULL; return NULL;
} }
/* 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. */
bool
check_ic_target (gcall *call_stmt, struct cgraph_node *target)
{
if (gimple_check_call_matching_types (call_stmt, target->decl, true))
return true;
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, call_stmt,
"Skipping target %s with mismatching types for icall\n",
target->name ());
return false;
}
/* Do transformation /* Do transformation
if (actual_callee_address == address_of_most_common_function/method) if (actual_callee_address == address_of_most_common_function/method)
...@@ -1456,17 +1437,6 @@ gimple_ic_transform (gimple_stmt_iterator *gsi) ...@@ -1456,17 +1437,6 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
return false; return false;
} }
if (!check_ic_target (stmt, direct_call))
{
if (dump_enabled_p ())
dump_printf_loc (MSG_MISSED_OPTIMIZATION, stmt,
"Indirect call -> direct call %T => %T "
"transformation skipped because of type mismatch: %G",
gimple_call_fn (stmt), direct_call->decl, stmt);
gimple_remove_histogram_value (cfun, stmt, histogram);
return false;
}
if (dump_enabled_p ()) if (dump_enabled_p ())
{ {
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt, dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment