use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand 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.IntConstantOperand in project JikesRVM by JikesRVM.
the class NormalizeConstants method asImmediateOrRegOffset.
static Operand asImmediateOrRegOffset(Operand addr, Instruction s, IR ir, boolean signed) {
if (addr instanceof AddressConstantOperand) {
if (!canBeImmediate(((AddressConstantOperand) addr).value, signed)) {
RegisterOperand rop = ir.regpool.makeTempOffset();
s.insertBefore(Move.create(REF_MOVE, rop, addr));
return rop.copyD2U();
} else {
// can be immediate --> convert to int
return new IntConstantOperand(((AddressConstantOperand) addr).value.toInt());
}
} else if (addr instanceof ConstantOperand) {
// must not happen, because is 64-bit unsafe
if (VM.VerifyAssertions)
VM._assert(VM.NOT_REACHED);
}
// Operand was OK as is.
return addr;
}
use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class LoopVersioning method createBranchBlocks.
/*
* TODO better JavaDoc comment.
* <p>
* Create the block containing explict branches to either the
* optimized or unoptimized loops
* @param optimalRegMap - mapping used to map eliminated bound and
* null check guards to
*/
private boolean createBranchBlocks(AnnotatedLSTNode loop, BasicBlock block, ArrayList<Instruction> checksToEliminate, BasicBlock unoptimizedLoopEntry, BasicBlock optimizedLoopEntry, HashMap<Register, Register> optimalRegMap) {
BasicBlock blockOnEntry = block;
// 1) generate null check guards
block = generateNullCheckBranchBlocks(loop, checksToEliminate, optimalRegMap, block, unoptimizedLoopEntry);
// 2) generate bound check guards
if (loop.isMonotonic()) {
// create new operands for values beyond initial and terminal iterator values
Operand terminal;
Operand terminalLessStrideOnce;
Operand terminalPlusStrideOnce;
// it does create dead code though
if (loop.terminalIteratorValue.isIntConstant()) {
terminal = loop.terminalIteratorValue;
int terminalAsInt = terminal.asIntConstant().value;
int stride = loop.strideValue.asIntConstant().value;
terminalLessStrideOnce = new IntConstantOperand(terminalAsInt - stride);
terminalPlusStrideOnce = new IntConstantOperand(terminalAsInt + stride);
} else {
Instruction tempInstr;
terminal = loop.generateLoopInvariantOperand(block, loop.terminalIteratorValue);
terminalLessStrideOnce = ir.regpool.makeTempInt();
terminalPlusStrideOnce = ir.regpool.makeTempInt();
tempInstr = Binary.create(INT_SUB, terminalLessStrideOnce.asRegister(), terminal.copy(), loop.strideValue.copy());
tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
block.appendInstruction(tempInstr);
DefUse.updateDUForNewInstruction(tempInstr);
tempInstr = Binary.create(INT_ADD, terminalPlusStrideOnce.asRegister(), terminal.copy(), loop.strideValue.copy());
tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
block.appendInstruction(tempInstr);
DefUse.updateDUForNewInstruction(tempInstr);
}
// Determine maximum and minimum index values for different loop types
Operand phiMinIndexValue;
Operand phiMaxIndexValue;
if (loop.isMonotonicIncreasing()) {
phiMinIndexValue = loop.initialIteratorValue;
if ((loop.condition.isLESS() || loop.condition.isLOWER() || loop.condition.isNOT_EQUAL())) {
phiMaxIndexValue = terminal;
} else if ((loop.condition.isLESS_EQUAL() || loop.condition.isLOWER_EQUAL() || loop.condition.isEQUAL())) {
phiMaxIndexValue = terminalPlusStrideOnce;
} else {
throw new Error("Unrecognised loop for fission " + loop);
}
} else if (loop.isMonotonicDecreasing()) {
phiMaxIndexValue = loop.initialIteratorValue;
if ((loop.condition.isGREATER() || loop.condition.isHIGHER() || loop.condition.isNOT_EQUAL())) {
phiMinIndexValue = terminalPlusStrideOnce;
} else if ((loop.condition.isGREATER_EQUAL() || loop.condition.isHIGHER_EQUAL() || loop.condition.isEQUAL())) {
phiMinIndexValue = terminalLessStrideOnce;
} else {
throw new Error("Unrecognised loop for fission " + loop);
}
} else {
throw new Error("Unrecognised loop for fission " + loop);
}
// Generate tests
for (int i = 0; i < checksToEliminate.size(); i++) {
Instruction instr = checksToEliminate.get(i);
if (BoundsCheck.conforms(instr)) {
// Have we already generated these tests?
boolean alreadyChecked = false;
for (int j = 0; j < i; j++) {
Instruction old_instr = checksToEliminate.get(j);
if (BoundsCheck.conforms(old_instr) && (BoundsCheck.getRef(old_instr).similar(BoundsCheck.getRef(instr))) && (BoundsCheck.getIndex(old_instr).similar(BoundsCheck.getIndex(instr)))) {
// yes - just create a guard move
alreadyChecked = true;
RegisterOperand guardResult = BoundsCheck.getGuardResult(instr).copyRO();
guardResult.setRegister(optimalRegMap.get(guardResult.getRegister()));
RegisterOperand guardSource = BoundsCheck.getGuardResult(old_instr).copyRO();
guardSource.setRegister(optimalRegMap.get(guardSource.getRegister()));
Instruction tempInstr = Move.create(GUARD_MOVE, guardResult, guardSource);
tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
block.appendInstruction(tempInstr);
break;
}
}
if (!alreadyChecked) {
// no - generate tests
Operand index = BoundsCheck.getIndex(instr);
int distance = loop.getFixedDistanceFromPhiIterator(index);
if (distance == 0) {
block = generateExplicitBoundCheck(instr, phiMinIndexValue, phiMaxIndexValue, optimalRegMap, block, unoptimizedLoopEntry);
} else {
Instruction tempInstr;
RegisterOperand minIndex = ir.regpool.makeTempInt();
RegisterOperand maxIndex = ir.regpool.makeTempInt();
tempInstr = Binary.create(INT_ADD, minIndex, phiMinIndexValue.copy(), new IntConstantOperand(distance));
tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
block.appendInstruction(tempInstr);
DefUse.updateDUForNewInstruction(tempInstr);
tempInstr = Binary.create(INT_ADD, maxIndex, phiMaxIndexValue.copy(), new IntConstantOperand(distance));
tempInstr.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
block.appendInstruction(tempInstr);
DefUse.updateDUForNewInstruction(tempInstr);
block = generateExplicitBoundCheck(instr, minIndex, maxIndex, optimalRegMap, block, unoptimizedLoopEntry);
}
}
}
}
}
// Have we had to create a new basic block since entry => we
// generated a branch to the unoptimized loop
boolean isUnoptimizedLoopReachable = (blockOnEntry != block);
// 3) Finish up with goto and generate true guard value
{
// the generated branch instruction
Instruction branch;
branch = Goto.create(GOTO, optimizedLoopEntry.makeJumpTarget());
branch.setBytecodeIndex(SYNTH_LOOP_VERSIONING_BCI);
block.appendInstruction(branch);
block.deleteNormalOut();
block.insertOut(optimizedLoopEntry);
}
return isUnoptimizedLoopReachable;
}
use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class CounterArrayManager method createEventCounterInstruction.
/**
* Create a place holder instruction to represent the counted event.
*
* @param handle The handle of the array for the method
* @param index Index within that array
* @param incrementValue The value to add to the counter
* @return The counter instruction
*/
@Override
public Instruction createEventCounterInstruction(int handle, int index, double incrementValue) {
// Now create the instruction to be returned.
Instruction c = InstrumentedCounter.create(INSTRUMENTED_EVENT_COUNTER, new IntConstantOperand(handle), new IntConstantOperand(index), new DoubleConstantOperand(incrementValue, Offset.zero()));
c.setBytecodeIndex(INSTRUMENTATION_BCI);
return c;
}
use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand in project JikesRVM by JikesRVM.
the class OperandStackTest method deepCopyCopiesAllOperandsInAStack.
@Test
public void deepCopyCopiesAllOperandsInAStack() throws Exception {
createOperandStackWithSize(3);
IntConstantOperand bottom = new IntConstantOperand(-2);
stack.push(bottom);
TrueGuardOperand top = new TrueGuardOperand();
stack.push(top);
OperandStack copy = stack.deepCopy();
assertThat(copy.getSize(), is(stack.getSize()));
TrueGuardOperand topFromCopiedStack = (TrueGuardOperand) copy.getFromTop(0);
assertThat(topFromCopiedStack, not(sameInstance(top)));
assertThat(copy.getFromTop(0).similar(top), is(true));
IntConstantOperand bottomFromCopiedStack = (IntConstantOperand) copy.getFromTop(1);
assertThat(bottomFromCopiedStack, not(sameInstance(bottom)));
assertThat(copy.getFromTop(1).similar(bottom), is(true));
}
Aggregations