Search in sources :

Example 11 with MemoryOperand

use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.

the class StackManagerTest method instructionsWithMemoryOperandsAlwaysNeedScratch.

@Test
public void instructionsWithMemoryOperandsAlwaysNeedScratch() {
    RegisterOperand result = new RegisterOperand(createRegister(), TypeReference.Int);
    MemoryOperand value = MemoryOperand.B(new RegisterOperand(createRegister(), TypeReference.Int), (byte) 4, null, null);
    Instruction scratchFreeMove = MIR_Move.create(IA32_MOV, result, value);
    assertTrue(stackManager.needScratch(result.getRegister(), scratchFreeMove));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Test(org.junit.Test)

Example 12 with MemoryOperand

use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.

the class BURS_Helpers method FPR_2INT.

/**
 * Expansion of FLOAT_2INT and DOUBLE_2INT, using the FIST instruction. This
 * expansion does some boolean logic and conditional moves in order to avoid
 * changing the floating-point rounding mode or inserting branches. Other
 * expansions are possible, and may be better?
 *
 * @param s the instruction to expand
 * @param result the result operand
 * @param value the second operand
 */
protected final void FPR_2INT(Instruction s, RegisterOperand result, Operand value) {
    MemoryOperand M;
    // and in 'strict' IEEE mode.
    if (value instanceof MemoryOperand) {
        // value is in memory, all we have to do is load it
        EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), value)));
    } else {
        // we must have a store/load sequence to cause IEEE rounding.
        if (value instanceof BURSManagedFPROperand) {
            if (VM.VerifyAssertions) {
                opt_assert(value.similar(myFP0()));
            }
            EMIT(CPOS(s, MIR_Move.create(IA32_FSTP, MO_CONV(DW), value)));
            EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), MO_CONV(DW))));
        } else {
            EMIT(CPOS(s, MIR_Move.create(IA32_FMOV, MO_CONV(DW), value)));
            EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), MO_CONV(DW))));
        }
    }
    // FP Stack: myFP0 = value
    EMIT(CPOS(s, MIR_Move.create(IA32_FIST, MO_CONV(DW), myFP0())));
    // MO_CONV now holds myFP0 converted to an integer (round-toward nearest)
    // FP Stack: myFP0 == value
    // isPositive == 1 iff 0.0 < value
    // isNegative == 1 iff 0.0 > value
    Register one = regpool.getInteger();
    Register isPositive = regpool.getInteger();
    Register isNegative = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(one, TypeReference.Int), IC(1))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(isPositive, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(isNegative, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_Nullary.create(IA32_FLDZ, myFP0())));
    // FP Stack: myFP0 = 0.0; myFP1 = value
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(isPositive, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LLT())));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(isNegative, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LGT())));
    EMIT(CPOS(s, MIR_Move.create(IA32_FILD, myFP0(), MO_CONV(DW))));
    // FP Stack: myFP0 = round(value), myFP1 = value
    // addee = 1 iff round(x) < x
    // subtractee = 1 iff round(x) > x
    Register addee = regpool.getInteger();
    Register subtractee = regpool.getInteger();
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(addee, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(subtractee, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(addee, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LLT())));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, new RegisterOperand(subtractee, TypeReference.Int), new RegisterOperand(one, TypeReference.Int), IA32ConditionOperand.LGT())));
    // Now a little tricky part.
    // We will add 1 iff isNegative and x > round(x)
    // We will subtract 1 iff isPositive and x < round(x)
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, new RegisterOperand(addee, TypeReference.Int), new RegisterOperand(isNegative, TypeReference.Int))));
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_AND, new RegisterOperand(subtractee, TypeReference.Int), new RegisterOperand(isPositive, TypeReference.Int))));
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, result.copy(), MO_CONV(DW))));
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_ADD, result.copy(), new RegisterOperand(addee, TypeReference.Int))));
    EMIT(CPOS(s, MIR_BinaryAcc.create(IA32_SUB, result.copy(), new RegisterOperand(subtractee, TypeReference.Int))));
    // Compare myFP0 with (double)Integer.MAX_VALUE
    M = loadFromJTOC(burs.ir, Entrypoints.maxintField.getOffset(), QW);
    EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), M)));
    // FP Stack: myFP0 = (double)Integer.MAX_VALUE; myFP1 = value
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    // If MAX_VALUE < value, then result := MAX_INT
    Register maxInt = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(maxInt, TypeReference.Int), IC(Integer.MAX_VALUE))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, result.copy(), new RegisterOperand(maxInt, TypeReference.Int), IA32ConditionOperand.LLT())));
    // Compare myFP0 with (double)Integer.MIN_VALUE
    M = MemoryOperand.D(Magic.getTocPointer().plus(Entrypoints.minintField.getOffset()), QW, null, null);
    EMIT(CPOS(s, MIR_Move.create(IA32_FLD, myFP0(), M)));
    // FP Stack: myFP0 = (double)Integer.MIN_VALUE; myFP1 = value
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP1())));
    // FP Stack: myFP0 = value
    // If MIN_VALUE > value, then result := MIN_INT
    Register minInt = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(minInt, TypeReference.Int), IC(Integer.MIN_VALUE))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, result.copy(), new RegisterOperand(minInt, TypeReference.Int), IA32ConditionOperand.LGT())));
    // Set condition flags: set PE iff myFP0 is a NaN
    EMIT(CPOS(s, MIR_Compare.create(IA32_FCOMIP, myFP0(), myFP0())));
    // FP Stack: back to original level (all BURS managed slots freed)
    // If FP0 was classified as a NaN, then result := 0
    Register zero = regpool.getInteger();
    EMIT(CPOS(s, MIR_Move.create(IA32_MOV, new RegisterOperand(zero, TypeReference.Int), IC(0))));
    EMIT(CPOS(s, MIR_CondMove.create(IA32_CMOV, result.copy(), new RegisterOperand(zero, TypeReference.Int), IA32ConditionOperand.PE())));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand)

