@@ -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");
@@ -878,19 +878,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))
@@ -1252,13 +1241,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;
@@ -1287,28 +1269,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,
@@ -3635,102 +3598,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);
new file mode 100644
@@ -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;
+}
new file mode 100644
@@ -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,