Functions are output early using call of
cgraph_assemble_pending_function from cgraph_finalize_function. The
decision on whether function is needed is made more conservative so
- uninlininable static functions are needed too. During the call-graph
+ uninlinable static functions are needed too. During the call-graph
construction the edge destinations are not marked as reachable and it
- is completely relied upn assemble_variable to mark them. */
+ is completely relied upon assemble_variable to mark them. */
#include "config.h"
/* Determine if function DECL is needed. That is, visible to something
either outside this translation unit, something magic in the system
- configury, or (if not doing unit-at-a-time) to something we havn't
+ configury, or (if not doing unit-at-a-time) to something we haven't
seen yet. */
static bool
it into reachable functions list. */
node->next_needed = NULL;
- node->needed = node->reachable = false;
cgraph_finalize_function (fndecl, false);
cgraph_mark_reachable_node (node);
output = true;
cgraph_analyze_function (node);
push_cfun (DECL_STRUCT_FUNCTION (fndecl));
current_function_decl = fndecl;
- node->local.inlinable = tree_inlinable_function_p (fndecl);
- node->local.self_insns = estimate_num_insns (fndecl,
- &eni_inlining_weights);
- node->local.disregard_inline_limits
- |= DECL_DISREGARD_INLINE_LIMITS (fndecl);
- /* Inlining characteristics are maintained by the
- cgraph_mark_inline. */
- node->global.insns = node->local.self_insns;
- if (flag_really_no_inline && !node->local.disregard_inline_limits)
- node->local.inlinable = 0;
+ compute_inline_parameters (node);
if ((cgraph_state == CGRAPH_STATE_IPA_SSA
&& !gimple_in_ssa_p (DECL_STRUCT_FUNCTION (fndecl)))
/* When not optimizing, be sure we run early local passes anyway
to expand OMP. */
|| !optimize)
- execute_pass_list (pass_early_local_passes.sub);
+ execute_pass_list (pass_early_local_passes.pass.sub);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
pop_cfun ();
{
bool output = false;
- if (flag_unit_at_a_time)
+ if (flag_unit_at_a_time || errorcount || sorrycount)
return false;
cgraph_output_pending_asms ();
cgraph_node_remove_callees (node);
/* We may need to re-queue the node for assembling in case
- we already proceeded it and ignored as not needed. */
- if (node->reachable && !flag_unit_at_a_time)
+ we already proceeded it and ignored as not needed or got
+ a re-declaration in IMA mode. */
+ if (node->reachable)
{
struct cgraph_node *n;
node->pid = cgraph_max_pid ++;
notice_global_symbol (decl);
- node->decl = decl;
node->local.finalized = true;
node->lowered = DECL_STRUCT_FUNCTION (decl)->cfg != NULL;
record_cdtor_fn (node->decl);
do_warn_unused_parameter (decl);
}
+/* C99 extern inline keywords allow changing of declaration after function
+ has been finalized. We need to re-decide if we want to mark the function as
+ needed then. */
+
+void
+cgraph_mark_if_needed (tree decl)
+{
+ struct cgraph_node *node = cgraph_node (decl);
+ if (node->local.finalized && decide_is_function_needed (node, decl))
+ cgraph_mark_needed_node (node);
+}
+
/* Verify cgraph nodes of given cgraph node. */
void
verify_cgraph_node (struct cgraph_node *node)
struct cgraph_edge *e;
struct cgraph_node *main_clone;
struct function *this_cfun = DECL_STRUCT_FUNCTION (node->decl);
+ struct function *saved_cfun = cfun;
basic_block this_block;
block_stmt_iterator bsi;
bool error_found = false;
return;
timevar_push (TV_CGRAPH_VERIFY);
+ /* debug_generic_stmt needs correct cfun */
+ set_cfun (this_cfun);
for (e = node->callees; e; e = e->next_callee)
if (e->aux)
{
dump_cgraph_node (stderr, node);
internal_error ("verify_cgraph_node failed");
}
+ set_cfun (saved_cfun);
timevar_pop (TV_CGRAPH_VERIFY);
}
cgraph_lower_function (node);
node->analyzed = true;
- if (!flag_unit_at_a_time)
+ if (!flag_unit_at_a_time && !sorrycount && !errorcount)
{
bitmap_obstack_initialize (NULL);
tree_register_cfg_hooks ();
- execute_pass_list (pass_early_local_passes.sub);
+ execute_pass_list (pass_early_local_passes.pass.sub);
free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (CDI_DOMINATORS);
bitmap_obstack_release (NULL);
/* Make sure that BE didn't give up on compiling. */
/* ??? Can happen with nested function of extern inline. */
- gcc_assert (TREE_ASM_WRITTEN (node->decl));
+ gcc_assert (TREE_ASM_WRITTEN (decl));
current_function_decl = NULL;
- if (!cgraph_preserve_function_body_p (node->decl))
+ if (!cgraph_preserve_function_body_p (decl))
{
cgraph_release_function_body (node);
/* Eliminate all call edges. This is important so the call_expr no longer
{
struct cgraph_node *node;
struct cgraph_node **order = XCNEWVEC (struct cgraph_node *, cgraph_n_nodes);
- int order_pos = 0, new_order_pos = 0;
+ int order_pos, new_order_pos = 0;
int i;
order_pos = cgraph_postorder (order);
if (!quiet_flag)
fprintf (stderr, "Performing interprocedural optimizations\n");
cgraph_state = CGRAPH_STATE_IPA;
-
+
/* Don't run the IPA passes if there was any error or sorry messages. */
if (errorcount == 0 && sorrycount == 0)
ipa_passes ();
varpool_remove_unreferenced_decls ();
varpool_assemble_pending_decls ();
- varpool_output_debug_info ();
}
+ varpool_output_debug_info ();
cgraph_process_new_functions ();
cgraph_state = CGRAPH_STATE_FINISHED;
dump_cgraph_node (stderr, node);
}
if (error_found)
- internal_error ("nodes with no released memory found");
+ internal_error ("nodes with unreleased memory found");
}
#endif
}
/* Generate and emit a static constructor or destructor. WHICH must
be one of 'I' (for a constructor) or 'D' (for a destructor). BODY
is a STATEMENT_LIST containing GENERIC statements. PRIORITY is the
- initialization priority fot this constructor or destructor. */
+ initialization priority for this constructor or destructor. */
void
cgraph_build_static_cdtor (char which, tree body, int priority)