Example 13 with MemoryOperand

use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.

the class ComplexLIR2MIRExpansion method double_2long.

private static Instruction double_2long(Instruction s, IR ir) {
    Instruction nextInstr = s.nextInstructionInCodeOrder();
    while (Label.conforms(nextInstr) || BBend.conforms(nextInstr)) {
        nextInstr = nextInstr.nextInstructionInCodeOrder();
    }
    // we need 6 basic blocks (in code order)
    // 1: the current block that does a test to see if this is a regular f2l or
    // branches to the maxint/NaN case
    // 2: a block to perform a regular f2l
    // 3: a block to test for NaN
    // 4: a block to perform give maxint
    // 5: a block to perform NaN
    // 6: the next basic block
    BasicBlock testBB = s.getBasicBlock();
    BasicBlock nextBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, nextBB);
    BasicBlock nanBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, nanBB);
    BasicBlock maxintBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, maxintBB);
    BasicBlock nanTestBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, nanTestBB);
    BasicBlock d2lBB = testBB.splitNodeAt(s, ir);
    ir.cfg.linkInCodeOrder(testBB, d2lBB);
    // branch if they are <= or unordered.
    if (VM.BuildFor32Addr) {
        RegisterOperand resultHi = Unary.getResult(s).copyRO();
        resultHi.setType(TypeReference.Int);
        RegisterOperand resultLo = new RegisterOperand(ir.regpool.getSecondReg(resultHi.getRegister()), TypeReference.Int);
        RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
        RegisterOperand cw = ir.regpool.makeTempInt();
        MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongField.getOffset(), (byte) 8);
        RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Double);
        RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Double);
        int offset = -ir.stackManager.allocateSpaceForConversion();
        StackLocationOperand slLo = new StackLocationOperand(true, offset, 4);
        StackLocationOperand slHi = new StackLocationOperand(true, offset + 4, 4);
        StackLocationOperand sl = new StackLocationOperand(true, offset, 8);
        MemoryOperand scratchLo = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset(), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        MemoryOperand scratchHi = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset().plus(4), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_MOVSD, sl, value)));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, sl.copy())));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0.copyRO(), maxlong)));
        MIR_Compare.mutate(s, IA32_FUCOMIP, st0.copyRO(), st1);
        testBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.LLE(), nanTestBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        testBB.insertOut(d2lBB);
        testBB.insertOut(nanTestBB);
        // Convert double to long knowing that if the value is < min long the Intel
        // unspecified result is min long
        // TODO: this would be a lot simpler and faster with SSE3's FISTTP instruction
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl.copy(), st0.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo, slLo)));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi, slHi)));
        d2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        d2lBB.insertOut(nextBB);
        // Did the compare find a NaN or a maximum integer?
        nanTestBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FSTP, st0.copyRO(), st0.copyRO())));
        nanTestBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.PE(), nanBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        nanTestBB.insertOut(nanBB);
        nanTestBB.insertOut(maxintBB);
        // Value was >= max long
        maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo.copyRO(), IC((int) Long.MAX_VALUE))));
        maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi.copyRO(), IC((int) (Long.MAX_VALUE >>> 32)))));
        maxintBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        maxintBB.insertOut(nextBB);
        // In case of NaN result is 0
        nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultLo.copyRO(), IC(0))));
        nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, resultHi.copyRO(), IC(0))));
        nanBB.insertOut(nextBB);
        return nextInstr;
    } else {
        RegisterOperand result = Unary.getResult(s).copyRO();
        RegisterOperand value = Unary.getVal(s).asRegister().copyRO();
        RegisterOperand cw = ir.regpool.makeTempInt();
        MemoryOperand maxlong = BURS_Helpers.loadFromJTOC(ir, Entrypoints.maxlongField.getOffset(), (byte) 8);
        RegisterOperand st0 = new RegisterOperand(phys(ir).getST0(), TypeReference.Double);
        RegisterOperand st1 = new RegisterOperand(phys(ir).getST1(), TypeReference.Double);
        int offset = -ir.stackManager.allocateSpaceForConversion();
        StackLocationOperand sl = new StackLocationOperand(true, offset, 8);
        MemoryOperand scratchLo = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset(), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        MemoryOperand scratchHi = new MemoryOperand(ir.regpool.makeTROp(), null, (byte) 0, Entrypoints.scratchStorageField.getOffset().plus(4), (byte) 4, new LocationOperand(Entrypoints.scratchStorageField), null);
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_MOVSD, sl, value)));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0, sl.copy())));
        s.insertBefore(CPOS(s, MIR_Move.create(IA32_FLD, st0.copyRO(), maxlong)));
        MIR_Compare.mutate(s, IA32_FUCOMIP, st0.copyRO(), st1);
        testBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.LLE(), nanTestBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        testBB.insertOut(d2lBB);
        testBB.insertOut(nanTestBB);
        // Convert double to long knowing that if the value is < min long the Intel
        // unspecified result is min long
        // TODO: this would be a lot simpler and faster with SSE3's FISTTP instruction
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FNSTCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Unary.create(IA32_MOVZX__W, cw, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_BinaryAcc.create(IA32_OR, cw.copyRO(), IC(0xC00))));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, scratchHi, cw.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchHi.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FISTP, sl.copy(), st0.copyRO())));
        d2lBB.appendInstruction(CPOS(s, MIR_UnaryNoRes.create(IA32_FLDCW, scratchLo.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result, sl.copy())));
        d2lBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        d2lBB.insertOut(nextBB);
        // Did the compare find a NaN or a maximum integer?
        nanTestBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_FSTP, st0.copyRO(), st0.copyRO())));
        nanTestBB.appendInstruction(CPOS(s, MIR_CondBranch.create(IA32_JCC, IA32ConditionOperand.PE(), nanBB.makeJumpTarget(), BranchProfileOperand.unlikely())));
        nanTestBB.insertOut(nanBB);
        nanTestBB.insertOut(maxintBB);
        // Value was >= max long
        maxintBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result.copyRO(), LC(Long.MAX_VALUE))));
        maxintBB.appendInstruction(CPOS(s, MIR_Branch.create(IA32_JMP, nextBB.makeJumpTarget())));
        maxintBB.insertOut(nextBB);
        // In case of NaN result is 0
        nanBB.appendInstruction(CPOS(s, MIR_Move.create(IA32_MOV, result.copyRO(), LC(0))));
        nanBB.insertOut(nextBB);
        return nextInstr;
    }
}
Also used : StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)

