GCC Middle and Back End API Reference
tree-ssa-threadupdate.c File Reference

Data Structures

struct  el
struct  redirection_data
struct  ssa_local_info_t
struct  thread_stats_d

Enumerations

enum  bb_dom_status { DOMST_NONDOMINATING, DOMST_LOOP_BROKEN, DOMST_DOMINATING }

Functions

static void remove_ctrl_stmt_and_useless_edges ()
static void create_block_for_threading ()
static struct redirection_datalookup_redirection_data ()
static void copy_phi_args ()
static void update_destination_phis ()
static void create_edge_and_update_destination_phis (struct redirection_data *rd, basic_block bb)
void ssa_fix_duplicate_block_edges (struct redirection_data *rd, ssa_local_info_t *local_info)
int ssa_create_duplicates (struct redirection_data **slot, ssa_local_info_t *local_info)
int ssa_fixup_template_block (struct redirection_data **slot, ssa_local_info_t *local_info)
int ssa_redirect_edges (struct redirection_data **slot, ssa_local_info_t *local_info)
static bool redirection_block_p ()
static bool thread_block ()
static basic_block thread_single_edge ()
static bool dbds_continue_enumeration_p ()
static enum bb_dom_status determine_bb_domination_status ()
static bool def_split_header_continue_p ()
static bool thread_through_loop_header ()
static void mark_threaded_blocks ()
bool thread_through_all_blocks ()
void register_jump_thread ()

Variables

static vec< edgethreaded_edges
struct thread_stats_d thread_stats
static hash_table
< redirection_data
redirection_data
static basic_block dbds_ce_stop

Enumeration Type Documentation

Evaluates the dominance relationship of latch of the LOOP and BB, and
   returns the state.   
Enumerator:
DOMST_NONDOMINATING 
DOMST_LOOP_BROKEN 
DOMST_DOMINATING 

Function Documentation

static void copy_phi_args ( )
static
static void create_block_for_threading ( )
static
static void create_edge_and_update_destination_phis ( struct redirection_data rd,
basic_block  bb 
)
static
Given a duplicate block and its single destination (both stored
   in RD).  Create an edge between the duplicate and its single
   destination.

   Add an additional argument to any PHI nodes at the single
   destination.   

References edge_def::aux, copy_phi_args(), edge_def::count, basic_block_def::count, edge_def::dest, el::e, make_edge(), redirection_data::outgoing_edge, edge_def::probability, and rescan_loop_exit().

Referenced by ssa_fix_duplicate_block_edges(), and thread_single_edge().

static bool dbds_continue_enumeration_p ( )
static
static bool def_split_header_continue_p ( )
static
Return true if BB is part of the new pre-header that is created
   when threading the latch to DATA.   

References loop_depth(), basic_block_def::loop_father, and loop_outer().

Referenced by thread_through_loop_header().

static struct redirection_data* lookup_redirection_data ( )
staticread
Given an outgoing edge E lookup and return its entry in our hash table.

   If INSERT is true, then we insert the entry into the hash table if
   it is not already present.  INCOMING_EDGE is added to the list of incoming
   edges associated with E in the hash table.   

References redirection_data::dup_block, el::e, hash_table< Descriptor, Allocator >::find_slot(), free(), redirection_data::incoming_edges, redirection_data::intermediate_edge, el::next, and redirection_data::outgoing_edge.

Referenced by thread_block().

static void mark_threaded_blocks ( )
static
Walk through the registered jump threads and convert them into a
   form convenient for this pass.

   Any block which has incoming edges threaded to outgoing edges
   will have its entry in THREADED_BLOCK set.

   Any threaded edge will have its new outgoing edge stored in the
   original edge's AUX field.

   This form avoids the need to walk all the edges in the CFG to
   discover blocks which need processing and avoids unnecessary
   hash table lookups to map from threaded edge to new target.   

References edge_def::aux, bitmap_copy(), bitmap_set_bit(), cfun, edge_def::dest, free(), basic_block_def::index, optimize_function_for_size_p(), basic_block_def::preds, and redirection_block_p().

Referenced by thread_through_all_blocks().

static bool redirection_block_p ( )
static
Return true if this block has no executable statements other than
   a simple ctrl flow instruction.  When the number of outgoing edges
   is one, this is equivalent to a "forwarder" block.   

References gimple_nop_p(), gsi_end_p(), gsi_next(), gsi_start_bb(), gsi_stmt(), and is_gimple_debug().

Referenced by mark_threaded_blocks(), and thread_through_loop_header().

void register_jump_thread ( )
Register a jump threading opportunity.  We queue up all the jump
   threading opportunities discovered by a pass and update the CFG
   and SSA form all at once.

   E is the edge we can thread, E2 is the new target edge, i.e., we
   are effectively recording that E->dest can be changed to E2->dest
   after fixing the SSA graph.   

References edge_def::dest, dump_file, dump_flags, and edge_def::src.

