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:
parent
0775830a79
commit
7313607478
12 changed files with 61 additions and 191 deletions
|
@ -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.
|
||||
|
|
|
@ -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");
|
||||
|
|
139
gcc/cgraph.c
139
gcc/cgraph.c
|
@ -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. */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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"))
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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.
|
||||
|
|
18
gcc/testsuite/g++.dg/lto/pr70929_0.C
Normal file
18
gcc/testsuite/g++.dg/lto/pr70929_0.C
Normal 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;
|
||||
}
|
10
gcc/testsuite/g++.dg/lto/pr70929_1.C
Normal file
10
gcc/testsuite/g++.dg/lto/pr70929_1.C
Normal file
|
@ -0,0 +1,10 @@
|
|||
struct s
|
||||
{
|
||||
int a;
|
||||
s() {a=1;}
|
||||
~s() {}
|
||||
};
|
||||
int t(struct s s)
|
||||
{
|
||||
return s.a;
|
||||
}
|
|
@ -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" } */
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Add table
Reference in a new issue