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

Data Structures

struct  edge_equivalency
struct  equiv_hash_elt
struct  val_ssa_equiv_hasher

Functions

static void associate_equivalences_with_edges ()
static void uncprop_enter_block (struct dom_walk_data *, basic_block)
static void uncprop_leave_block (struct dom_walk_data *, basic_block)
static void uncprop_into_successor_phis (basic_block)
static void remove_equivalence ()
static void record_equiv ()
static unsigned int tree_ssa_uncprop ()
static void uncprop_into_successor_phis ()
static edge single_incoming_edge_ignoring_loop_edges ()
static bool gate_uncprop ()
gimple_opt_passmake_pass_uncprop ()

Variables

static vec< treeequiv_stack
static hash_table
< val_ssa_equiv_hasher
val_ssa_equiv

Function Documentation

static void associate_equivalences_with_edges ( )
static
This routine finds and records edge equivalences for every edge
   in the CFG.

   When complete, each edge that creates an equivalency will have an
   EDGE_EQUIVALENCY structure hanging off the edge's AUX field.
   The caller is responsible for freeing the AUX fields.   

References edge_def::aux, dconst0, extract_true_false_edges_from_block(), find_edge(), free(), gimple_cond_code(), gimple_cond_lhs(), gimple_cond_rhs(), gimple_switch_index(), gimple_switch_label(), gimple_switch_num_labels(), gsi_end_p(), gsi_last_bb(), gsi_stmt(), basic_block_def::index, integer_zerop(), is_gimple_min_invariant(), edge_equivalency::lhs, and edge_equivalency::rhs.

Referenced by tree_ssa_uncprop().

static bool gate_uncprop ( )
static
gimple_opt_pass* make_pass_uncprop ( )
static void record_equiv ( )
static
static void remove_equivalence ( )
static
Remove the most recently recorded equivalency for VALUE.   

References equiv_hash_elt::equivalences, hash_table< Descriptor, Allocator >::find_slot(), and equiv_hash_elt::value.

Referenced by uncprop_into_successor_phis(), and uncprop_leave_block().

static edge single_incoming_edge_ignoring_loop_edges ( )
static
Ignoring loop backedges, if BB has precisely one incoming edge then
   return that edge.  Otherwise return NULL.   

References CDI_DOMINATORS, edge_def::dest, dominated_by_p(), basic_block_def::preds, and edge_def::src.

Referenced by uncprop_enter_block().

static void uncprop_into_successor_phis ( basic_block  )
static

Referenced by uncprop_enter_block().

static void uncprop_leave_block ( struct dom_walk_data walk_data,
basic_block  bb 
)
static
We have finished processing the dominator children of BB, perform
   any finalization actions in preparation for leaving this node in
   the dominator tree.   

References remove_equivalence().

Referenced by tree_ssa_uncprop().


Variable Documentation

vec<tree> equiv_stack
static
Translating out of SSA sometimes requires inserting copies and
   constant initializations on edges to eliminate PHI nodes.

   In some cases those copies and constant initializations are
   redundant because the target already has the value on the
   RHS of the assignment.

   We previously tried to catch these cases after translating
   out of SSA form.  However, that code often missed cases.  Worse
   yet, the cases it missed were also often missed by the RTL
   optimizers.  Thus the resulting code had redundant instructions.

   This pass attempts to detect these situations before translating
   out of SSA form.

   The key concept that this pass is built upon is that these
   redundant copies and constant initializations often occur
   due to constant/copy propagating equivalences resulting from
   COND_EXPRs and SWITCH_EXPRs.

   We want to do those propagations as they can sometimes allow
   the SSA optimizers to do a better job.  However, in the cases
   where such propagations do not result in further optimization,
   we would like to "undo" the propagation to avoid the redundant
   copies and constant initializations.

   This pass works by first associating equivalences with edges in
   the CFG.  For example, the edge leading from a SWITCH_EXPR to
   its associated CASE_LABEL will have an equivalency between
   SWITCH_COND and the value in the case label.

   Once we have found the edge equivalences, we proceed to walk
   the CFG in dominator order.  As we traverse edges we record
   equivalences associated with those edges we traverse.

   When we encounter a PHI node, we walk its arguments to see if we
   have an equivalence for the PHI argument.  If so, then we replace
   the argument.

   Equivalences are looked up based on their value (think of it as
   the RHS of an assignment).   A value may be an SSA_NAME or an
   invariant.  We may have several SSA_NAMEs with the same value,
   so with each value we have a list of SSA_NAMEs that have the
   same value.   
As we enter each block we record the value for any edge equivalency
   leading to this block.  If no such edge equivalency exists, then we
   record NULL.  These equivalences are live until we leave the dominator
   subtree rooted at the block where we record the equivalency.   
hash_table<val_ssa_equiv_hasher> val_ssa_equiv
static
Global hash table implementing a mapping from invariant values
   to a list of SSA_NAMEs which have the same value.  We might be
   able to reuse tree-vn for this code.