public class ConditionalEliminationPhase extends BasePhase<CoreProviders>
StructuredGraph
. This is done by optimizing
LogicNode
s to be conditionally (flow-sensitive) true
or false
. If such a
condition is input to a control split node, i.e., an IfNode
a subsequent application of
the CanonicalizerPhase
can remove the unconditional branch from the graph.
In order to prove conditions this phase build the
Dominator Tree of a method
and traverses it depth first. Every time the traversal encounters a basic block whose predecessor
has multiple successors (i.e., the predecessor block ends with a control flow split node) it
inspects the control split's condition in detail: The condition leading to the current block
carries value & type information for the operands of the condition.
Consider the following example where a variable a
is used in a condition 3 times.
Traversing the dominator tree depth first and recording the value ranges for a
after
every condition effectively makes the last condition a == 0
trivially true.
if (a >= 0) { // a in [0:Integer.MAX_VAL] if (a < 1) { // a in [Integer.MIN_VAL,0] && a in [0:Integer.MAX_VAL] // --> a in [0] if (a == 0) { // true } } }
Modifier and Type | Class and Description |
---|---|
static class |
ConditionalEliminationPhase.Instance |
static class |
ConditionalEliminationPhase.MoveGuardsUpwards |
static class |
ConditionalEliminationPhase.Options |
BasePhase.ApplyScope, BasePhase.BasePhaseStatistics, BasePhase.NotApplicable, BasePhase.PhaseOptions, BasePhase.SharedGlobalPhaseState
ALWAYS_APPLICABLE
Constructor and Description |
---|
ConditionalEliminationPhase(boolean fullSchedule) |
ConditionalEliminationPhase(boolean fullSchedule,
boolean moveGuards) |
Modifier and Type | Method and Description |
---|---|
Optional<BasePhase.NotApplicable> |
canApply(GraphState graphState)
Checks if all the preconditions to
BasePhase.apply(StructuredGraph, Object, boolean) the phase
are met. |
float |
codeSizeIncrease()
Returns a factor
>=1 that determines what the final code size in terms of the sum of
the node code sizes NodeSize of all nodes is. |
protected ControlFlowGraph.RecursiveVisitor<?> |
createVisitor(StructuredGraph graph,
ControlFlowGraph cfg,
BlockMap<List<Node>> blockToNodes,
NodeMap<Block> nodeToBlock,
CoreProviders context) |
protected BlockMap<List<Node>> |
getBlockToNodes(ControlFlowGraph cfg) |
protected void |
run(StructuredGraph graph,
CoreProviders context) |
apply, apply, applyScope, contractorName, equals, getName, hashCode, mustApply, shouldDumpAfterAtBasicLevel, shouldDumpBeforeAtBasicLevel, updateGraphState
clone, getClass, notify, notifyAll, toString, wait, wait, wait
checkContract
public ConditionalEliminationPhase(boolean fullSchedule)
public ConditionalEliminationPhase(boolean fullSchedule, boolean moveGuards)
public Optional<BasePhase.NotApplicable> canApply(GraphState graphState)
BasePhase
BasePhase.apply(StructuredGraph, Object, boolean)
the phase
are met.canApply
in class BasePhase<CoreProviders>
graphState
- represents the state of the StructuredGraph
used for compilation
and contains the required information to determine if a phase can be applied.Optional.empty()
if all the checks pass, Optional#of(NotApplicable)
containing why this phase is not applicable on this graphState
otherwise.protected void run(StructuredGraph graph, CoreProviders context)
run
in class BasePhase<CoreProviders>
protected BlockMap<List<Node>> getBlockToNodes(ControlFlowGraph cfg)
protected ControlFlowGraph.RecursiveVisitor<?> createVisitor(StructuredGraph graph, ControlFlowGraph cfg, BlockMap<List<Node>> blockToNodes, NodeMap<Block> nodeToBlock, CoreProviders context)
public float codeSizeIncrease()
PhaseSizeContract
>=1
that determines what the final code size in terms of the sum of
the node code sizes NodeSize
of all nodes is.codeSizeIncrease
in interface PhaseSizeContract
codeSizeIncrease
in class BasePhase<CoreProviders>