GCC Middle and Back End API 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_pass * | make_pass_uncprop () |
Variables | |
static vec< tree > | equiv_stack |
static hash_table < val_ssa_equiv_hasher > | val_ssa_equiv |
|
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 |
gimple_opt_pass* make_pass_uncprop | ( | ) |
|
static |
Record EQUIVALENCE = VALUE into our hash table.
References equiv_hash_elt::equivalences, hash_table< Descriptor, Allocator >::find_slot(), free(), and equiv_hash_elt::value.
Referenced by uncprop_enter_block(), and uncprop_into_successor_phis().
|
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 |
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 |
Main driver for un-cprop.
References dom_walk_data::after_dom_children, associate_equivalences_with_edges(), edge_def::aux, dom_walk_data::before_dom_children, dom_walk_data::block_local_data_size, calculate_dominance_info(), CDI_DOMINATORS, hash_table< Descriptor, Allocator >::create(), hash_table< Descriptor, Allocator >::dispose(), fini_walk_dominator_tree(), free(), dom_walk_data::global_data, init_walk_dominator_tree(), dom_walk_data::initialize_block_local_data, uncprop_enter_block(), uncprop_leave_block(), and walk_dominator_tree().
|
static |
|
static |
Referenced by uncprop_enter_block().
|
static |
Unpropagate values from PHI nodes in successor blocks of BB.
References edge_def::aux, edge_def::dest, edge_def::dest_idx, equiv_hash_elt::equivalences, hash_table< Descriptor, Allocator >::find_slot(), gimple_can_coalesce_p(), gimple_seq_empty_p(), gsi_end_p(), gsi_next(), gsi_stmt(), is_gimple_min_invariant(), edge_equivalency::lhs, phi_nodes(), phis, record_equiv(), remove_equivalence(), edge_equivalency::rhs, basic_block_def::succs, and equiv_hash_elt::value.
|
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().
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.
|
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.