Search in sources :

Example 6 with IntConstantOperand

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);
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Register(org.jikesrvm.compilers.opt.ir.Register) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)

Example 7 with IntConstantOperand

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;
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)

Example 8 with IntConstantOperand

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;
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 9 with IntConstantOperand

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;
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 10 with IntConstantOperand

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));
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Test(org.junit.Test)

Aggregations

IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)49 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)41 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)28 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)23 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)21 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)21 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)19 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)18 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)17 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)16 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)16 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)15 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)15 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)15 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)14 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)13 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)12 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)11 TypeReference (org.jikesrvm.classloader.TypeReference)10 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)9