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

Data Structures

struct  phiprop_d

Functions

static bool phivn_valid_p ()
static tree phiprop_insert_phi (basic_block bb, gimple phi, gimple use_stmt, struct phiprop_d *phivn, size_t n)
static bool propagate_with_phi (basic_block bb, gimple phi, struct phiprop_d *phivn, size_t n)
static unsigned int tree_ssa_phiprop ()
static bool gate_phiprop ()
gimple_opt_passmake_pass_phiprop ()

Function Documentation

static bool gate_phiprop ( )
static
gimple_opt_pass* make_pass_phiprop ( )
static tree phiprop_insert_phi ( basic_block  bb,
gimple  phi,
gimple  use_stmt,
struct phiprop_d phivn,
size_t  n 
)
static
   Insert a new phi node for the dereference of PHI at basic_block
   BB with the virtual operands from USE_STMT.  
     Build a new PHI node to replace the definition of
     the indirect reference lhs.  
     Add PHI arguments for each edge inserting loads of the
     addressable operands.  
             Reuse a formerly created dereference.  
static bool phivn_valid_p ( )
static
   Verify if the value recorded for NAME in PHIVN is still valid at
   the start of basic block BB.  
     The def stmts of the virtual uses need to be dominated by bb.  
         If BB does not dominate a VDEF, the value is invalid.  

Referenced by propagate_with_phi().

static bool propagate_with_phi ( basic_block  bb,
gimple  phi,
struct phiprop_d phivn,
size_t  n 
)
static
   Propagate between the phi node arguments of PHI in BB and phi result
   users.  For now this matches
        # p_2 = PHI <&x, &y>
      <Lx>:;
        p_3 = p_2;
        z_2 = *p_3;
   and converts it to
        # z_2 = PHI <x, y>
      <Lx>:;
   Returns true if a transformation was done and edge insertions
   need to be committed.  Global data PHIVN and N is used to track
   past transformation results.  We need to be especially careful here
   with aliasing issues as we are moving memory reads.  
     Check if we can "cheaply" dereference all phi arguments.  
         Walk the ssa chain until we reach a ssa name we already
         created a value for or we reach a definition of the form
         ssa_name_n = &var;  
     Find a dereferencing use.  First follow (single use) ssa
     copy chains for ptr.  
     Replace the first dereference of *ptr if there is one and if we
     can move the loads to the place of the ptr phi node.  
         Check whether this is a load of *ptr.  
               We cannot replace a load that may throw or is volatile.  
         Check if we can move the loads.  The def stmt of the virtual use
         needs to be in a different basic block dominating bb.  
         Found a proper dereference.  Insert a phi node if this
         is the first load transformation.  
             Remember the value we created for *ptr.  
             Remove old stmt.  The phi is taken care of by DCE, if we
             want to delete it here we also have to delete all intermediate
             copies.  
             Further replacements are easy, just make a copy out of the
             load.  
         Continue searching for a proper dereference.  

References gimple_assign_rhs1(), gimple_assign_single_p(), phivn_valid_p(), and types_compatible_p().

static unsigned int tree_ssa_phiprop ( )
static
   Main entry for phiprop pass.  
     Walk the dominator tree in preorder.