use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.
the class BranchSimplifier method processTableSwitch.
static boolean processTableSwitch(IR ir, BasicBlock bb, Instruction s) {
Operand val = TableSwitch.getValue(s);
int low = TableSwitch.getLow(s).value;
int high = TableSwitch.getHigh(s).value;
if (val.isConstant()) {
int value = ((IntConstantOperand) val).value;
BranchOperand target = TableSwitch.getDefault(s);
if (value >= low && value <= high) {
target = TableSwitch.getTarget(s, value - low);
}
Goto.mutate(s, GOTO, target);
} else if (low == high) {
// only 1 match, simplify to ifcmp
BranchOperand defaultTarget = TableSwitch.getClearDefault(s);
IfCmp.mutate(s, INT_IFCMP, ir.regpool.makeTempValidation(), val, new IntConstantOperand(low), ConditionOperand.EQUAL(), TableSwitch.getTarget(s, 0), TableSwitch.getBranchProfile(s, 0));
s.insertAfter(Goto.create(GOTO, defaultTarget));
} else {
// no optimisation, just continue
return false;
}
return true;
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.
the class Diamond method threeElementDiamond.
private static Diamond threeElementDiamond(BasicBlock top, BasicBlock side, BasicBlock bottom) {
Instruction cb = top.firstBranchInstruction();
// for now we only support IfCmp diamonds.
if (VM.VerifyAssertions)
VM._assert(IfCmp.conforms(cb));
BranchOperand takenTarget = IfCmp.getTarget(cb);
if (Label.getBlock(takenTarget.target).block == side) {
return new Diamond(top, side, null, bottom);
} else {
return new Diamond(top, null, side, bottom);
}
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.
the class MIRBranchOptimizations method flipConditionalBranch.
/**
* Flip a conditional branch and remove the trailing goto.
* See comment 3) of processCondBranch
*
* <p> Precondition isFlipCandidate(cb)
* @param cb the conditional branch instruction
*/
private void flipConditionalBranch(Instruction cb) {
// get the trailing GOTO instruction
Instruction g = cb.nextInstructionInCodeOrder();
BranchOperand gTarget = MIR_Branch_getClearTarget(g);
// now flip the test and set the new target
if (VM.BuildForIA32) {
org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch.setCond(cb, org.jikesrvm.compilers.opt.ir.ia32.MIR_CondBranch.getCond(cb).flipCode());
} else {
if (VM.VerifyAssertions)
VM._assert(VM.BuildForPowerPC);
org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch.setCond(cb, org.jikesrvm.compilers.opt.ir.ppc.MIR_CondBranch.getCond(cb).flipCode());
}
MIR_CondBranch_setTarget(cb, gTarget);
// Remove the trailing GOTO instruction
g.remove();
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.
the class MIRBranchOptimizations method processCondBranch.
/**
* Perform optimizations for a conditional branch.
*
* <pre>
* 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) IF .. GOTO A replaced by IF .. GOTO B
* A: LABEL
* BBEND
* B:
* 5) fallthrough to a goto: replicate goto to enable other optimizations.
* </pre>
*
* <p> Precondition: MIR_CondBranch.conforms(cb)
*
* @param ir the governing IR
* @param cb the instruction to optimize
* @param bb the basic block holding if
* @return {@code true} iff made a transformation
*/
private boolean processCondBranch(IR ir, Instruction cb, BasicBlock bb) {
BasicBlock targetBlock = cb.getBranchTarget();
Instruction targetLabel = targetBlock.firstInstruction();
// get the first real instruction at the branch target
// NOTE: this instruction is not necessarily in targetBlock,
// iff targetBlock has no real instructions
Instruction targetInst = firstRealInstructionFollowing(targetLabel);
if (targetInst == null || targetInst == cb) {
return false;
}
boolean endsBlock = cb.nextInstructionInCodeOrder().operator() == BBEND;
if (endsBlock) {
Instruction nextLabel = firstLabelFollowing(cb);
if (targetLabel == nextLabel) {
// found a conditional branch to the next instruction. just remove it.
cb.remove();
return true;
}
Instruction nextI = firstRealInstructionFollowing(nextLabel);
if (nextI != null && isMIR_Branch(nextI)) {
// replicate Goto
cb.insertAfter(nextI.copyWithoutLinks());
// fix the CFG
bb.recomputeNormalOut(ir);
return true;
}
}
if (isMIR_Branch(targetInst)) {
// conditional branch to unconditional branch.
// change conditional branch target to latter's target
Instruction target2 = firstRealInstructionFollowing(targetInst.getBranchTarget().firstInstruction());
if (target2 == targetInst) {
// This happens in GCUtil in some systems due to a while(true) {}
return false;
}
MIR_CondBranch_setTarget(cb, (BranchOperand) MIR_Branch_getTarget(targetInst).copy());
// fix the CFG
bb.recomputeNormalOut(ir);
return true;
}
if (targetBlock.isEmpty()) {
// branch to an empty block. Change target to the next block.
BasicBlock nextBlock = targetBlock.getFallThroughBlock();
BranchOperand newTarget = nextBlock.makeJumpTarget();
MIR_CondBranch_setTarget(cb, newTarget);
// fix the CFG
bb.recomputeNormalOut(ir);
return true;
}
if (isFlipCandidate(cb, targetInst)) {
flipConditionalBranch(cb);
// fix the CFG
bb.recomputeNormalOut(ir);
return true;
}
return false;
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchOperand in project JikesRVM by JikesRVM.
the class InstrumentationSamplingFramework method createCheck.
/**
* Append a check to a basic block, and make it jump to the right places.
*
* @param checkBB The block to append the CBS check to.
* @param noInstBB The basic block to jump to if the CBS check fails
* @param instBB The basicBlock to jump to if the CBS check succeeds
* @param fallthroughToInstBB Should checkBB fallthrough to instBB
* (otherwise it must fallthrough to noInstBB)
* @param ir the IR that contains the blocks
*/
private void createCheck(BasicBlock checkBB, BasicBlock noInstBB, BasicBlock instBB, boolean fallthroughToInstBB, IR ir) {
appendLoad(checkBB, ir);
// Depending on where you fallthrough, set the condition correctly
ConditionOperand cond = null;
BranchOperand target = null;
BranchProfileOperand profileOperand = null;
if (fallthroughToInstBB) {
// The instrumented basic block is the fallthrough of checkBB,
// so make the branch jump to the non-instrumented block.
cond = ConditionOperand.GREATER();
target = noInstBB.makeJumpTarget();
// Taken frequently
profileOperand = new BranchProfileOperand(1.0f);
} else {
// The non-instrumented basic block is the fallthrough of checkBB,
// so make the branch jump to the instrumented block.
cond = ConditionOperand.LESS_EQUAL();
target = instBB.makeJumpTarget();
// Taken infrequently
profileOperand = new BranchProfileOperand(0.0f);
}
RegisterOperand guard = ir.regpool.makeTempValidation();
checkBB.appendInstruction(IfCmp.create(INT_IFCMP, guard, cbsReg.copyRO(), new IntConstantOperand(0), cond, target, profileOperand));
checkBB.recomputeNormalOut(ir);
// Insert the decrement and store in the block that is the
// successor of the check
prependStore(noInstBB, ir);
prependDecrement(noInstBB, ir);
// Insert a counter reset in the duplicated block.
prependCounterReset(instBB, ir);
}
Aggregations