参照元†
返り値†
/* Execute PASS. */
bool
execute_one_pass (opt_pass *pass)
{
unsigned int todo_after = 0;
bool gate_status;
/* IPA passes are executed on whole program, so cfun should be NULL.
Other passes need function context set. */
if (pass->type == SIMPLE_IPA_PASS || pass->type == IPA_PASS)
gcc_assert (!cfun && !current_function_decl);
else
gcc_assert (cfun && current_function_decl);
current_pass = pass;
/* Check whether gate check should be avoided.
User controls the value of the gate through the parameter "gate_status". */
gate_status = pass->gate (cfun);
gate_status = override_gate_status (pass, current_function_decl, gate_status);
/* Override gate with plugin. */
invoke_plugin_callbacks (PLUGIN_OVERRIDE_GATE, &gate_status);
if (!gate_status)
{
/* Run so passes selectively disabling themselves on a given function
are not miscounted. */
if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
{
check_profile_consistency (pass->static_pass_number, 0, false);
check_profile_consistency (pass->static_pass_number, 1, false);
}
current_pass = NULL;
return false;
}
if (should_skip_pass_p (pass))
{
skip_pass (pass);
return true;
}
/* Pass execution event trigger: useful to identify passes being
executed. */
invoke_plugin_callbacks (PLUGIN_PASS_EXECUTION, pass);
if (!quiet_flag && !cfun)
fprintf (stderr, " <%s>", pass->name ? pass->name : "");
/* Note that the folders should only create gimple expressions.
This is a hack until the new folder is ready. */
in_gimple_form = (cfun && (cfun->curr_properties & PROP_trees)) != 0;
pass_init_dump_file (pass);
/* If a timevar is present, start it. */
if (pass->tv_id != TV_NONE)
timevar_push (pass->tv_id);
/* Run pre-pass verification. */
execute_todo (pass->todo_flags_start);
if (flag_checking)
do_per_function (verify_curr_properties,
(void *)(size_t)pass->properties_required);
/* Do it! */
todo_after = pass->execute (cfun);
if (todo_after & TODO_discard_function)
{
/* Stop timevar. */
if (pass->tv_id != TV_NONE)
timevar_pop (pass->tv_id);
pass_fini_dump_file (pass);
gcc_assert (cfun);
/* As cgraph_node::release_body expects release dominators info,
we have to release it. */
if (dom_info_available_p (CDI_DOMINATORS))
free_dominance_info (CDI_DOMINATORS);
if (dom_info_available_p (CDI_POST_DOMINATORS))
free_dominance_info (CDI_POST_DOMINATORS);
tree fn = cfun->decl;
pop_cfun ();
gcc_assert (!cfun);
cgraph_node::get (fn)->release_body ();
current_pass = NULL;
redirect_edge_var_map_empty ();
ggc_collect ();
return true;
}
do_per_function (clear_last_verified, NULL);
do_per_function (update_properties_after_pass, pass);
if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
check_profile_consistency (pass->static_pass_number, 0, true);
/* Run post-pass cleanup and verification. */
execute_todo (todo_after | pass->todo_flags_finish | TODO_verify_il);
if (profile_report && cfun && (cfun->curr_properties & PROP_cfg))
check_profile_consistency (pass->static_pass_number, 1, true);
verify_interpass_invariants ();
/* Stop timevar. */
if (pass->tv_id != TV_NONE)
timevar_pop (pass->tv_id);
if (pass->type == IPA_PASS
&& ((ipa_opt_pass_d *)pass)->function_transform)
{
struct cgraph_node *node;
FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *)pass);
}
else if (dump_file)
do_per_function (execute_function_dump, pass);
if (!current_function_decl)
symtab->process_new_functions ();
pass_fini_dump_file (pass);
if (pass->type != SIMPLE_IPA_PASS && pass->type != IPA_PASS)
gcc_assert (!(cfun->curr_properties & PROP_trees)
|| pass->type != RTL_PASS);
current_pass = NULL;
redirect_edge_var_map_empty ();
/* Signal this is a suitable GC collection point. */
if (!((todo_after | pass->todo_flags_finish) & TODO_do_not_ggc_collect))
ggc_collect ();
return true;
}
コメント†