GCC Middle and Back End API Reference
tree-ssa-uncprop.c File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "flags.h"
#include "tm_p.h"
#include "basic-block.h"
#include "function.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "tree-cfg.h"
#include "tree-phinodes.h"
#include "ssa-iterators.h"
#include "domwalk.h"
#include "tree-pass.h"
#include "tree-ssa-propagate.h"
Include dependency graph for tree-ssa-uncprop.c:

Data Structures

struct  edge_equivalency
struct  equiv_hash_elt
struct  val_ssa_equiv_hasher
class  uncprop_dom_walker

Functions

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 ()

Variables

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.

 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
     ways.   
         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, BASIC_BLOCK, boolean_false_node, boolean_true_node, CASE_HIGH, CASE_LABEL, CASE_LOW, dconst0, error_mark_node, extract_true_false_edges_from_block(), find_edge(), fold_convert, 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(), HONOR_SIGNED_ZEROS, basic_block_def::index, integer_zerop(), is_gimple_min_invariant(), label_to_block, last_basic_block, edge_equivalency::lhs, n_basic_blocks, NULL, REAL_VALUES_EQUAL, edge_equivalency::rhs, SSA_NAME_OCCURS_IN_ABNORMAL_PHI, TREE_CODE, TREE_REAL_CST, TREE_TYPE, and TYPE_MODE.

static bool gate_uncprop ( )
static
gimple_opt_pass* make_pass_uncprop ( )
static void record_equiv ( )
static

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

Remove the most recently recorded equivalency for VALUE.

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.

     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
     it.   

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

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 NULL.

Referenced by uncprop_dom_walker::before_dom_children().

static void uncprop_into_successor_phis ( basic_block  )
static
static void uncprop_into_successor_phis ( )
static

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, gimple_can_coalesce_p(), and SET_PHI_ARG_DEF.


Variable Documentation

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.