/* Driver of optimization process
- Copyright (C) 2003-2014 Free Software Foundation, Inc.
+ Copyright (C) 2003-2015 Free Software Foundation, Inc.
Contributed by Jan Hubicka
This file is part of GCC.
#include "system.h"
#include "coretypes.h"
#include "tm.h"
+#include "alias.h"
+#include "symtab.h"
#include "tree.h"
+#include "fold-const.h"
#include "varasm.h"
#include "stor-layout.h"
#include "stringpool.h"
#include "output.h"
#include "rtl.h"
#include "predict.h"
-#include "vec.h"
-#include "hashtab.h"
-#include "hash-set.h"
-#include "machmode.h"
#include "hard-reg-set.h"
-#include "input.h"
#include "function.h"
#include "basic-block.h"
+#include "dominance.h"
+#include "cfgcleanup.h"
+#include "cfg.h"
#include "tree-ssa-alias.h"
#include "internal-fn.h"
#include "gimple-fold.h"
#include "gimple-expr.h"
-#include "is-a.h"
#include "gimple.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "diagnostic.h"
#include "params.h"
#include "intl.h"
-#include "hash-map.h"
-#include "plugin-api.h"
-#include "ipa-ref.h"
#include "cgraph.h"
#include "alloc-pool.h"
+#include "symbol-summary.h"
#include "ipa-prop.h"
#include "tree-iterator.h"
#include "tree-pass.h"
#include "tree-chkp.h"
#include "lto-section-names.h"
#include "omp-low.h"
+#include "print-tree.h"
/* Queue of cgraph nodes scheduled to be added into cgraph. This is a
secondary queue used during optimization to accommodate passes that
if (forced_by_abi && TREE_PUBLIC (decl))
return true;
- /* Keep constructors, destructors and virtual functions. */
+ /* Keep constructors, destructors and virtual functions. */
if (TREE_CODE (decl) == FUNCTION_DECL
&& (DECL_STATIC_CONSTRUCTOR (decl) || DECL_STATIC_DESTRUCTOR (decl)))
return true;
case IPA:
case IPA_SSA:
+ case IPA_SSA_AFTER_INLINING:
/* When IPA optimization already started, do all essential
transformations that has been already performed on the whole
cgraph but not on this function. */
if (!node->analyzed)
node->analyze ();
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
- if (state == IPA_SSA
+ if ((state == IPA_SSA || state == IPA_SSA_AFTER_INLINING)
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
g->get_passes ()->execute_early_local_passes ();
- else if (inline_summary_vec != NULL)
+ else if (inline_summaries != NULL)
compute_inline_parameters (node, true);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
remove_all_references ();
}
-/* Return true when there are references to the node. */
+/* Return true when there are references to the node. INCLUDE_SELF is
+ true if a self reference counts as a reference. */
bool
-symtab_node::referred_to_p (void)
+symtab_node::referred_to_p (bool include_self)
{
ipa_ref *ref = NULL;
/* For functions check also calls. */
cgraph_node *cn = dyn_cast <cgraph_node *> (this);
if (cn && cn->callers)
- return true;
+ {
+ if (include_self)
+ return true;
+ for (cgraph_edge *e = cn->callers; e; e = e->next_caller)
+ if (e->caller != this)
+ return true;
+ }
return false;
}
node->local.redefined_extern_inline = true;
}
- notice_global_symbol (decl);
+ /* Set definition first before calling notice_global_symbol so that
+ it is available to notice_global_symbol. */
node->definition = true;
+ notice_global_symbol (decl);
node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
/* With -fkeep-inline-functions we are keeping all inline functions except
if (!TREE_ASM_WRITTEN (decl))
(*debug_hooks->deferred_inline_function) (decl);
- /* Possibly warn about unused parameters. */
- if (warn_unused_parameter)
- do_warn_unused_parameter (decl);
-
if (!no_collect)
ggc_collect ();
{
gcc::pass_manager *passes = g->get_passes ();
cgraph_node *node;
+
+ if (dump_file)
+ {
+ struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
+ const char *function_type = ((gimple_has_body_p (fndecl))
+ ? (lowered
+ ? (gimple_in_ssa_p (fn)
+ ? "ssa gimple"
+ : "low gimple")
+ : "high gimple")
+ : "to-be-gimplified");
+ fprintf (dump_file,
+ "Added new %s function %s to callgraph\n",
+ function_type,
+ fndecl_name (fndecl));
+ }
+
switch (symtab->state)
{
case PARSING:
case IPA:
case IPA_SSA:
+ case IPA_SSA_AFTER_INLINING:
case EXPANSION:
/* Bring the function into finalized state and enqueue for later
analyzing and compilation. */
if (thunk.thunk_p)
{
- create_edge (cgraph_node::get (thunk.alias),
- NULL, 0, CGRAPH_FREQ_BASE);
+ cgraph_node *t = cgraph_node::get (thunk.alias);
+
+ create_edge (t, NULL, 0, CGRAPH_FREQ_BASE);
+ /* Target code in expand_thunk may need the thunk's target
+ to be analyzed, so recurse here. */
+ if (!t->analyzed)
+ t->analyze ();
+ if (t->alias)
+ {
+ t = t->get_alias_target ();
+ if (!t->analyzed)
+ t->analyze ();
+ }
if (!expand_thunk (false, false))
{
thunk.alias = NULL;
body. */
if (!gimple_has_body_p (decl))
gimplify_function_tree (decl);
- dump_function (TDI_generic, decl);
/* Lower the function. */
if (!lowered)
if (node->definition)
return;
- notice_global_symbol (decl);
+ /* Set definition first before calling notice_global_symbol so that
+ it is available to notice_global_symbol. */
node->definition = true;
+ notice_global_symbol (decl);
if (TREE_THIS_VOLATILE (decl) || DECL_PRESERVE_P (decl)
/* Traditionally we do not eliminate static variables when not
optimizing and when not doing toplevel reoder. */
(TREE_TYPE (targets[i]->decl))
== METHOD_TYPE
&& !type_in_anonymous_namespace_p
- (method_class_type
- (TREE_TYPE (targets[i]->decl))))
- enqueue_node (targets[i]);
+ (TYPE_METHOD_BASETYPE (TREE_TYPE (targets[i]->decl))))
+ enqueue_node (targets[i]);
}
}
static cgraph_node *first_analyzed;
static varpool_node *first_analyzed_var;
+/* FIRST_TIME is set to TRUE for the first time we are called for a
+ translation unit from finalize_compilation_unit() or false
+ otherwise. */
+
static void
-analyze_functions (void)
+analyze_functions (bool first_time)
{
/* Keep track of already processed nodes when called multiple times for
intermodule optimization. */
cnode->analyze ();
for (edge = cnode->callees; edge; edge = edge->next_callee)
- if (edge->callee->definition)
+ if (edge->callee->definition
+ && (!DECL_EXTERNAL (edge->callee->decl)
+ /* When not optimizing, do not try to analyze extern
+ inline functions. Doing so is pointless. */
+ || opt_for_fn (edge->callee->decl, optimize)
+ /* Weakrefs needs to be preserved. */
+ || edge->callee->alias
+ /* always_inline functions are inlined aven at -O0. */
+ || lookup_attribute
+ ("always_inline",
+ DECL_ATTRIBUTES (edge->callee->decl))
+ /* Multiversioned functions needs the dispatcher to
+ be produced locally even for extern functions. */
+ || edge->callee->function_version ()))
enqueue_node (edge->callee);
if (opt_for_fn (cnode->decl, optimize)
&& opt_for_fn (cnode->decl, flag_devirtualize))
for (next = node->same_comdat_group;
next != node;
next = next->same_comdat_group)
- enqueue_node (next);
+ if (!next->comdat_local_p ())
+ enqueue_node (next);
}
for (i = 0; node->iterate_reference (i, ref); i++)
- if (ref->referred->definition)
+ if (ref->referred->definition
+ && (!DECL_EXTERNAL (ref->referred->decl)
+ || ((TREE_CODE (ref->referred->decl) != FUNCTION_DECL
+ && optimize)
+ || (TREE_CODE (ref->referred->decl) == FUNCTION_DECL
+ && opt_for_fn (ref->referred->decl, optimize))
+ || node->alias
+ || ref->referred->alias)))
enqueue_node (ref->referred);
symtab->process_new_functions ();
}
symtab_node::dump_table (symtab->dump_file);
}
+ if (first_time)
+ {
+ symtab_node *snode;
+ FOR_EACH_SYMBOL (snode)
+ check_global_declaration (snode->decl);
+ }
+
if (symtab->dump_file)
fprintf (symtab->dump_file, "\nRemoving unused symbols:");
{
if (symtab->dump_file)
fprintf (symtab->dump_file, " %s", node->name ());
+
+ /* See if the debugger can use anything before the DECL
+ passes away. Perhaps it can notice a DECL that is now a
+ constant and can tag the early DIE with an appropriate
+ attribute.
+
+ Otherwise, this is the last chance the debug_hooks have
+ at looking at optimized away DECLs, since
+ late_global_decl will subsequently be called from the
+ contents of the now pruned symbol table. */
+ if (!decl_function_context (node->decl))
+ (*debug_hooks->late_global_decl) (node->decl);
+
node->remove ();
continue;
}
return basic block in the function body. */
basic_block
-init_lowered_empty_function (tree decl, bool in_ssa)
+init_lowered_empty_function (tree decl, bool in_ssa, gcov_type count)
{
basic_block bb;
+ edge e;
current_function_decl = decl;
allocate_struct_function (decl, false);
loops_for_fn (cfun)->state |= LOOPS_MAY_HAVE_MULTIPLE_LATCHES;
/* Create BB for body of the function and connect it properly. */
- bb = create_basic_block (NULL, (void *) 0, ENTRY_BLOCK_PTR_FOR_FN (cfun));
- make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
- make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+ ENTRY_BLOCK_PTR_FOR_FN (cfun)->count = count;
+ ENTRY_BLOCK_PTR_FOR_FN (cfun)->frequency = REG_BR_PROB_BASE;
+ EXIT_BLOCK_PTR_FOR_FN (cfun)->count = count;
+ EXIT_BLOCK_PTR_FOR_FN (cfun)->frequency = REG_BR_PROB_BASE;
+ bb = create_basic_block (NULL, ENTRY_BLOCK_PTR_FOR_FN (cfun));
+ bb->count = count;
+ bb->frequency = BB_FREQ_MAX;
+ e = make_edge (ENTRY_BLOCK_PTR_FOR_FN (cfun), bb, EDGE_FALLTHRU);
+ e->count = count;
+ e->probability = REG_BR_PROB_BASE;
+ e = make_edge (bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+ e->count = count;
+ e->probability = REG_BR_PROB_BASE;
add_bb_to_loop (bb, ENTRY_BLOCK_PTR_FOR_FN (cfun)->loop_father);
return bb;
tree thunk_fndecl = decl;
tree a;
+ /* Instrumentation thunk is the same function with
+ a different signature. Never need to expand it. */
+ if (thunk.add_pointer_bounds_args)
+ return false;
if (!force_gimple_thunk && this_adjusting
&& targetm.asm_out.can_output_mi_thunk (thunk_fndecl, fixed_offset,
current_function_decl = thunk_fndecl;
/* Ensure thunks are emitted in their correct sections. */
- resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
+ resolve_unique_section (thunk_fndecl, 0,
+ flag_function_sections);
DECL_RESULT (thunk_fndecl)
= build_decl (DECL_SOURCE_LOCATION (thunk_fndecl),
thunk.thunk_p = false;
analyzed = false;
}
+ else if (stdarg_p (TREE_TYPE (thunk_fndecl)))
+ {
+ error ("generic thunk code fails for method %qD which uses %<...%>",
+ thunk_fndecl);
+ TREE_ASM_WRITTEN (thunk_fndecl) = 1;
+ analyzed = true;
+ return false;
+ }
else
{
tree restype;
int i;
tree resdecl;
tree restmp = NULL;
+ tree resbnd = NULL;
gcall *call;
greturn *ret;
+ bool alias_is_noreturn = TREE_THIS_VOLATILE (alias);
if (in_lto_p)
get_untransformed_body ();
current_function_decl = thunk_fndecl;
/* Ensure thunks are emitted in their correct sections. */
- resolve_unique_section (thunk_fndecl, 0, flag_function_sections);
+ resolve_unique_section (thunk_fndecl, 0,
+ flag_function_sections);
DECL_IGNORED_P (thunk_fndecl) = 1;
bitmap_obstack_initialize (NULL);
else
resdecl = DECL_RESULT (thunk_fndecl);
- bb = then_bb = else_bb = return_bb = init_lowered_empty_function (thunk_fndecl, true);
+ bb = then_bb = else_bb = return_bb
+ = init_lowered_empty_function (thunk_fndecl, true, count);
bsi = gsi_start_bb (bb);
/* Build call to the function being thunked. */
- if (!VOID_TYPE_P (restype))
+ if (!VOID_TYPE_P (restype) && !alias_is_noreturn)
{
if (DECL_BY_REFERENCE (resdecl))
{
}
else if (!is_gimple_reg_type (restype))
{
- restmp = resdecl;
+ if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl)))
+ {
+ restmp = resdecl;
- if (TREE_CODE (restmp) == VAR_DECL)
- add_local_decl (cfun, restmp);
- BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
+ if (TREE_CODE (restmp) == VAR_DECL)
+ add_local_decl (cfun, restmp);
+ BLOCK_VARS (DECL_INITIAL (current_function_decl)) = restmp;
+ }
+ else
+ restmp = create_tmp_var (restype, "retval");
}
else
restmp = create_tmp_reg (restype, "retval");
for (arg = a; arg; arg = DECL_CHAIN (arg))
nargs++;
auto_vec<tree> vargs (nargs);
+ i = 0;
+ arg = a;
if (this_adjusting)
- vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
- virtual_offset));
- else if (nargs)
- vargs.quick_push (a);
+ {
+ vargs.quick_push (thunk_adjust (&bsi, a, 1, fixed_offset,
+ virtual_offset));
+ arg = DECL_CHAIN (a);
+ i = 1;
+ }
if (nargs)
- for (i = 1, arg = DECL_CHAIN (a); i < nargs; i++, arg = DECL_CHAIN (arg))
+ for (; i < nargs; i++, arg = DECL_CHAIN (arg))
{
tree tmp = arg;
if (!is_gimple_val (arg))
callees->call_stmt = call;
gimple_call_set_from_thunk (call, true);
gimple_call_set_with_bounds (call, instrumentation_clone);
- if (restmp)
+
+ /* Return slot optimization is always possible and in fact requred to
+ return values with DECL_BY_REFERENCE. */
+ if (aggregate_value_p (resdecl, TREE_TYPE (thunk_fndecl))
+ && (!is_gimple_reg_type (TREE_TYPE (resdecl))
+ || DECL_BY_REFERENCE (resdecl)))
+ gimple_call_set_return_slot_opt (call, true);
+
+ if (restmp && !alias_is_noreturn)
{
gimple_call_set_lhs (call, restmp);
gcc_assert (useless_type_conversion_p (TREE_TYPE (restmp),
TREE_TYPE (TREE_TYPE (alias))));
}
gsi_insert_after (&bsi, call, GSI_NEW_STMT);
- if (!(gimple_call_flags (call) & ECF_NORETURN))
+ if (!alias_is_noreturn)
{
+ if (instrumentation_clone
+ && !DECL_BY_REFERENCE (resdecl)
+ && restmp
+ && BOUNDED_P (restmp))
+ {
+ resbnd = chkp_insert_retbnd_call (NULL, restmp, &bsi);
+ create_edge (get_create (gimple_call_fndecl (gsi_stmt (bsi))),
+ as_a <gcall *> (gsi_stmt (bsi)),
+ callees->count, callees->frequency);
+ }
+
if (restmp && !this_adjusting
&& (fixed_offset || virtual_offset))
{
if (TREE_CODE (TREE_TYPE (restmp)) == POINTER_TYPE)
{
gimple stmt;
+ edge e;
/* If the return type is a pointer, we need to
protect against NULL. We know there will be an
adjustment, because that's why we're emitting a
thunk. */
- then_bb = create_basic_block (NULL, (void *) 0, bb);
- return_bb = create_basic_block (NULL, (void *) 0, then_bb);
- else_bb = create_basic_block (NULL, (void *) 0, else_bb);
+ then_bb = create_basic_block (NULL, bb);
+ then_bb->count = count - count / 16;
+ then_bb->frequency = BB_FREQ_MAX - BB_FREQ_MAX / 16;
+ return_bb = create_basic_block (NULL, then_bb);
+ return_bb->count = count;
+ return_bb->frequency = BB_FREQ_MAX;
+ else_bb = create_basic_block (NULL, else_bb);
+ then_bb->count = count / 16;
+ then_bb->frequency = BB_FREQ_MAX / 16;
add_bb_to_loop (then_bb, bb->loop_father);
add_bb_to_loop (return_bb, bb->loop_father);
add_bb_to_loop (else_bb, bb->loop_father);
build_zero_cst (TREE_TYPE (restmp)),
NULL_TREE, NULL_TREE);
gsi_insert_after (&bsi, stmt, GSI_NEW_STMT);
- make_edge (bb, then_bb, EDGE_TRUE_VALUE);
- make_edge (bb, else_bb, EDGE_FALSE_VALUE);
- make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
- make_edge (then_bb, return_bb, EDGE_FALLTHRU);
- make_edge (else_bb, return_bb, EDGE_FALLTHRU);
+ e = make_edge (bb, then_bb, EDGE_TRUE_VALUE);
+ e->probability = REG_BR_PROB_BASE - REG_BR_PROB_BASE / 16;
+ e->count = count - count / 16;
+ e = make_edge (bb, else_bb, EDGE_FALSE_VALUE);
+ e->probability = REG_BR_PROB_BASE / 16;
+ e->count = count / 16;
+ e = make_edge (return_bb, EXIT_BLOCK_PTR_FOR_FN (cfun), 0);
+ e->probability = REG_BR_PROB_BASE;
+ e->count = count;
+ e = make_edge (then_bb, return_bb, EDGE_FALLTHRU);
+ e->probability = REG_BR_PROB_BASE;
+ e->count = count - count / 16;
+ e = make_edge (else_bb, return_bb, EDGE_FALLTHRU);
+ e->probability = REG_BR_PROB_BASE;
+ e->count = count / 16;
bsi = gsi_last_bb (then_bb);
}
ret = gimple_build_return (restmp);
else
ret = gimple_build_return (resdecl);
+ gimple_return_set_retbnd (ret, resbnd);
gsi_insert_after (&bsi, ret, GSI_NEW_STMT);
}
}
cfun->gimple_df->in_ssa_p = true;
+ profile_status_for_fn (cfun)
+ = count ? PROFILE_READ : PROFILE_GUESSED;
/* FIXME: C++ FE should stop setting TREE_ASM_WRITTEN on thunks. */
TREE_ASM_WRITTEN (thunk_fndecl) = false;
delete_unreachable_blocks ();
if (node->process)
{
- expanded_func_count++;
- if(node->tp_first_run)
- profiled_func_count++;
-
- if (symtab->dump_file)
- fprintf (symtab->dump_file,
- "Time profile order in expand_all_functions:%s:%d\n",
- node->asm_name (), node->tp_first_run);
+ expanded_func_count++;
+ if(node->tp_first_run)
+ profiled_func_count++;
+
+ if (symtab->dump_file)
+ fprintf (symtab->dump_file,
+ "Time profile order in expand_all_functions:%s:%d\n",
+ node->asm_name (), node->tp_first_run);
node->process = 0;
node->expand ();
}
/* This extra symtab_remove_unreachable_nodes pass tends to catch some
devirtualization and other changes where removal iterate. */
- symtab->remove_unreachable_nodes (true, symtab->dump_file);
+ symtab->remove_unreachable_nodes (symtab->dump_file);
/* If pass_all_early_optimizations was not scheduled, the state of
the cgraph will not be properly updated. Update it now. */
}
/* Some targets need to handle LTO assembler output specially. */
- if (flag_generate_lto)
+ if (flag_generate_lto || flag_generate_offload)
targetm.asm_out.lto_start ();
if (!in_lto_p)
if (g->have_offload)
{
section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
- ipa_write_summaries (true);
+ lto_stream_offload_p = true;
+ ipa_write_summaries ();
+ lto_stream_offload_p = false;
}
if (flag_lto)
{
section_name_prefix = LTO_SECTION_NAME_PREFIX;
- ipa_write_summaries (false);
+ lto_stream_offload_p = false;
+ ipa_write_summaries ();
}
}
- if (flag_generate_lto)
+ if (flag_generate_lto || flag_generate_offload)
targetm.asm_out.lto_end ();
if (!flag_ltrans && (in_lto_p || !flag_lto || flag_fat_lto_objects))
/* Offloading requires LTO infrastructure. */
if (!in_lto_p && g->have_offload)
- flag_generate_lto = 1;
+ flag_generate_offload = 1;
/* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
- if (flag_generate_lto)
+ if (flag_generate_lto || flag_generate_offload)
lto_streamer_hooks_init ();
/* Don't run the IPA passes if there was any error or sorry messages. */
return;
}
- /* This pass remove bodies of extern inline functions we never inlined.
- Do this later so other IPA passes see what is really going on.
- FIXME: This should be run just after inlining by pasmanager. */
- remove_unreachable_nodes (false, dump_file);
global_info_ready = true;
if (dump_file)
{
/* Gimplify and lower all functions, compute reachability and
remove unreachable nodes. */
- analyze_functions ();
+ analyze_functions (/*first_time=*/true);
/* Mark alias targets necessary and emit diagnostics. */
handle_alias_pairs ();
/* Gimplify and lower thunks. */
- analyze_functions ();
+ analyze_functions (/*first_time=*/false);
+
+ /* Emit early debug for reachable functions, and by consequence,
+ locally scoped symbols. */
+ struct cgraph_node *cnode;
+ FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (cnode)
+ (*debug_hooks->early_global_decl) (cnode->decl);
+
+ /* Clean up anything that needs cleaning up after initial debug
+ generation. */
+ (*debug_hooks->early_finish) ();
/* Finally drive the pass manager. */
compile ();
void
cgraph_node::create_wrapper (cgraph_node *target)
{
- /* Preserve DECL_RESULT so we get right by reference flag. */
- tree decl_result = DECL_RESULT (decl);
+ /* Preserve DECL_RESULT so we get right by reference flag. */
+ tree decl_result = DECL_RESULT (decl);
- /* Remove the function's body but keep arguments to be reused
- for thunk. */
- release_body (true);
- reset ();
+ /* Remove the function's body but keep arguments to be reused
+ for thunk. */
+ release_body (true);
+ reset ();
- DECL_RESULT (decl) = decl_result;
- DECL_INITIAL (decl) = NULL;
- allocate_struct_function (decl, false);
- set_cfun (NULL);
+ DECL_UNINLINABLE (decl) = false;
+ DECL_RESULT (decl) = decl_result;
+ DECL_INITIAL (decl) = NULL;
+ allocate_struct_function (decl, false);
+ set_cfun (NULL);
- /* Turn alias into thunk and expand it into GIMPLE representation. */
- definition = true;
- thunk.thunk_p = true;
- thunk.this_adjusting = false;
+ /* Turn alias into thunk and expand it into GIMPLE representation. */
+ definition = true;
- cgraph_edge *e = create_edge (target, NULL, 0, CGRAPH_FREQ_BASE);
+ memset (&thunk, 0, sizeof (cgraph_thunk_info));
+ thunk.thunk_p = true;
+ create_edge (target, NULL, count, CGRAPH_FREQ_BASE);
- tree arguments = DECL_ARGUMENTS (decl);
+ tree arguments = DECL_ARGUMENTS (decl);
- while (arguments)
- {
- TREE_ADDRESSABLE (arguments) = false;
- arguments = TREE_CHAIN (arguments);
- }
+ while (arguments)
+ {
+ TREE_ADDRESSABLE (arguments) = false;
+ arguments = TREE_CHAIN (arguments);
+ }
- expand_thunk (false, true);
- e->call_stmt_cannot_inline_p = true;
+ expand_thunk (false, true);
- /* Inline summary set-up. */
- analyze ();
- inline_analyze_function (this);
+ /* Inline summary set-up. */
+ analyze ();
+ inline_analyze_function (this);
}
#include "gt-cgraphunit.h"