GCC Middle and Back End API Reference
passes.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "line-map.h"
#include "hash-table.h"
#include "input.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "flags.h"
#include "insn-attr.h"
#include "insn-config.h"
#include "insn-flags.h"
#include "hard-reg-set.h"
#include "recog.h"
#include "output.h"
#include "except.h"
#include "function.h"
#include "toplev.h"
#include "expr.h"
#include "basic-block.h"
#include "intl.h"
#include "ggc.h"
#include "graph.h"
#include "regs.h"
#include "diagnostic-core.h"
#include "params.h"
#include "reload.h"
#include "debug.h"
#include "target.h"
#include "langhooks.h"
#include "cfgloop.h"
#include "hosthooks.h"
#include "opts.h"
#include "coverage.h"
#include "value-prof.h"
#include "tree-inline.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-ssanames.h"
#include "tree-ssa-loop-manip.h"
#include "tree-into-ssa.h"
#include "tree-dfa.h"
#include "tree-ssa.h"
#include "tree-pass.h"
#include "tree-dump.h"
#include "df.h"
#include "predict.h"
#include "lto-streamer.h"
#include "plugin.h"
#include "ipa-utils.h"
#include "tree-pretty-print.h"
#include "context.h"
#include "pass_manager.h"
#include "tree-ssa-live.h"
#include "tree-cfgcleanup.h"
#include "pass-instances.def"
#include "gt-passes.h"

Data Structures

struct  pass_registry
struct  pass_registry_hasher
struct  uid_range
struct  pass_list_node

Macros

#define DEF_PASS_LIST(LIST)   pass_lists[PASS_LIST_NO_##LIST] = &LIST;
#define INSERT_PASSES_AFTER(PASS)   p = &(PASS);
#define PUSH_INSERT_PASSES_WITHIN(PASS)
#define POP_INSERT_PASSES()   }
#define NEXT_PASS(PASS, NUM)
#define TERMINATE_PASS_LIST()   *p = NULL;

Typedefs

typedef const char * char_ptr
typedef struct uid_rangeuid_range_p

Functions

static void register_pass_name (struct opt_pass *, const char *)
void print_current_pass ()
DEBUG_FUNCTION void debug_pass ()
void rest_of_decl_compilation (tree decl, int top_level, int at_end)
void rest_of_type_compilation ()
static unsigned int execute_all_early_local_passes ()
static bool gate_all_early_local_passes ()
simple_ipa_opt_passmake_pass_early_local_passes ()
static bool gate_all_early_optimizations ()
static gimple_opt_passmake_pass_all_early_optimizations ()
static bool gate_all_optimizations ()
static gimple_opt_passmake_pass_all_optimizations ()
static bool gate_all_optimizations_g ()
static gimple_opt_passmake_pass_all_optimizations_g ()
static bool gate_rest_of_compilation ()
static rtl_opt_passmake_pass_rest_of_compilation ()
static bool gate_postreload ()
static rtl_opt_passmake_pass_postreload ()
void register_one_dump_file ()
static void register_pass_name ()
int passes_pass_traverse ()
static void create_pass_tab ()
static bool override_gate_status (struct opt_pass *, tree, bool)
static void dump_one_pass ()
static void dump_pass_list ()
void dump_passes ()
static struct opt_passget_pass_by_name ()
static void enable_disable_pass ()
void enable_pass ()
void disable_pass ()
static bool is_pass_explicitly_enabled_or_disabled (struct opt_pass *pass, tree func, vec< uid_range_p > tab)
static void add_pass_instance (struct opt_pass *new_pass, bool track_duplicates, opt_pass *initial_pass)
static struct opt_pass ** next_pass_1 (struct opt_pass **list, struct opt_pass *pass, struct opt_pass *initial_pass)
static bool position_pass (struct register_pass_info *new_pass_info, struct opt_pass **pass_list)
void register_pass ()
void register_pass (opt_pass *pass, pass_positioning_ops pos, const char *ref_pass_name, int ref_pass_inst_number)
static void do_per_function (void(*callback)(void *data), void *data)
void do_per_function_toporder (void(*callback)(void *data), void *data)
static void execute_function_dump ()
static void check_profile_consistency ()
void dump_profile_report ()
static void execute_function_todo ()
static void execute_todo ()
static void verify_interpass_invariants ()
static void clear_last_verified ()
bool pass_init_dump_file ()
void pass_fini_dump_file ()
static void update_properties_after_pass ()
void execute_ipa_summary_passes ()
static void execute_one_ipa_transform_pass (struct cgraph_node *node, struct ipa_opt_pass_d *ipa_pass)
void execute_all_ipa_transforms ()
static void apply_ipa_transforms ()
static bool override_gate_status ()
bool execute_one_pass ()
void execute_pass_list ()
static void ipa_write_summaries_2 ()
static void ipa_write_summaries_1 ()
void ipa_write_summaries ()
static void ipa_write_optimization_summaries_1 ()
void ipa_write_optimization_summaries ()
static void ipa_read_summaries_1 ()
void ipa_read_summaries ()
static void ipa_read_optimization_summaries_1 ()
void ipa_read_optimization_summaries ()
void execute_ipa_pass_list ()
static void execute_ipa_stmt_fixups (struct opt_pass *pass, struct cgraph_node *node, gimple *stmts)
void execute_all_ipa_stmt_fixups ()
void debug_properties (unsigned int)
void dump_properties (FILE *, unsigned int)
DEBUG_FUNCTION void dump_properties ()
DEBUG_FUNCTION void debug_properties ()
bool function_called_by_processed_nodes_p ()

