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
class  uncprop_dom_walker


static void associate_equivalences_with_edges ()
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 ()


static hash_table
< val_ssa_equiv_hasher

Function Documentation

static void associate_equivalences_with_edges ( )
   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.  
     Walk over each block.  If the block ends with a control statement,
     then it might create a useful equivalence.  
         If the block does not end with a COND_EXPR or SWITCH_EXPR
         then there is nothing to do.  
         A COND_EXPR may create an equivalency in a variety of different
             Equality tests may create one or two equivalences.  
                 Special case comparing booleans against a constant as we
                 know the value of OP0 on both arms of the branch.  i.e., we
                 can record an equivalence for OP0 rather than COND.  
                     For IEEE, -0.0 == 0.0, so we don't necessarily know
                     the sign of a variable compared against zero.  If
                     we're honoring signed zeros, then we cannot record
                     this value unless we know that the value is nonzero.  
             ??? TRUTH_NOT_EXPR can create an equivalence too.  
         For a SWITCH_EXPR, a case label which represents a single
         value and which is the only case label which reaches the
         target block creates an equivalence.  
                 Walk over the case label vector.  Record blocks
                 which are reached by a single case label which represents
                 a single value.  
                 Now walk over the blocks to determine which ones were
                 marked as being reached by a useful case label.  
                         Record an equivalency on the edge from BB to basic
                         block I.  

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.

static bool gate_uncprop ( )
gimple_opt_pass* make_pass_uncprop ( )
static void record_equiv ( )
   Record EQUIVALENCE = VALUE into our hash table.  

References uncprop_dom_walker::m_equiv_stack.

Referenced by uncprop_dom_walker::after_dom_children(), and single_incoming_edge_ignoring_loop_edges().

static void remove_equivalence ( )
   Remove the most recently recorded equivalency for VALUE.  
static edge single_incoming_edge_ignoring_loop_edges ( )
   Ignoring loop backedges, if BB has precisely one incoming edge then
   return that edge.  Otherwise return NULL.  
         A loop back edge can be identified by the destination of
         the edge dominating the source of the edge.  
         If we have already seen a non-loop edge, then we must have
         multiple incoming non-loop edges and thus we return NULL.  
         This is the first non-loop incoming edge we have found.  Record

References edge_def::aux, edge_equivalency::lhs, uncprop_dom_walker::m_equiv_stack, record_equiv(), and edge_equivalency::rhs.

static unsigned int tree_ssa_uncprop ( )
   Main driver for un-cprop.  
     Create our global data structures.  
     We're going to do a dominator walk, so ensure that we have
     dominance information.  
     Recursively walk the dominator tree undoing unprofitable
     constant/copy propagations.  
     we just need to empty elements out of the hash table, and cleanup the
    AUX field on the edges.  

References edge_def::aux, and free().

Referenced by uncprop_dom_walker::before_dom_children().

static void uncprop_into_successor_phis ( basic_block  )
static void uncprop_into_successor_phis ( )
   Unpropagate values from PHI nodes in successor blocks of BB.  
     For each successor edge, first temporarily record any equivalence
     on that edge.  Then unpropagate values in any PHI nodes at the
     destination of the edge.  Then remove the temporary equivalence.  
         If there are no PHI nodes in this destination, then there is
         no sense in recording any equivalences.  
         Record any equivalency associated with E.  
         Walk over the PHI nodes, unpropagating values.  
             If the argument is not an invariant and can be potentially
             coalesced with the result, then there's no point in
             un-propagating the argument.  
             Lookup this argument's value in the hash table.  
                 Walk every equivalence with the same value.  If we find
                 one that can potentially coalesce with the PHI rsult,
                 then replace the value in the argument with its equivalent
                 SSA_NAME.  Use the most recent equivalence as hopefully
                 that results in shortest lifetimes.  
         If we had an equivalence associated with this edge, remove it.  

References edge_def::dest_idx, equiv_hash_elt::equivalences, and gimple_can_coalesce_p().

Variable Documentation

hash_table<val_ssa_equiv_hasher> val_ssa_equiv
   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.