Example 14 with MemoryOperand

use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.

the class BURS_Helpers method loadFromJTOC.

/**
 * Create memory operand to load from a given jtoc offset
 *
 * @param ir the IR to use for getting a JTOC reg operand, if available
 * @param offset location in JTOC
 * @param size of value in JTOC
 * @return created memory operand
 */
static MemoryOperand loadFromJTOC(IR ir, Offset offset, byte size) {
    LocationOperand loc = new LocationOperand(offset);
    Operand guard = TG();
    if (JTOC_REGISTER == null) {
        return MemoryOperand.D(Magic.getTocPointer().plus(offset), size, loc, guard);
    } else {
        return MemoryOperand.BD(ir.regpool.makeTocOp().asRegister(), offset, size, loc, guard);
    }
}
Also used : StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)

Example 15 with MemoryOperand

use of org.jikesrvm.compilers.opt.ir.operand.MemoryOperand in project JikesRVM by JikesRVM.

the class SimpleSpillCost method calculate.

@Override
void calculate(IR ir) {
    final double moveFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MOVE_FACTOR;
    final double memoryOperandFactor = ir.options.REGALLOC_SIMPLE_SPILL_COST_MEMORY_OPERAND_FACTOR;
    for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements(); ) {
        BasicBlock bb = e.nextElement();
        for (Enumeration<Instruction> ie = bb.forwardInstrEnumerator(); ie.hasMoreElements(); ) {
            Instruction s = ie.nextElement();
            double factor = (bb.getInfrequent()) ? 0.0 : 1.0;
            if (s.isMove()) {
                factor *= moveFactor;
            }
            double baseFactor = factor;
            if (hasBadSizeMemoryOperand(s)) {
                baseFactor *= memoryOperandFactor;
            }
            // first deal with non-memory operands
            for (Enumeration<Operand> e2 = s.getRootOperands(); e2.hasMoreElements(); ) {
                Operand op = e2.nextElement();
                if (op.isRegister()) {
                    Register r = op.asRegister().getRegister();
                    if (r.isSymbolic()) {
                        update(r, baseFactor);
                    }
                }
            }
            // now handle memory operands
            factor *= memoryOperandFactor;
            for (Enumeration<Operand> e2 = s.getMemoryOperands(); e2.hasMoreElements(); ) {
                MemoryOperand M = (MemoryOperand) e2.nextElement();
                if (M.base != null) {
                    Register r = M.base.getRegister();
                    if (r.isSymbolic()) {
                        update(r, factor);
                    }
                }
                if (M.index != null) {
                    Register r = M.index.getRegister();
                    if (r.isSymbolic()) {
                        update(r, factor);
                    }
                }
            }
        }
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

MemoryOperand (org.jikesrvm.compilers.opt.ir.operand.MemoryOperand)32 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)24 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)13 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)13 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)11 Register (org.jikesrvm.compilers.opt.ir.Register)10 StackLocationOperand (org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand)9 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)9 IA32ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand)9 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 PhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet)7 GenericPhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.GenericPhysicalRegisterSet)6 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)6 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)5 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)4 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)3 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)3 BURSManagedFPROperand (org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand)3 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)2