Variables

struct opt_passcurrent_pass
bool in_gimple_form
bool first_pass_instance
static hash_table
< pass_registry_hasher
name_to_pass_map
static vec< char_ptrpass_tab = vNULL
static vec< uid_range_penabled_pass_uid_range_tab = vNULL
static vec< uid_range_pdisabled_pass_uid_range_tab = vNULL
static struct pass_list_nodeadded_pass_nodes = NULL
static struct pass_list_nodeprev_added_pass_node
static int nnodes
static cgraph_node_ptrorder
static struct profile_recordprofile_record

Macro Definition Documentation

#define DEF_PASS_LIST (   LIST)    pass_lists[PASS_LIST_NO_##LIST] = &LIST;
#define INSERT_PASSES_AFTER (   PASS)    p = &(PASS);
#define NEXT_PASS (   PASS,
  NUM 
)
Value:
do { \
gcc_assert (NULL == PASS ## _ ## NUM); \
if ((NUM) == 1) \
PASS ## _1 = make_##PASS (m_ctxt); \
else \
{ \
gcc_assert (PASS ## _1); \
PASS ## _ ## NUM = PASS ## _1->clone (); \
} \
p = next_pass_1 (p, PASS ## _ ## NUM, PASS ## _1); \
} while (0)
#define POP_INSERT_PASSES ( )    }
#define PUSH_INSERT_PASSES_WITHIN (   PASS)
Value:
{ \
struct opt_pass **p = &(PASS ## _1)->sub;
#define TERMINATE_PASS_LIST ( )    *p = NULL;

Typedef Documentation

typedef const char* char_ptr

Map from pass id to canonicalized pass name.

typedef struct uid_range* uid_range_p

Function Documentation

static void add_pass_instance ( struct opt_pass new_pass,
bool  track_duplicates,
opt_pass initial_pass 
)
static

Update static_pass_number for passes (and the flag TODO_mark_first_instance).

Passes are constructed with static_pass_number preinitialized to 0

This field is used in two different ways: initially as instance numbers of their kind, and then as ids within the entire pass manager.

Within pass_manager::pass_manager:

In add_pass_instance(), as called by next_pass_1 in NEXT_PASS in init_optimization_passes

When the initial instance of a pass within a pass manager is seen, it is flagged, and its static_pass_number is set to -1

On subsequent times that it is seen, the static pass number is decremented each time, so that if there are e.g. 4 dups, they have static_pass_number -4, 2, 3, 4 respectively (note how the initial one is negative and gives the count); these can be thought of as instance numbers of the specific pass

Within the register_dump_files () traversal, set_pass_for_id() is called on each pass, using these instance numbers to create dumpfile switches, and then overwriting them with a pass id, which are global to the whole pass manager (based on (TDI_end + current value of extra_dump_files_in_use) )

 Are we dealing with the first pass of its kind, or a clone?   
     We're dealing with a clone.   
     Indicate to register_dump_files that this pass has duplicates,
     and so it should rename the dump file.  The first instance will
     be -1, and be number of duplicates = -static_pass_number - 1.
     Subsequent instances will be > 0 and just the duplicate number.   
     We're dealing with the first pass of its kind.   

References opt_pass::clone(), opt_pass::next, NULL, register_pass_info::pass, register_pass_info::ref_pass_instance_number, register_pass_info::reference_pass_name, TODO_mark_first_instance, and pass_data::type.

static void apply_ipa_transforms ( )
static

Callback for do_per_function to apply all IPA transforms.

static void check_profile_consistency ( )
static

Do profile consistency book-keeping for the pass with static number INDEX. If SUBPASS is zero, we run before the pass, and if SUBPASS is one, then we run after the pass. RUN is true if the pass really runs, or FALSE if we are only book-keeping on passes that may have selectively disabled themselves on a given function.

static void clear_last_verified ( )
static

Clear the last verified flag.

static void create_pass_tab ( )
static

The function traverses NAME_TO_PASS_MAP and creates a pass info table for dumping purpose.

DEBUG_FUNCTION void debug_pass ( void  )

Call from the debugger to get the current pass name.

void debug_properties ( unsigned  int)
DEBUG_FUNCTION void debug_properties ( )
void disable_pass ( )

Disable pass specified by ARG.

static void do_per_function ( void(*)(void *data callback,
void *  data 
)
static

If we are in IPA mode (i.e., current_function_decl is NULL), call function CALLBACK for every function in the call graph. Otherwise, call CALLBACK on the current function.

void do_per_function_toporder ( void(*)(void *data callback,
void *  data 
)

If we are in IPA mode (i.e., current_function_decl is NULL), call function CALLBACK for every function in the call graph. Otherwise, call CALLBACK on the current function. This function is global so that plugins can use it.

Allow possibly removed nodes to be garbage collected.

References gcc::pass_manager::dump_profile_report(), g, and gcc::context::get_passes().

static void dump_one_pass ( )
static

Dump the instantiated name for PASS. IS_ON indicates if PASS is turned on or not.

static void dump_pass_list ( )
static

Dump pass list PASS with indentation INDENT.

References name_to_pass_map, NULL, and pass_registry::unique_name.

void dump_passes ( void  )

Dump all optimization passes.

References last.

void dump_profile_report ( void  )

Output profile consistency.

References gcc::pass_manager::passes_by_id.

void dump_properties ( FILE *  ,
unsigned  int 
)
DEBUG_FUNCTION void dump_properties ( )
static void enable_disable_pass ( )
static

Parse option string for -fdisable- and -fenable- The syntax of the options:

-fenable-<pass_name> -fdisable-<pass_name>

-fenable-<pass_name>=s1:e1,s2:e2,... -fdisable-<pass_name>=s1:e1,s2:e2,...

void enable_pass ( )

Enable pass specified by ARG.

static unsigned int execute_all_early_local_passes ( )
static

Once this pass (and its sub-passes) are complete, all functions will be in SSA form. Technically this state change is happening a tad early, since the sub-passes have not yet run, but since none of the sub-passes are IPA passes and do not create new functions, this is ok. We're setting this value for the benefit of IPA passes that follow.

void execute_all_ipa_stmt_fixups ( )

Execute stmt fixup hooks of all IPA passes for NODE and STMTS.

void execute_all_ipa_transforms ( void  )

For the current function, execute all ipa transforms.

static void execute_function_dump ( )
static

Helper function to perform function body dump.

Flush the file. If verification fails, we won't be able to close the file before aborting.

static void execute_function_todo ( )
static

Perform all TODO actions that ought to be done on each function.

 Always cleanup the CFG before trying to update SSA.   
     When cleanup_tree_cfg merges consecutive blocks, it may
     perform some simplistic propagation when removing single
     valued PHI nodes.  This propagation may, in turn, cause the
     SSA form to become out-of-date (see PR 22037).  So, even
     if the parent pass had not scheduled an SSA update, we may
     still need to do one.   
 If we've seen errors do not bother running any verifiers.   

References cfun, dump_file, gcc_assert, and symtab_remove_unreachable_nodes().

void execute_ipa_pass_list ( )

Same as execute_pass_list but assume that subpasses of IPA passes are local passes.

static void execute_ipa_stmt_fixups ( struct opt_pass pass,
struct cgraph_node node,
gimple stmts 
)
static

Execute stmt fixup hooks of all passes in PASS for NODE and STMTS.

     Execute all of the IPA_PASSes in the list.   
             If a timevar is present, start it.   
             Stop timevar.   
void execute_ipa_summary_passes ( )

Execute summary generation for all of the passes in IPA_PASS.

     Execute all of the IPA_PASSes in the list.   
         If a timevar is present, start it.   
         Stop timevar.   
static void execute_one_ipa_transform_pass ( struct cgraph_node node,
struct ipa_opt_pass_d ipa_pass 
)
static

Execute IPA_PASS function transform on NODE.

 Note that the folders should only create gimple expressions.
 This is a hack until the new folder is ready.   
 Run pre-pass verification.   
 If a timevar is present, start it.   
 Do it!   
 Stop timevar.   
 Run post-pass cleanup and verification.   
 Signal this is a suitable GC collection point.   
bool execute_one_pass ( )

Execute PASS.

 IPA passes are executed on whole program, so cfun should be NULL.
 Other passes need function context set.   
 Check whether gate check should be avoided.
 User controls the value of the gate through the parameter "gate_status".  
 Override gate with plugin.   
     Run so passes selectively disabling themselves on a given function
     are not miscounted.   
 Pass execution event trigger: useful to identify passes being
 executed.   
 SIPLE IPA passes do not handle callgraphs with IPA transforms in it.
 Apply all trnasforms first.   
     Restore current_pass.   
 Note that the folders should only create gimple expressions.
 This is a hack until the new folder is ready.   
 Run pre-pass verification.   
 If a timevar is present, start it.   
 Do it!   
 Stop timevar.   
 Run post-pass cleanup and verification.   
 Signal this is a suitable GC collection point.   

References execute_pass_list(), gcc_assert, and GIMPLE_PASS.

void execute_pass_list ( )

Referenced by execute_one_pass().

static void execute_todo ( )
static

Perform all TODO actions.

 Inform the pass whether it is the first time it is run.   
 Always remove functions just as before inlining: IPA passes might be
 interested to see bodies of extern inline functions that are not inlined
 to analyze side effects.  The full removal is done just at the end
 of IPA pass queue.   
     Flush the file.  If verification fails, we won't be able to
     close the file before aborting.   
 Now that the dumping has been done, we can get rid of the optional
 df problems.   
bool function_called_by_processed_nodes_p ( void  )

Called by local passes to see if function is called by already processed nodes. Because we process nodes in topological order, this means that function is in recursive cycle or we introduced new direct calls.

static bool gate_all_early_local_passes ( )
static

Gate: execute, or not, all of the non-trivial optimizations.

Don't bother doing anything if the program has errors.

static bool gate_all_early_optimizations ( )
static

Gate: execute, or not, all of the non-trivial optimizations.

Don't bother doing anything if the program has errors.

static bool gate_all_optimizations ( )
static

Gate: execute, or not, all of the non-trivial optimizations.

static bool gate_all_optimizations_g ( )
static

Gate: execute, or not, all of the non-trivial optimizations.

static bool gate_postreload ( )
static
static bool gate_rest_of_compilation ( )
static

Early return if there were errors. We can run afoul of our consistency checks, and there's not really much point in fixing them.

static struct opt_pass* get_pass_by_name ( )
staticread

Returns the pass with NAME.

void ipa_read_optimization_summaries ( void  )

Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes.

static void ipa_read_optimization_summaries_1 ( )
static

Same as execute_pass_list but assume that subpasses of IPA passes are local passes.

If a timevar is present, start it.

             Stop timevar.   

References dump_properties().

void ipa_read_summaries ( void  )

Read all the summaries for all_regular_ipa_passes and all_lto_gen_passes.

static void ipa_read_summaries_1 ( )
static

Same as execute_pass_list but assume that subpasses of IPA passes are local passes.

If a timevar is present, start it.

             Stop timevar.   

Referenced by ipa_write_summaries().

void ipa_write_optimization_summaries ( )

Write all the optimization summaries for the cgraph nodes in SET. If SET is NULL, write out all summaries of all nodes.

When streaming out references to statements as part of some IPA pass summary, the statements need to have uids assigned.

For functions newly born at WPA stage we need to initialize the uids here.

static void ipa_write_optimization_summaries_1 ( )
static

Same as execute_pass_list but assume that subpasses of IPA passes are local passes. If SET is not NULL, write out optimization summaries of only those node in SET.

If a timevar is present, start it.

         If a timevar is present, start it.   
void ipa_write_summaries ( void  )

Write out summaries for all the nodes in the callgraph.

Create the callgraph set in the same order used in cgraph_expand_all_functions. This mostly facilitates debugging, since it causes the gimple file to be processed in the same order as the source code.

         When streaming out references to statements as part of some IPA
         pass summary, the statements need to have uids assigned and the
         following does that for all the IPA passes here. Naturally, this
         ordering then matches the one IPA-passes get in their stmt_fixup
         hooks.   

References GIMPLE_PASS, IPA_PASS, ipa_read_summaries_1(), pass_fini_dump_file(), pass_init_dump_file(), ipa_opt_pass_d::read_summary, opt_pass::sub, timevar_pop(), timevar_push(), pass_data::tv_id, and pass_data::type.

static void ipa_write_summaries_1 ( )
static

Helper function of ipa_write_summaries. Creates and destroys the decl state and calls ipa_write_summaries_2 for all passes that have summaries. SET is the set of nodes to be written.

static void ipa_write_summaries_2 ( )
static

Same as execute_pass_list but assume that subpasses of IPA passes are local passes. If SET is not NULL, write out summaries of only those node in SET.

If a timevar is present, start it.

         If a timevar is present, start it.   
static bool is_pass_explicitly_enabled_or_disabled ( struct opt_pass pass,
tree  func,
vec< uid_range_p tab 
)
static

Returns true if PASS is explicitly enabled/disabled for FUNC.

References invoke_plugin_callbacks(), pass_data::name, opt_pass::static_pass_number, pass_data::todo_flags_start, and TODO_mark_first_instance.

static gimple_opt_pass* make_pass_all_early_optimizations ( )
static
static gimple_opt_pass* make_pass_all_optimizations ( )
static
static gimple_opt_pass* make_pass_all_optimizations_g ( )
static
simple_ipa_opt_pass* make_pass_early_local_passes ( )
static rtl_opt_pass* make_pass_postreload ( )
static
static rtl_opt_pass* make_pass_rest_of_compilation ( )
static
static struct opt_pass** next_pass_1 ( struct opt_pass **  list,
struct opt_pass pass,
struct opt_pass initial_pass 
)
staticread

Add a pass to the pass list. Duplicate the pass if it's already in the list.

Every pass should have a name so that plugins can refer to them.

static bool override_gate_status ( struct opt_pass ,
tree  ,
bool   
)
static
static bool override_gate_status ( )
static

Check if PASS is explicitly disabled or enabled and return the gate status. FUNC is the function to be processed, and GATE_STATUS is the gate status determined by pass manager by default.

void pass_fini_dump_file ( )

Flush PASS dump file. This is non-static so that plugins can use it.

Flush and close dump file.

Referenced by ipa_write_summaries().

bool pass_init_dump_file ( )

Helper function. Verify that the properties has been turn into the properties expected by the pass. Initialize pass dump file. This is non-static so that the plugins can use it.

If a dump file name is present, open it if enabled.

Referenced by ipa_write_summaries().

int passes_pass_traverse ( )

Callback function for traversing NAME_TO_PASS_MAP.

Referenced by register_pass_name().

static bool position_pass ( struct register_pass_info new_pass_info,
struct opt_pass **  pass_list 
)
static

Insert the pass at the proper position. Return true if the pass is successfully added.

NEW_PASS_INFO - new pass to be inserted PASS_LIST - root of the pass list to insert the new pass to

     Check if the current pass is of the same type as the new pass and
     matches the name and the instance number of the reference pass.   
         Insert the new pass instance based on the positioning op.   
               Skip newly inserted pass to avoid repeated
               insertions in the case where the new pass and the
               existing one have the same name.   
         Save the newly added pass (instance) in the added_pass_nodes
         list so that we can register its dump file later. Note that
         we cannot register the dump file now because doing so will modify
         the static_pass_number of the opt_pass object and therefore
         mess up the dump file name of future instances.   
void print_current_pass ( )

Call from anywhere to find out what pass this is. Useful for printing out debugging information deep inside an service routine.

void register_one_dump_file ( )

Iterate over the pass tree allocating dump file numbers. We want to do this depth first, and independent of whether the pass is enabled or not.

References TDF_TREE.

void register_pass ( )

Hooks a new pass into the pass lists.

PASS_INFO - pass information that specifies the opt_pass object, reference pass, instance number, and how to position the pass

void register_pass ( opt_pass pass,
pass_positioning_ops  pos,
const char *  ref_pass_name,
int  ref_pass_inst_number 
)
static void register_pass_name ( struct opt_pass ,
const char *   
)
static
static void register_pass_name ( )
static
void rest_of_decl_compilation ( tree  decl,
int  top_level,
int  at_end 
)

This is called from various places for FUNCTION_DECL, VAR_DECL, and TYPE_DECL nodes.

This does nothing for local (non-static) variables, unless the variable is a register variable with DECL_ASSEMBLER_NAME set. In that case, or if the variable is not an automatic, it sets up the RTL and outputs any assembler code (label definition, storage allocation and initialization).

DECL is the declaration. TOP_LEVEL is nonzero if this declaration is not within a function.

 We deferred calling assemble_alias so that we could collect
 other attributes such as visibility.  Emit the alias now.   
       A quirk of the initial implementation of aliases required that the
       user add "extern" to all of them.  Which is silly, but now
       historical.  Do note that the symbol is in fact locally defined.   
 Can't defer this, because it needs to happen before any
 later function definitions are processed.   
 Forward declarations for nested functions are not "external",
 but we need to treat them as if they were.   
     Don't output anything when a tentative file-scope definition
     is seen.  But at end of compilation, do output code for them.

     We do output all variables and rely on
     callgraph code to defer them except for forward declarations
     (see gcc.c-torture/compile/920624-1.c)  
         When reading LTO unit, we also read varpool, so do not
         rebuild it.   
          Like in rest_of_type_compilation, avoid confusing the debug
          information machinery when there are errors.   
 Let cgraph know about the existence of variables.   
void rest_of_type_compilation ( )

Called after finishing a record, union or enumeral type.

Avoid confusing the debug information machinery when there are errors.

References gcc::dump_manager::dump_finish(), gcc::dump_manager::dump_start(), end_branch_prob(), gcc::context::get_dumps(), gcc::pass_manager::m_ctxt, NULL, and timevar_push().

static void update_properties_after_pass ( )
static

After executing the pass, apply expected changes to the function properties.

static void verify_interpass_invariants ( )
static

Verify invariants that should hold between passes. This is a place to put simple sanity checks.


Variable Documentation

struct pass_list_node* added_pass_nodes = NULL
static
struct opt_pass* current_pass

This is used for debugging. It allows the current pass to printed from anywhere in compilation. The variable current_pass is also used for statistics and plugins.

Referenced by gcc::pass_manager::execute_pass_mode_switching(), and statistics_fini_pass_3().

vec<uid_range_p> disabled_pass_uid_range_tab = vNULL
static
vec<uid_range_p> enabled_pass_uid_range_tab = vNULL
static
bool first_pass_instance

Set to true if the pass is called the first time during compilation of the current function. Note that using this information in the optimization passes is considered not to be clean, and it should be avoided if possible. This flag is currently used to prevent loops from being peeled repeatedly in jump threading; it will be removed once we preserve loop structures throughout the compilation – we will be able to mark the affected loops directly in jump threading, and avoid peeling them next time.

bool in_gimple_form

Global variables used to communicate with passes.

hash_table<pass_registry_hasher> name_to_pass_map
static
int nnodes
static

Because inlining might remove no-longer reachable nodes, we need to keep the array visible to garbage collector to avoid reading collected out nodes.

vec<char_ptr> pass_tab = vNULL
static

Referenced by register_pass_name().

struct pass_list_node* prev_added_pass_node
static