GCC Middle and Back End API 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"
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_pass * | make_pass_uncprop () |
Variables | |
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.
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 |
Referenced by uncprop_dom_walker::before_dom_children().
gimple_opt_pass* make_pass_uncprop | ( | ) |
|
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 |
Remove the most recently recorded equivalency for VALUE.
|
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 |
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 |
|
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.
|
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.