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
This commit is contained in:
Martin Jambor 2019-11-07 11:55:43 +01:00 committed by Martin Jambor
parent 0775830a79
commit 7313607478
12 changed files with 61 additions and 191 deletions

View file

@ -1,3 +1,23 @@
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>
* config/arm/arm.md (arm_<simd32_op>): New define_expand.

View file

@ -606,8 +606,6 @@ function_instance::find_icall_target_map (gcall *stmt,
get_identifier (afdo_string_table->get_name (callee)));
if (node == NULL)
continue;
if (!check_ic_target (stmt, node))
continue;
(*map)[callee] = 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,
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)
fprintf (dump_file, " not transforming\n");

View file

@ -881,19 +881,8 @@ symbol_table::create_edge (cgraph_node *caller, cgraph_node *callee,
edge->can_throw_external
= call_stmt ? stmt_can_throw_external (DECL_STRUCT_FUNCTION (caller->decl),
call_stmt) : false;
if (call_stmt
&& callee && callee->decl
&& !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;
}
edge->inline_failed = CIF_FUNCTION_NOT_CONSIDERED;
edge->call_stmt_cannot_inline_p = false;
if (opt_for_fn (edge->caller->decl, flag_devirtualize)
&& call_stmt && DECL_STRUCT_FUNCTION (caller->decl))
@ -1255,13 +1244,6 @@ cgraph_edge::make_direct (cgraph_node *callee)
/* Insert to callers list of the new 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. */
initialize_inline_failed (edge);
return edge;
@ -1290,28 +1272,9 @@ cgraph_edge::redirect_call_stmt_to_callee (void)
substitution), forget about speculating. */
if (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
{
/* Expand speculation into GIMPLE code. */
if (dump_file)
{
fprintf (dump_file,
@ -3638,102 +3601,6 @@ cgraph_node::get_fun () const
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
within the same process. For use by toplev::finalize. */

View file

@ -2445,8 +2445,6 @@ bool cgraph_function_possibly_inlined_p (tree);
const char* cgraph_inline_failed_string (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 */
void cgraphunit_c_finalize (void);

View file

@ -95,10 +95,6 @@ DEFCIFCODE(NEVER_CALL, CIF_FINAL_NORMAL,
DEFCIFCODE(NOT_DECLARED_INLINED, CIF_FINAL_NORMAL,
N_("function not declared inline and code size would grow"))
/* 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,
N_("mismatched declarations during linktime optimization"))

View file

@ -2913,14 +2913,6 @@ early_inliner (function *fun)
= estimate_num_insns (edge->call_stmt, &eni_size_weights);
es->call_stmt_time
= 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)
ipa_update_overall_fn_summary (node);

View file

@ -3492,11 +3492,6 @@ update_indirect_edges_after_inlining (struct cgraph_edge *cs,
else if (new_direct_edge)
{
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)
{
new_edges->safe_push (new_direct_edge);

View file

@ -1,3 +1,9 @@
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>
* gcc.target/arm/acle/simd32.c: Update test.

View file

@ -0,0 +1,18 @@
// { 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;
}

View file

@ -0,0 +1,10 @@
struct s
{
int a;
s() {a=1;}
~s() {}
};
int t(struct s s)
{
return s.a;
}

View file

@ -1,9 +1,9 @@
/* { dg-do compile } */
/* { dg-options "-O2 -Winline" } */
/* { dg-options "-O2 -Winline -fopt-info-optimized-inline=stderr" } */
struct s { int a; };
inline void f (x) /* { dg-warning "inlining .* mismatched arg" } */
inline void f (x)
int x;
{
asm ("");
@ -11,7 +11,7 @@ inline void f (x) /* { dg-warning "inlining .* mismatched arg" } */
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" } */

View file

@ -1245,25 +1245,6 @@ find_func_by_profile_id (int profile_id)
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
if (actual_callee_address == address_of_most_common_function/method)
@ -1456,17 +1437,6 @@ gimple_ic_transform (gimple_stmt_iterator *gsi)
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 ())
{
dump_printf_loc (MSG_OPTIMIZED_LOCATIONS, stmt,