static void remove_ctrl_stmt_and_useless_edges ( )
static
Remove the last statement in block BB if it is a control statement
   Also remove all outgoing edges except the edge which reaches DEST_BB.
   If DEST_BB is NULL, then remove all outgoing edges.   

References edge_def::dest, ei_next(), ei_safe_edge(), gsi_end_p(), gsi_last_bb(), gsi_remove(), gsi_stmt(), remove_edge(), and basic_block_def::succs.

Referenced by ssa_fix_duplicate_block_edges(), and thread_single_edge().

int ssa_create_duplicates ( struct redirection_data **  slot,
ssa_local_info_t local_info 
)
Hash table traversal callback routine to create duplicate blocks.   

References ssa_local_info_t::bb, create_block_for_threading(), redirection_data::dup_block, ssa_fix_duplicate_block_edges(), and ssa_local_info_t::template_block.

Referenced by thread_block().

int ssa_fixup_template_block ( struct redirection_data **  slot,
ssa_local_info_t local_info 
)
inline
We did not create any outgoing edges for the template block during
   block creation.  This hash table traversal callback creates the
   outgoing edge for the template block.   

References redirection_data::dup_block, ssa_fix_duplicate_block_edges(), and ssa_local_info_t::template_block.

Referenced by thread_block().

static bool thread_block ( )
static
BB is a block which ends with a COND_EXPR or SWITCH_EXPR and when BB
   is reached via one or more specific incoming edges, we know which
   outgoing edge from BB will be traversed.

   We want to redirect those incoming edges to the target of the
   appropriate outgoing edge.  Doing so avoids a conditional branch
   and may expose new optimization opportunities.  Note that we have
   to update dominator tree and SSA graph after such changes.

   The key to keeping the SSA graph update manageable is to duplicate
   the side effects occurring in BB so that those side effects still
   occur on the paths which bypass BB after redirecting edges.

   We accomplish this by creating duplicates of BB and arranging for
   the duplicates to unconditionally pass control to one specific
   successor of BB.  We then revector the incoming edges into BB to
   the appropriate duplicate of BB.

   If NOLOOP_ONLY is true, we only perform the threading as long as it
   does not affect the structure of the loops in a nontrivial way.   

References edge_def::aux, ssa_local_info_t::bb, CDI_DOMINATORS, edge_def::count, hash_table< Descriptor, Allocator >::create(), edge_def::dest, hash_table< Descriptor, Allocator >::dispose(), el::e, free_dominance_info(), loop::header, ssa_local_info_t::jumps_threaded, loop::latch, lookup_redirection_data(), loop_exit_edge_p(), basic_block_def::loop_father, loop_latch_edge(), loop_outer(), LOOPS_NEED_FIXUP, loops_state_set(), basic_block_def::preds, set_loop_copy(), edge_def::src, ssa_create_duplicates(), ssa_fixup_template_block(), ssa_redirect_edges(), basic_block_def::succs, ssa_local_info_t::template_block, hash_table< Descriptor, Allocator >::traverse(), and update_bb_profile_for_threading().

Referenced by thread_through_all_blocks(), and thread_through_loop_header().

bool thread_through_all_blocks ( )
Walk through all blocks and thread incoming edges to the appropriate
   outgoing edge for each edge pair recorded in THREADED_EDGES.

   It is the caller's responsibility to fix the dominance information
   and rewrite duplicated SSA_NAMEs back into SSA form.

   If MAY_PEEL_LOOP_HEADERS is false, we avoid threading edges through
   loop headers if it does not simplify the loop.

   Returns true if one or more edges were threaded, false otherwise.   

References bitmap_bit_p(), cfun, free_original_copy_tables(), loop::header, basic_block_def::index, initialize_original_copy_tables(), LI_FROM_INNERMOST, LOOPS_NEED_FIXUP, loops_state_set(), mark_threaded_blocks(), memset(), thread_stats_d::num_threaded_edges, basic_block_def::preds, statistics_counter_event(), thread_block(), thread_stats, and thread_through_loop_header().

static void update_destination_phis ( )
static
We have recently made a copy of ORIG_BB, including its outgoing
   edges.  The copy is NEW_BB.  Every PHI node in every direct successor of
   ORIG_BB has a new argument associated with edge from NEW_BB to the
   successor.  Initialize the PHI argument so that it is equal to the PHI
   argument associated with the edge from ORIG_BB to the successor.   

References copy_phi_args(), edge_def::dest, el::e, find_edge(), and basic_block_def::succs.

Referenced by ssa_fix_duplicate_block_edges().


Variable Documentation

basic_block dbds_ce_stop
static
Callback for dfs_enumerate_from.  Returns true if BB is different
   from STOP and DBDS_CE_STOP.   
Main data structure to hold information for duplicates of BB.   
vec<edge> threaded_edges
static
Passes which use the jump threading code register jump threading
   opportunities as they are discovered.  We keep the registered
   jump threading opportunities in this vector as edge pairs
   (original_edge, target_edge).   

Referenced by try_forward_edges().