public final class BranchOptimizations extends BranchOptimizationDriver
Modifier and Type | Field and Description |
---|---|
private static Atom |
ABS
Name of abs method used as a special case in conditional moves
|
private boolean |
mayDuplicateCondBranches
Are we allowed to duplication conditional branches?
|
private boolean |
mayReorderCode
Is branch optimizations allowed to change the code order to
create fallthrough edges (and thus merge basic blocks)?
|
container
Constructor and Description |
---|
BranchOptimizations(int level,
boolean mayReorderCode,
boolean mayDuplicateCondBranches) |
BranchOptimizations(int level,
boolean mayReorderCode,
boolean mayDuplicateCondBranches,
boolean simplify) |
Modifier and Type | Method and Description |
---|---|
private void |
booleanCompareHelper(Instruction cb,
RegisterOperand res,
Operand val1,
Operand val2,
ConditionOperand cond)
Generate a boolean operation opcode
1) IF br !
|
private Instruction[] |
copyAndMapInstructions(BasicBlock bb,
HashMap<Instruction,Instruction> map)
For each real non-branch instruction s in bb,
Copy s to s', and store s' in the returned array
Insert the function s->s' in the map
|
private void |
doCondMove(IR ir,
Diamond diamond,
Instruction cb)
Perform the transformation to replace conditional branch with a
sequence using conditional moves.
|
private int |
evaluateCost(BasicBlock bb)
Evaluates the cost of a basic block, in number of real instructions
excluding branches.
|
private void |
flipConditionalBranch(Instruction cb)
Flip a conditional branch and remove the trailing goto.
|
private boolean |
fpConditionOK(ConditionOperand c)
Is a specified condition operand 'safe' to transfer into an FCMP
instruction?
|
private boolean |
generateBooleanCompare(IR ir,
BasicBlock bb,
Instruction cb,
BasicBlock tb)
Attempt to generate a boolean compare opcode from a conditional branch.
|
private boolean |
generateCondMove(IR ir,
BasicBlock bb,
Instruction cb)
Attempt to generate a straight-line sequence using conditional move
instructions, to replace a diamond control flow structure.
|
private boolean |
hasCMTaboo(BasicBlock bb)
Do any of the instructions in a basic block preclude eliminating the
basic block with conditional moves?
|
private static boolean |
hasFloatingPointDef(BasicBlock bb,
boolean invert)
Do any of the instructions in a basic block define a floating-point
register?
|
private boolean |
hasLongDef(BasicBlock bb)
Do any of the instructions in a basic block define a long
register?
|
private void |
insertBefore(Instruction[] list,
Instruction s)
Inserts each instruction in a list before another instruction.
|
private boolean |
isFlipCandidate(Instruction cb,
Instruction target)
Is a conditional branch a candidate to be flipped?
|
protected boolean |
optimizeBranchInstruction(IR ir,
Instruction s,
BasicBlock bb)
This method actually does the work of attempting to
peephole optimize a branch instruction.
|
private boolean |
processConditionalBranch(IR ir,
Instruction cb,
BasicBlock bb)
Perform optimizations for a conditional branch.
|
private boolean |
processGoto(IR ir,
Instruction g,
BasicBlock bb)
Perform optimizations for a Goto.
|
private boolean |
processInlineGuard(IR ir,
Instruction cb,
BasicBlock bb)
Perform optimizations for an inline guard.
|
private boolean |
processTwoTargetConditionalBranch(IR ir,
Instruction cb,
BasicBlock bb)
Perform optimizations for a two way conditional branch.
|
private void |
rewriteWithTemporaries(Instruction[] set,
IR ir)
For each in a set of instructions, rewrite every def to use a new
temporary register.
|
applyPeepholeBranchOpts, firstLabelFollowing, firstRealInstructionFollowing, getName, maximizeBasicBlocks, newExecution, perform, perform, printingEnabled, removeUnreachableCode, shouldPerform
dumpIR, dumpIR, getClassConstructor, getCompilerPhaseConstructor, getCompilerPhaseConstructor, performPhase, reportAdditionalStats, setContainer, verify
private final boolean mayReorderCode
private final boolean mayDuplicateCondBranches
public BranchOptimizations(int level, boolean mayReorderCode, boolean mayDuplicateCondBranches)
level
- the minimum optimization level at which the branch
optimizations should be performed.mayReorderCode
- are we allowed to change the code order?mayDuplicateCondBranches
- are we allowed to duplicate conditional branches?public BranchOptimizations(int level, boolean mayReorderCode, boolean mayDuplicateCondBranches, boolean simplify)
level
- the minimum optimization level at which the branch
optimizations should be performed.mayReorderCode
- are we allowed to change the code order?mayDuplicateCondBranches
- are we allowed to duplicate conditional branches?simplify
- simplify prior to optimizing?protected boolean optimizeBranchInstruction(IR ir, Instruction s, BasicBlock bb)
optimizeBranchInstruction
in class BranchOptimizationDriver
ir
- the containing IRs
- the branch instruction to optimizebb
- the containing basic blocktrue
if an optimization was applied, false
otherwiseprivate boolean processGoto(IR ir, Instruction g, BasicBlock bb)
Patterns:
1) GOTO A replaced by GOTO B A: GOTO B 2) GOTO A replaced by IF .. GOTO B A: IF .. GOTO B GOTO C C: ... 3) GOTO next instruction eliminated 4) GOTO A replaced by GOTO B A: LABEL BBEND B: 5) GOTO BBn where BBn has exactly one in edge - move BBn immediately after the GOTO in the code order, so that pattern 3) will create a fallthrough
Precondition: Goto.conforms(g)
ir
- governing IRg
- the instruction to optimizebb
- the basic block holding gtrue
if made a transformationprivate boolean processConditionalBranch(IR ir, Instruction cb, BasicBlock bb)
1) IF .. GOTO A replaced by IF .. GOTO B ... A: GOTO B 2) conditional branch to next instruction eliminated 3) IF (condition) GOTO A replaced by IF (!condition) GOTO B GOTO B A: ... A: ... 4) special case to generate Boolean compare opcode 5) special case to generate conditional move sequence 6) IF .. GOTO A replaced by IF .. GOTO B A: LABEL BBEND B: 7) fallthrough to a goto: replicate goto to enable other optimizations.
Precondition: IfCmp.conforms(cb)
ir
- the governing IRcb
- the instruction to optimizebb
- the basic block holding iftrue
iff made a transformationprivate boolean processInlineGuard(IR ir, Instruction cb, BasicBlock bb)
Precondition: InlineGuard.conforms(cb)
ir
- the governing IRcb
- the instruction to optimizebb
- the basic block holding iftrue
iff made a transformationprivate boolean processTwoTargetConditionalBranch(IR ir, Instruction cb, BasicBlock bb)
Precondition: IfCmp2.conforms(cb)
ir
- the governing IRcb
- the instruction to optimizebb
- the basic block holding iftrue
iff made a transformationprivate boolean isFlipCandidate(Instruction cb, Instruction target)
Precondition: IfCmp.conforms(cb)
cb
- the conditional branch instructiontarget
- the target instruction (real instruction) of the conditional
branchprivate void flipConditionalBranch(Instruction cb)
Precondition isFlipCandidate(cb)
cb
- the conditional branch instructionprivate void booleanCompareHelper(Instruction cb, RegisterOperand res, Operand val1, Operand val2, ConditionOperand cond)
1) IF br != 0 THEN x=1 ELSE x=0 replaced by INT_MOVE x=br IF br == 0 THEN x=0 ELSE x=1 2) IF br == 0 THEN x=1 ELSE x=0 replaced by BOOLEAN_NOT x=br IF br != 0 THEN x=0 ELSE x=1 3) IF v1 ~ v2 THEN x=1 ELSE x=0 replaced by BOOLEAN_CMP x=v1,v2,~
cb
- conditional branch instructionres
- the operand for resultval1
- value being comparedval2
- value being compared withcond
- comparison conditionprivate boolean generateCondMove(IR ir, BasicBlock bb, Instruction cb)
Suppose we have the following code, where e{n} is an expression:
if (a op b) { x = e2; y = e3; } else { z = e4; x = e5; }We would transform this to:
t1 = a; t2 = b; t3 = e2; t4 = e3; t5 = e4; t6 = e5; COND MOVE [if (t1 op t2) x := t3 else x := t6 ]; COND MOVE [if (t1 op t2) y := t4 else y := y]; COND MOVE [if (t1 op t2) z := z else z := t5];
Note that we rely on other optimizations (eg. copy propagation) to clean up some of this unnecessary mess.
Note that in this example, we've increased the shortest path by 2 expression evaluations, 2 moves, and 3 cond moves, but eliminated one conditional branch.
We apply a cost heuristic to guide this transformation: We will eliminate a conditional branch iff it increases the shortest path by no more than 'k' operations. Currently, we count each instruction (alu, move, or cond move) as 1 evaluation. The parameter k is specified by OPT\_Options.COND_MOVE_CUTOFF.
In the example above, since we've increased the shortest path by
6 instructions, we will only perform the transformation if k >= 7
.
TODO items
ir
- governing IRbb
- basic block of cbcb
- conditional branch instructionprivate boolean fpConditionOK(ConditionOperand c)
c
- operand to checkprivate static boolean hasFloatingPointDef(BasicBlock bb, boolean invert)
bb
- basic block to searchinvert
- true
if and only if the sense of the search
should be invertedprivate boolean hasLongDef(BasicBlock bb)
bb
- basic block to searchprivate boolean hasCMTaboo(BasicBlock bb)
bb
- the block to checkprivate int evaluateCost(BasicBlock bb)
bb
- the block to evaluateprivate Instruction[] copyAndMapInstructions(BasicBlock bb, HashMap<Instruction,Instruction> map)
bb
- the basic block to processmap
- map for instructions (must be empty at the start)private void rewriteWithTemporaries(Instruction[] set, IR ir)
set
- the instructions to rewriteir
- the IR that will provide the temporary registersprivate void insertBefore(Instruction[] list, Instruction s)
list
- the instructions to insert before the other instructions
- the instruction before which the insertion should be doneprivate void doCondMove(IR ir, Diamond diamond, Instruction cb)
ir
- governing IRdiamond
- the IR diamond structure to replacecb
- conditional branch instruction at the head of the diamondprivate boolean generateBooleanCompare(IR ir, BasicBlock bb, Instruction cb, BasicBlock tb)
1) IF .. GOTO A replaced by BOOLEAN_CMP x=.. x = 0 GOTO B A: x = 1 B: ...
Precondition: IfCmp.conforms(cb)
ir
- governing IRbb
- basic block of cbcb
- conditional branch instructiontb
- target block the branch instructiontrue
if and only if the transformation succeeds