use of org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand in project JikesRVM by JikesRVM.
the class LoopUnrolling method unrollLeaf.
boolean unrollLeaf(LSTNode t, IR ir) {
int instructionsInLoop = 0;
BasicBlock exitBlock = null, backEdgeBlock = null, succBlock = null, predBlock = null;
BitVector nloop = t.getLoop();
BasicBlock header = t.header;
Instruction tmp;
if (ir.hasReachableExceptionHandlers()) {
report("0 IR may have exception handlers");
return false;
}
// determine loop structure by looking at its blocks
Enumeration<BasicBlock> loopBlocks = ir.getBasicBlocks(nloop);
int blocks = 0;
while (loopBlocks.hasMoreElements()) {
BasicBlock b = loopBlocks.nextElement();
blocks++;
// check for size
instructionsInLoop += b.getNumberOfRealInstructions();
if (instructionsInLoop > MaxInstructions) {
report("1 is too big");
return false;
}
// look at the in edges. We want the header to be the only
// block with out of loop incoming edges.
Enumeration<BasicBlock> e = b.getIn();
if (b != header) {
while (e.hasMoreElements()) {
BasicBlock o = e.nextElement();
if (!CFGTransformations.inLoop(o, nloop)) {
report("2 interior pointers.");
return true;
}
}
} else {
// check the headers predecessors: there should be
// one out of loop input and one backedge.
// We can extend this for loops with several backedges,
// if they all have the same conditions.
int inEdges = 0;
while (e.hasMoreElements()) {
inEdges++;
BasicBlock o = e.nextElement();
if (!CFGTransformations.inLoop(o, nloop)) {
if (predBlock == null) {
predBlock = o;
} else {
report("3 multi entry header.");
return true;
}
} else {
if (backEdgeBlock == null) {
backEdgeBlock = o;
} else {
report("4 multiple back edges.");
return true;
}
}
}
}
// look at the out edges to find loop exits
e = b.getOut();
while (e.hasMoreElements()) {
BasicBlock out = e.nextElement();
if (!CFGTransformations.inLoop(out, nloop)) {
if (exitBlock == null) {
exitBlock = b;
} else {
report("5 multiple exit blocks.");
return true;
}
}
}
}
// exitBlock must equal backEdgeBlock
if (exitBlock == null) {
report("6 no exit block found...infinite loop?");
return true;
}
if (exitBlock != backEdgeBlock) {
report("7 exit block is not immediate predecessor of loop head");
return true;
}
// exitBlock must exit (skip over pads in critical edges)
while (exitBlock.getNumberOfOut() == 1 && exitBlock.getNumberOfIn() == 1) {
exitBlock = exitBlock.getIn().nextElement();
}
if (exitBlock == header && blocks > 1) {
report("6 while loop? (" + blocks + ")");
return true;
}
// So far, so good. Examine the exit test.
Instruction origBranch = exitBlock.firstBranchInstruction();
if (origBranch != exitBlock.lastRealInstruction()) {
Instruction aGoto = origBranch.nextInstructionInCodeOrder();
if (aGoto.getOpcode() != GOTO_opcode) {
report("7 too complex exit");
return true;
}
succBlock = Label.getBlock(Goto.getTarget(aGoto).target).block;
if (VM.VerifyAssertions) {
VM._assert(aGoto == exitBlock.lastRealInstruction());
}
} else {
succBlock = exitBlock.getFallThroughBlock();
}
if (origBranch.getOpcode() != INT_IFCMP_opcode) {
report("8 branch isn't int_ifcmp: " + origBranch.operator() + ".");
return true;
}
// examine operands:
Operand op1 = follow(IfCmp.getVal1(origBranch));
Operand op2 = follow(IfCmp.getVal2(origBranch));
ConditionOperand cond = (ConditionOperand) IfCmp.getCond(origBranch).copy();
RegisterOperand ifcmpGuard = IfCmp.getGuardResult(origBranch);
float backBranchProbability = IfCmp.getBranchProfile(origBranch).takenProbability;
if (!loopInvariant(op2, nloop, 4)) {
if (loopInvariant(op1, nloop, 4)) {
Operand op = op1;
op1 = op2;
op2 = op;
cond.flipOperands();
} else {
if (DEBUG) {
printDefs(op1, nloop, 4);
printDefs(op2, nloop, 4);
VM.sysWriteln(origBranch.toString());
}
report("8a op1 and op2 may not be loop invariant");
return true;
}
}
BasicBlock target = Label.getBlock(IfCmp.getTarget(origBranch).target).block;
if (!(op1 instanceof RegisterOperand)) {
report("9 op1 of ifcmp isn't a register");
return true;
}
RegisterOperand rop1 = (RegisterOperand) op1;
Register reg = rop1.getRegister();
if (reg.isPhysical()) {
report("10 loops over physical register");
return false;
}
if (succBlock == header && !CFGTransformations.inLoop(target, nloop)) {
succBlock = target;
target = header;
cond.flipCode();
}
if (target != header) {
report("11 ifcmp doesn't jump to header");
return true;
}
Instruction iterator = null;
Enumeration<Operand> defs = new RealDefs(rop1);
while (defs.hasMoreElements()) {
Operand def = defs.nextElement();
Instruction inst = def.instruction;
BasicBlock block = inst.getBasicBlock();
// VM.sysWriteln(block + ": " + inst);
if (CFGTransformations.inLoop(block, nloop)) {
if (iterator == null) {
iterator = inst;
} else {
report("12 iterator not unique.");
return true;
}
}
}
if (iterator == null) {
report("15 iterator not found.");
return true;
}
if (iterator.getOpcode() != INT_ADD_opcode) {
// dumpIR (ir, "malformed");
report("16 iterator is no addition: " + iterator.operator());
return true;
}
if (!rop1.similar(follow(Binary.getVal1(iterator)))) {
// dumpIR (ir, "malformed");
report("17 malformed iterator.\n" + iterator);
return true;
}
Operand strideOp = follow(Binary.getVal2(iterator));
if (!(strideOp instanceof IntConstantOperand)) {
report("18 stride not constant");
return true;
}
int stride = ((IntConstantOperand) strideOp).value;
if (stride != 1 && stride != -1) {
report("18b stride != +/-1 (" + stride + ")");
return true;
}
if ((stride == 1 && ((cond.value != ConditionOperand.LESS) && cond.value != ConditionOperand.LESS_EQUAL && cond.value != ConditionOperand.NOT_EQUAL)) || (stride == -1 && ((cond.value != ConditionOperand.GREATER) && cond.value != ConditionOperand.GREATER_EQUAL && cond.value != ConditionOperand.NOT_EQUAL))) {
report("19 unexpected condition: " + cond + "\n" + iterator + "\n" + origBranch);
return true;
}
RegisterOperand outerGuard;
BasicBlock outer = predBlock;
while (outer.getNumberOfOut() == 1 && outer.getNumberOfIn() == 1) {
outer = outer.getIn().nextElement();
}
if (outer.getNumberOfIn() > 0 && outer.getNumberOfOut() < 2) {
report("23 no suitable outer guard found.");
return true;
}
tmp = outer.firstBranchInstruction();
if (tmp != null && GuardResultCarrier.conforms(tmp)) {
outerGuard = GuardResultCarrier.getGuardResult(tmp);
} else {
outerGuard = ir.regpool.makeTempValidation();
}
// //////////
// transfom
// transform this:
//
// Orig:
// B
// if i CC b goto Orig
// else goto exit
//
// exit:
//
// into this:
//
//
// stride == 1: common: stride == -1:
// --------------------------------------------------------------------------
// guard0:
// limit = b;
// if a > b goto Orig if b > a goto Orig
// else guard1
//
//
// guard 1:
// remainder = b - a; remainder = a - b;
// if cond == '<=' if cond == '>='
// remainder++; remainder++;
// remainder = remainder & 3
// limit = a + remainder limit = a - remainder
// if cond == '<=' if cond == '>='
// limit--; limit++;
// if remainder == 0 goto mllp
// goto Orig
//
// Orig:
// LOOP;
// if i CC limit goto Orig
// else guard2
//
// guard2: if i CC b goto mllp
// else exit
//
// mllp: // landing pad
// goto ml
//
// ml:
// LOOP;LOOP;LOOP;LOOP;
// if i CC b goto ml
// else exit
//
// exit:
// --------------------------------------------------------------------------
report("...transforming.");
if (DEBUG && ir.options.hasMETHOD_TO_PRINT() && ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) {
dumpIR(ir, "before unroll");
}
CFGTransformations.killFallThroughs(ir, nloop);
BasicBlock[] handles = makeSomeCopies(unrollFactor, ir, nloop, blocks, header, exitBlock, exitBlock);
BasicBlock mainHeader = handles[0];
BasicBlock mainExit = handles[1];
// test block for well formed bounds
BasicBlock guardBlock0 = header.createSubBlock(header.firstInstruction().getBytecodeIndex(), ir);
predBlock.redirectOuts(header, guardBlock0, ir);
// test block for iteration alignemnt
BasicBlock guardBlock1 = header.createSubBlock(header.firstInstruction().getBytecodeIndex(), ir);
// landing pad for orig loop
BasicBlock olp = header.createSubBlock(header.firstInstruction().getBytecodeIndex(), ir);
olp.setLandingPad();
BasicBlock predSucc = predBlock.nextBasicBlockInCodeOrder();
if (predSucc != null) {
ir.cfg.breakCodeOrder(predBlock, predSucc);
ir.cfg.linkInCodeOrder(olp, predSucc);
}
ir.cfg.linkInCodeOrder(predBlock, guardBlock0);
ir.cfg.linkInCodeOrder(guardBlock0, guardBlock1);
ir.cfg.linkInCodeOrder(guardBlock1, olp);
// guard block for main loop
BasicBlock guardBlock2 = header.createSubBlock(header.firstInstruction().getBytecodeIndex(), ir);
// landing pad for main loop
BasicBlock landingPad = header.createSubBlock(header.firstInstruction().getBytecodeIndex(), ir);
landingPad.setLandingPad();
BasicBlock mainLoop = exitBlock.nextBasicBlockInCodeOrder();
ir.cfg.breakCodeOrder(exitBlock, mainLoop);
ir.cfg.linkInCodeOrder(exitBlock, guardBlock2);
ir.cfg.linkInCodeOrder(guardBlock2, landingPad);
ir.cfg.linkInCodeOrder(landingPad, mainLoop);
RegisterOperand remainder = ir.regpool.makeTemp(rop1.getType());
RegisterOperand limit = ir.regpool.makeTemp(rop1.getType());
// test whether a <= b for stride == 1 and a >= b for stride == -1
tmp = guardBlock0.lastInstruction();
tmp.insertBefore(Move.create(INT_MOVE, limit, op2.copy()));
ConditionOperand g0cond = ConditionOperand.GREATER_EQUAL();
if (stride == -1)
g0cond = ConditionOperand.LESS_EQUAL();
tmp.insertBefore(IfCmp.create(INT_IFCMP, outerGuard.copyD2D(), rop1.copyD2U(), op2.copy(), g0cond, olp.makeJumpTarget(), BranchProfileOperand.unlikely()));
tmp.insertBefore(Goto.create(GOTO, guardBlock1.makeJumpTarget()));
// align the loop iterations
tmp = guardBlock1.lastInstruction();
if (stride == 1) {
tmp.insertBefore(Binary.create(INT_SUB, remainder, op2.copy(), rop1.copyD2U()));
} else {
tmp.insertBefore(Binary.create(INT_SUB, remainder, rop1.copyD2U(), op2.copy()));
}
if (cond.isGREATER_EQUAL() || cond.isLESS_EQUAL()) {
tmp.insertBefore(Binary.create(INT_ADD, remainder.copyD2D(), remainder.copyD2U(), new IntConstantOperand(1)));
}
tmp.insertBefore(Binary.create(INT_ADD, remainder.copyD2D(), remainder.copyD2U(), new IntConstantOperand(-1)));
tmp.insertBefore(Binary.create(INT_AND, remainder.copyD2D(), remainder.copyD2U(), new IntConstantOperand(unrollFactor - 1)));
tmp.insertBefore(Binary.create(INT_ADD, remainder.copyD2D(), remainder.copyD2U(), new IntConstantOperand(1)));
if (stride == 1) {
tmp.insertBefore(Binary.create(INT_ADD, limit.copyD2U(), op1.copy(), remainder.copyD2U()));
} else {
tmp.insertBefore(Binary.create(INT_SUB, limit.copyD2U(), op1.copy(), remainder.copyD2U()));
}
if (cond.isLESS_EQUAL()) {
tmp.insertBefore(Binary.create(INT_ADD, limit.copyD2D(), limit.copyD2U(), new IntConstantOperand(-1)));
}
if (cond.isGREATER_EQUAL()) {
tmp.insertBefore(Binary.create(INT_ADD, limit.copyD2D(), limit.copyD2U(), new IntConstantOperand(1)));
}
tmp.insertBefore(Goto.create(GOTO, olp.makeJumpTarget()));
// build landing pad for original loop
tmp = olp.lastInstruction();
tmp.insertBefore(Goto.create(GOTO, header.makeJumpTarget()));
// change the back branch in the original loop
deleteBranches(exitBlock);
tmp = exitBlock.lastInstruction();
tmp.insertBefore(IfCmp.create(INT_IFCMP, outerGuard.copyD2D(), rop1.copyU2U(), limit.copyD2U(), (ConditionOperand) cond.copy(), header.makeJumpTarget(), new BranchProfileOperand(1.0f - 1.0f / (unrollFactor / 2))));
tmp.insertBefore(Goto.create(GOTO, guardBlock2.makeJumpTarget()));
// only enter main loop if iterations left
tmp = guardBlock2.lastInstruction();
tmp.insertBefore(IfCmp.create(INT_IFCMP, outerGuard.copyD2D(), rop1.copyU2U(), op2.copy(), (ConditionOperand) cond.copy(), landingPad.makeJumpTarget(), new BranchProfileOperand(backBranchProbability)));
tmp.insertBefore(Goto.create(GOTO, succBlock.makeJumpTarget()));
// landing pad jumps to mainHeader
tmp = landingPad.lastInstruction();
tmp.insertBefore(Goto.create(GOTO, mainHeader.makeJumpTarget()));
// repair back edge in mainExit
if (VM.VerifyAssertions)
VM._assert(mainExit != null);
tmp = mainExit.lastInstruction();
if (VM.VerifyAssertions) {
VM._assert((mainExit.lastRealInstruction() == null) || !mainExit.lastRealInstruction().isBranch());
}
tmp.insertBefore(IfCmp.create(INT_IFCMP, ifcmpGuard.copyU2U(), rop1.copyU2U(), op2.copy(), (ConditionOperand) cond.copy(), mainHeader.makeJumpTarget(), new BranchProfileOperand(1.0f - (1.0f - backBranchProbability) * unrollFactor)));
tmp.insertBefore(Goto.create(GOTO, succBlock.makeJumpTarget()));
// recompute normal outs
guardBlock0.recomputeNormalOut(ir);
guardBlock1.recomputeNormalOut(ir);
olp.recomputeNormalOut(ir);
guardBlock2.recomputeNormalOut(ir);
exitBlock.recomputeNormalOut(ir);
landingPad.recomputeNormalOut(ir);
mainExit.recomputeNormalOut(ir);
if (DEBUG && ir.options.hasMETHOD_TO_PRINT() && ir.options.fuzzyMatchMETHOD_TO_PRINT(ir.method.toString())) {
dumpIR(ir, "after unroll");
}
return false;
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method boolean_cmp.
private static void boolean_cmp(Instruction s, IR ir, boolean cmp32Bit) {
// undo the optimization because it cannot efficiently be generated
Register res = BooleanCmp.getClearResult(s).getRegister();
RegisterOperand one = (RegisterOperand) BooleanCmp.getClearVal1(s);
Operand two = BooleanCmp.getClearVal2(s);
ConditionOperand cond = BooleanCmp.getClearCond(s);
res.setSpansBasicBlock();
BasicBlock BB1 = s.getBasicBlock();
BasicBlock BB4 = BB1.splitNodeAt(s, ir);
s = s.remove();
BasicBlock BB2 = BB1.createSubBlock(0, ir);
BasicBlock BB3 = BB1.createSubBlock(0, ir);
RegisterOperand t = ir.regpool.makeTempInt();
t.getRegister().setCondition();
Operator op;
if (VM.BuildFor64Addr && !cmp32Bit) {
if (two instanceof IntConstantOperand) {
op = cond.isUNSIGNED() ? PPC64_CMPLI : PPC64_CMPI;
} else {
op = cond.isUNSIGNED() ? PPC64_CMPL : PPC64_CMP;
}
} else if (two instanceof IntConstantOperand) {
op = cond.isUNSIGNED() ? PPC_CMPLI : PPC_CMPI;
} else {
op = cond.isUNSIGNED() ? PPC_CMPL : PPC_CMP;
}
BB1.appendInstruction(MIR_Binary.create(op, t, one, two));
BB1.appendInstruction(MIR_CondBranch.create(PPC_BCOND, t.copyD2U(), PowerPCConditionOperand.get(cond), BB3.makeJumpTarget(), new BranchProfileOperand()));
BB2.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(0)));
BB2.appendInstruction(MIR_Branch.create(PPC_B, BB4.makeJumpTarget()));
BB3.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(1)));
// fix CFG
BB1.insertOut(BB2);
BB1.insertOut(BB3);
BB2.insertOut(BB4);
BB3.insertOut(BB4);
ir.cfg.linkInCodeOrder(BB1, BB2);
ir.cfg.linkInCodeOrder(BB2, BB3);
ir.cfg.linkInCodeOrder(BB3, BB4);
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method threeValueCmp.
/**
* compare to values and set result to -1, 0, 1 for <, =, >, respectively
* @param s the compare instruction
* @param ir the governing IR
*/
private static void threeValueCmp(Instruction s, IR ir) {
PowerPCConditionOperand firstCond = PowerPCConditionOperand.LESS_EQUAL();
int firstConst = 1;
switch(s.getOpcode()) {
case DOUBLE_CMPG_opcode:
case FLOAT_CMPG_opcode:
firstCond = PowerPCConditionOperand.GREATER_EQUAL();
firstConst = -1;
break;
case DOUBLE_CMPL_opcode:
case FLOAT_CMPL_opcode:
break;
default:
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
break;
}
Register res = Binary.getClearResult(s).getRegister();
RegisterOperand one = (RegisterOperand) Binary.getClearVal1(s);
RegisterOperand two = (RegisterOperand) Binary.getClearVal2(s);
res.setSpansBasicBlock();
BasicBlock BB1 = s.getBasicBlock();
BasicBlock BB6 = BB1.splitNodeAt(s, ir);
s = s.remove();
BasicBlock BB2 = BB1.createSubBlock(0, ir);
BasicBlock BB3 = BB1.createSubBlock(0, ir);
BasicBlock BB4 = BB1.createSubBlock(0, ir);
BasicBlock BB5 = BB1.createSubBlock(0, ir);
RegisterOperand t = ir.regpool.makeTempInt();
t.getRegister().setCondition();
BB1.appendInstruction(MIR_Binary.create(PPC_FCMPU, t, one, two));
BB1.appendInstruction(MIR_CondBranch.create(PPC_BCOND, t.copyD2U(), firstCond, BB3.makeJumpTarget(), new BranchProfileOperand(0.5f)));
BB2.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(firstConst)));
BB2.appendInstruction(MIR_Branch.create(PPC_B, BB6.makeJumpTarget()));
BB3.appendInstruction(MIR_CondBranch.create(PPC_BCOND, t.copyD2U(), PowerPCConditionOperand.EQUAL(), BB5.makeJumpTarget(), BranchProfileOperand.unlikely()));
BB4.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(-firstConst)));
BB4.appendInstruction(MIR_Branch.create(PPC_B, BB6.makeJumpTarget()));
BB5.appendInstruction(MIR_Unary.create(PPC_LDI, I(res), IC(0)));
// fix CFG
BB1.insertOut(BB2);
BB1.insertOut(BB3);
BB2.insertOut(BB6);
BB3.insertOut(BB4);
BB3.insertOut(BB5);
BB4.insertOut(BB6);
BB5.insertOut(BB6);
ir.cfg.linkInCodeOrder(BB1, BB2);
ir.cfg.linkInCodeOrder(BB2, BB3);
ir.cfg.linkInCodeOrder(BB3, BB4);
ir.cfg.linkInCodeOrder(BB4, BB5);
ir.cfg.linkInCodeOrder(BB5, BB6);
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method attempt.
private static void attempt(Instruction s, IR ir, boolean isAddress, boolean isLong) {
BasicBlock BB1 = s.getBasicBlock();
BasicBlock BB4 = BB1.splitNodeAt(s, ir);
BasicBlock BB2 = BB1.createSubBlock(0, ir);
BasicBlock BB3 = BB2.createSubBlock(0, ir);
BB1.insertOut(BB2);
BB1.insertOut(BB3);
BB2.insertOut(BB4);
BB3.insertOut(BB4);
ir.cfg.linkInCodeOrder(BB1, BB2);
ir.cfg.linkInCodeOrder(BB2, BB3);
ir.cfg.linkInCodeOrder(BB3, BB4);
// mutate ATTEMPT into a STWCX
RegisterOperand newValue = (RegisterOperand) Attempt.getNewValue(s);
RegisterOperand address = (RegisterOperand) Attempt.getAddress(s);
Operand offset = Attempt.getOffset(s);
LocationOperand location = Attempt.getLocation(s);
Operand guard = Attempt.getGuard(s);
RegisterOperand result = Attempt.getResult(s);
MIR_Store.mutate(s, (isAddress || isLong ? PPC_STAddrCXr : PPC_STWCXr), newValue, address, offset, location, guard);
// Branch to BB3 iff the STWXC succeeds (CR(0) is EQUAL)
// Else fall through to BB2
PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
BB1.appendInstruction(MIR_CondBranch.create(PPC_BCOND, I(phys.getConditionRegister(0)), PowerPCConditionOperand.EQUAL(), BB3.makeJumpTarget(), new BranchProfileOperand()));
// BB2 sets result to FALSE and jumps to BB4
BB2.appendInstruction(MIR_Unary.create(PPC_LDI, result.copyRO(), IC(0)));
BB2.appendInstruction(MIR_Branch.create(PPC_B, BB4.makeJumpTarget()));
// BB3 sets result to TRUE and falls through to BB4
BB3.appendInstruction(MIR_Unary.create(PPC_LDI, result.copyRO(), IC(1)));
}
use of org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand in project JikesRVM by JikesRVM.
the class ComplexLIR2MIRExpansion method get_time_base.
private static void get_time_base(Instruction s, IR ir) {
if (VM.BuildFor32Addr) {
BasicBlock BB1 = s.getBasicBlock();
BB1 = BB1.segregateInstruction(s, ir);
Register defHigh = Nullary.getResult(s).getRegister();
Register defLow = ir.regpool.getSecondReg(defHigh);
Register t0 = ir.regpool.getInteger();
Register cr = ir.regpool.getCondition();
defLow.setSpansBasicBlock();
defHigh.setSpansBasicBlock();
// Try to get the base
Register TU = ir.regpool.getPhysicalRegisterSet().asPPC().getTU();
Register TL = ir.regpool.getPhysicalRegisterSet().asPPC().getTL();
s.insertBefore(MIR_Move.create(PPC_MFTBU, I(defHigh), I(TU)));
s.insertBefore(MIR_Move.create(PPC_MFTB, I(defLow), I(TL)));
// Try again to see if it changed
s.insertBefore(MIR_Move.create(PPC_MFTBU, I(t0), I(TU)));
s.insertBefore(MIR_Binary.create(PPC_CMP, I(cr), I(t0), I(defHigh)));
MIR_CondBranch.mutate(s, PPC_BCOND, I(cr), PowerPCConditionOperand.NOT_EQUAL(), BB1.makeJumpTarget(), new BranchProfileOperand());
// fix up CFG
BB1.insertOut(BB1);
} else {
// We read the 64-bit time base register atomically
Register def = Nullary.getResult(s).getRegister();
// See PowerPC Architecture, Book II, pp.352-353
Register TL = ir.regpool.getPhysicalRegisterSet().asPPC().getTL();
MIR_Move.mutate(s, PPC_MFTB, L(def), L(TL));
}
}
Aggregations