Search in sources :

Example 21 with MethodOperand

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

the class FinalMIRExpansion method expand.

/**
 * @param ir the IR to expand
 * @return upperbound on number of machine code instructions
 * that will be generated for this IR
 */
public static int expand(IR ir) {
    int instructionCount = 0;
    int conditionalBranchCount = 0;
    int machinecodeLength = 0;
    PhysicalRegisterSet phys = ir.regpool.getPhysicalRegisterSet().asPPC();
    MachineCodeOffsets mcOffsets = ir.MIRInfo.mcOffsets;
    for (Instruction p = ir.firstInstructionInCodeOrder(); p != null; p = p.nextInstructionInCodeOrder()) {
        mcOffsets.setMachineCodeOffset(p, -1);
        switch(p.getOpcode()) {
            case MIR_LOWTABLESWITCH_opcode:
                {
                    BasicBlock tableBlock = p.getBasicBlock();
                    BasicBlock nextBlock = tableBlock.splitNodeWithLinksAt(p.prevInstructionInCodeOrder(), ir);
                    mcOffsets.setMachineCodeOffset(nextBlock.firstInstruction(), -1);
                    Register regI = MIR_LowTableSwitch.getIndex(p).getRegister();
                    int NumTargets = MIR_LowTableSwitch.getNumberOfTargets(p);
                    tableBlock.appendInstruction(MIR_Call.create0(PPC_BL, null, null, nextBlock.makeJumpTarget()));
                    for (int i = 0; i < NumTargets; i++) {
                        tableBlock.appendInstruction(MIR_DataLabel.create(PPC_DATA_LABEL, MIR_LowTableSwitch.getClearTarget(p, i)));
                    }
                    Register temp = phys.getGPR(0);
                    p.insertBefore(MIR_Move.create(PPC_MFSPR, A(temp), A(phys.getLR())));
                    p.insertBefore(MIR_Binary.create(PPC_SLWI, I(regI), I(regI), IC(2)));
                    p.insertBefore(MIR_LoadUpdate.create(PPC_LIntUX, I(temp), I(regI), A(temp)));
                    p.insertBefore(MIR_Binary.create(PPC_ADD, A(regI), A(regI), I(temp)));
                    p.insertBefore(MIR_Move.create(PPC_MTSPR, A(phys.getCTR()), A(regI)));
                    MIR_Branch.mutate(p, PPC_BCTR);
                    instructionCount += NumTargets + 7;
                }
                break;
            case PPC_BCOND2_opcode:
                {
                    RegisterOperand cond = MIR_CondBranch2.getClearValue(p);
                    p.insertAfter(MIR_CondBranch.create(PPC_BCOND, cond.copyU2U(), MIR_CondBranch2.getClearCond2(p), MIR_CondBranch2.getClearTarget2(p), MIR_CondBranch2.getClearBranchProfile2(p)));
                    MIR_CondBranch.mutate(p, PPC_BCOND, cond, MIR_CondBranch2.getClearCond1(p), MIR_CondBranch2.getClearTarget1(p), MIR_CondBranch2.getClearBranchProfile1(p));
                    conditionalBranchCount++;
                }
                break;
            case PPC_BLRL_opcode:
            case PPC_BCTRL_opcode:
                {
                    // See also ConvertToLowlevelIR.java
                    if (VM.BuildForIMTInterfaceInvocation) {
                        if (MIR_Call.hasMethod(p)) {
                            MethodOperand mo = MIR_Call.getMethod(p);
                            if (mo.isInterface()) {
                                InterfaceMethodSignature sig = InterfaceMethodSignature.findOrCreate(mo.getMemberRef());
                                int signatureId = sig.getId();
                                Instruction s;
                                if (fits(signatureId, 16)) {
                                    s = MIR_Unary.create(PPC_LDI, I(phys.getGPR(LAST_SCRATCH_GPR)), IC(signatureId));
                                    p.insertBefore(s);
                                    instructionCount++;
                                } else {
                                    s = MIR_Unary.create(PPC_LDIS, I(phys.getGPR(LAST_SCRATCH_GPR)), IC(PPCMaskUpper16(signatureId)));
                                    p.insertBefore(s);
                                    s = MIR_Binary.create(PPC_ADDI, I(phys.getGPR(LAST_SCRATCH_GPR)), I(phys.getGPR(LAST_SCRATCH_GPR)), IC(PPCMaskLower16(signatureId)));
                                    p.insertBefore(s);
                                    instructionCount += 2;
                                }
                            }
                        }
                    }
                    instructionCount++;
                }
                break;
            case LABEL_opcode:
            case BBEND_opcode:
            case UNINT_BEGIN_opcode:
            case UNINT_END_opcode:
                // These generate no code, so don't count them.
                break;
            case RESOLVE_opcode:
                {
                    Register zero = phys.getGPR(0);
                    Register JTOC = phys.getJTOC();
                    Register CTR = phys.getCTR();
                    if (VM.VerifyAssertions)
                        VM._assert(p.getBytecodeIndex() >= 0 && p.position() != null);
                    Offset offset = Entrypoints.optResolveMethod.getOffset();
                    if (fits(offset, 16)) {
                        p.insertBefore(MIR_Load.create(PPC_LAddr, A(zero), A(JTOC), IC(PPCMaskLower16(offset))));
                    } else {
                        // not implemented
                        if (VM.VerifyAssertions)
                            VM._assert(fits(offset, 32));
                        p.insertBefore(MIR_Binary.create(PPC_ADDIS, A(zero), A(JTOC), IC(PPCMaskUpper16(offset))));
                        p.insertBefore(MIR_Load.create(PPC_LAddr, A(zero), A(zero), IC(PPCMaskLower16(offset))));
                        instructionCount += 1;
                    }
                    p.insertBefore(MIR_Move.create(PPC_MTSPR, A(CTR), A(zero)));
                    instructionCount += 3;
                    // Because the GC Map code holds a reference to the original
                    // instruction, it is important that we mutate the last instruction
                    // because this will be the GC point.
                    MIR_Call.mutate0(p, PPC_BCTRL, null, null);
                    break;
                }
            case YIELDPOINT_PROLOGUE_opcode:
                {
                    Register TSR = phys.getTSR();
                    BasicBlock yieldpoint = findOrCreateYieldpointBlock(ir, RVMThread.PROLOGUE);
                    // Because the GC Map code holds a reference to the original
                    // instruction, it is important that we mutate the last instruction
                    // because this will be the GC point.
                    MIR_CondCall.mutate0(p, PPC_BCL, null, null, I(TSR), PowerPCConditionOperand.NOT_EQUAL(), yieldpoint.makeJumpTarget());
                    p.getBasicBlock().insertOut(yieldpoint);
                    conditionalBranchCount++;
                }
                break;
            case YIELDPOINT_BACKEDGE_opcode:
                {
                    BasicBlock yieldpoint = findOrCreateYieldpointBlock(ir, RVMThread.BACKEDGE);
                    Register zero = phys.getGPR(0);
                    Register TSR = phys.getTSR();
                    Register TR = phys.getTR();
                    Offset offset = Entrypoints.takeYieldpointField.getOffset();
                    if (VM.VerifyAssertions)
                        VM._assert(fits(offset, 16));
                    p.insertBefore(MIR_Load.create(PPC_LInt, I(zero), A(TR), IC(PPCMaskLower16(offset))));
                    p.insertBefore(MIR_Binary.create(PPC_CMPI, I(TSR), I(zero), IC(0)));
                    instructionCount += 2;
                    // Because the GC Map code holds a reference to the original
                    // instruction, it is important that we mutate the last instruction
                    // because this will be the GC point.
                    MIR_CondCall.mutate0(p, PPC_BCL, null, null, I(TSR), PowerPCConditionOperand.GREATER(), yieldpoint.makeJumpTarget());
                    p.getBasicBlock().insertOut(yieldpoint);
                    conditionalBranchCount++;
                }
                break;
            case YIELDPOINT_EPILOGUE_opcode:
                {
                    BasicBlock yieldpoint = findOrCreateYieldpointBlock(ir, RVMThread.EPILOGUE);
                    Register zero = phys.getGPR(0);
                    Register TSR = phys.getTSR();
                    Register TR = phys.getTR();
                    Offset offset = Entrypoints.takeYieldpointField.getOffset();
                    if (VM.VerifyAssertions)
                        VM._assert(fits(offset, 16));
                    p.insertBefore(MIR_Load.create(PPC_LInt, I(zero), A(TR), IC(PPCMaskLower16(offset))));
                    p.insertBefore(MIR_Binary.create(PPC_CMPI, I(TSR), I(zero), IC(0)));
                    instructionCount += 2;
                    // Because the GC Map code holds a reference to the original
                    // instruction, it is important that we mutate the last instruction
                    // because this will be the GC point.
                    MIR_CondCall.mutate0(p, PPC_BCL, null, null, I(TSR), PowerPCConditionOperand.NOT_EQUAL(), yieldpoint.makeJumpTarget());
                    p.getBasicBlock().insertOut(yieldpoint);
                    conditionalBranchCount++;
                }
                break;
            case YIELDPOINT_OSR_opcode:
                {
                    // unconditionally branch to yield point.
                    BasicBlock yieldpoint = findOrCreateYieldpointBlock(ir, RVMThread.OSROPT);
                    // Because the GC Map code holds a reference to the original
                    // instruction, it is important that we mutate the last instruction
                    // because this will be the GC point.
                    MIR_Call.mutate0(p, PPC_BL, null, null, yieldpoint.makeJumpTarget());
                    p.getBasicBlock().insertOut(yieldpoint);
                }
                instructionCount++;
                break;
            default:
                if (p.operator().isConditionalBranch()) {
                    conditionalBranchCount++;
                } else {
                    instructionCount++;
                }
                break;
        }
    }
    // reasonably sized methods
    if ((instructionCount + conditionalBranchCount) > AssemblerOpt.MAX_COND_DISPL) {
        machinecodeLength = instructionCount + 2 * conditionalBranchCount;
    } else {
        machinecodeLength = instructionCount + conditionalBranchCount;
    }
    if ((machinecodeLength & ~AssemblerOpt.MAX_24_BITS) != 0) {
        throw new OptimizingCompilerException("CodeGen", "method too large to compile:", AssemblerOpt.MAX_24_BITS);
    }
    return machinecodeLength;
}
Also used : InterfaceMethodSignature(org.jikesrvm.classloader.InterfaceMethodSignature) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ppc.PhysicalRegisterSet) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) MachineCodeOffsets(org.jikesrvm.compilers.opt.mir2mc.MachineCodeOffsets) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) Offset(org.vmmagic.unboxed.Offset)

Example 22 with MethodOperand

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

the class BasicBlock method hasAthrowInst.

/**
 * Does this basic block contain an explicit athrow instruction?
 *
 * @return <code>true</code> if the block ends in an explicit Athrow
 *         instruction or <code>false</code> if it does not
 */
public final boolean hasAthrowInst() {
    if (isEmpty())
        return false;
    Instruction s = lastRealInstruction();
    if (VM.BuildForIA32 && s.operator().isAdviseESP()) {
        s = s.getPrev();
    }
    if (Athrow.conforms(s)) {
        return true;
    }
    MethodOperand mop = null;
    if (VM.BuildForIA32 && org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.conforms(s)) {
        mop = org.jikesrvm.compilers.opt.ir.ia32.MIR_Call.getMethod(s);
    } else if (VM.BuildForPowerPC && org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.conforms(s)) {
        mop = org.jikesrvm.compilers.opt.ir.ppc.MIR_Call.getMethod(s);
    } else if (Call.conforms(s)) {
        mop = Call.getMethod(s);
    }
    return mop != null && mop.getTarget() == Entrypoints.athrowMethod;
}
Also used : MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 23 with MethodOperand

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

the class CFGVisualization method formatCall.

protected String formatCall(Instruction inst) {
    StringBuilder buf = new StringBuilder();
    MethodOperand mop = Call.getMethod(inst);
    if (mop != null && mop.hasTarget()) {
        RVMMethod method = mop.getTarget();
        buf.append(method.getDeclaringClass());
        buf.append(":");
        buf.append(method.getName());
        buf.append(":");
        buf.append(method.getDescriptor());
        buf.append(":");
        int params = Call.getNumberOfParams(inst);
        for (int i = 1; i <= params; i++) {
            buf.append(Call.getParam(inst, i - 1));
            if (i < params) {
                buf.append(", ");
            } else {
                buf.append("; ");
            }
        }
    }
    return buf.toString();
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 24 with MethodOperand

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

the class GenerationContextTest method inliningInstanceMethodWithRegisterReceiver.

@Test
public void inliningInstanceMethodWithRegisterReceiver() throws Exception {
    NormalMethod nm = getNormalMethodForTest("methodForInliningTests");
    CompiledMethod cm = new OptCompiledMethod(-1, nm);
    OptOptions opts = new OptOptions();
    InlineOracle io = new DefaultInlineOracle();
    GenerationContext gc = new GenerationContext(nm, null, cm, opts, io);
    Class<?>[] argumentTypes = { Object.class, double.class, int.class, long.class };
    NormalMethod callee = getNormalMethodForTest("emptyInstanceMethodWithParams", argumentTypes);
    MethodOperand methOp = MethodOperand.VIRTUAL(callee.getMemberRef().asMethodReference(), callee);
    Instruction callInstr = Call.create(CALL, null, null, methOp, 5);
    RegisterOperand receiver = createMockRegisterOperand(TypeReference.JavaLangObject);
    assertFalse(receiver.isPreciseType());
    assertFalse(receiver.isDeclaredType());
    receiver.setPreciseType();
    Call.setParam(callInstr, 0, receiver);
    RegisterOperand objectParam = prepareCallWithObjectParam(callInstr);
    RegisterOperand doubleParam = prepareCallWithDoubleParam(callInstr);
    RegisterOperand intParam = prepareCallWithIntParam(callInstr);
    RegisterOperand longParam = prepareCallWithLongParam(callInstr);
    callInstr.setPosition(new InlineSequence(nm));
    ExceptionHandlerBasicBlockBag ebag = getMockEbag();
    int nodeNumber = 12345;
    gc.getCfg().setNumberOfNodes(nodeNumber);
    GenerationContext child = gc.createChildContext(ebag, callee, callInstr);
    assertThatStateIsCopiedFromParentToChild(gc, callee, child, ebag);
    assertThatReturnValueIsVoid(child);
    RegisterOperand thisArg = child.getArguments()[0].asRegister();
    assertFalse(thisArg.isPreciseType());
    assertTrue(thisArg.isDeclaredType());
    TypeReference calleeClass = callee.getDeclaringClass().getTypeRef();
    assertSame(thisArg.getType(), calleeClass);
    RegisterOperand expectedLocalForReceiverParam = child.makeLocal(0, thisArg);
    assertTrue(thisArg.sameRegisterPropertiesAs(expectedLocalForReceiverParam));
    RegisterOperand firstArg = child.getArguments()[1].asRegister();
    RegisterOperand expectedLocalForObjectParam = child.makeLocal(1, firstArg);
    assertTrue(firstArg.sameRegisterPropertiesAs(expectedLocalForObjectParam));
    RegisterOperand secondArg = child.getArguments()[2].asRegister();
    RegisterOperand expectedLocalForDoubleParam = child.makeLocal(2, secondArg);
    assertTrue(secondArg.sameRegisterPropertiesAs(expectedLocalForDoubleParam));
    RegisterOperand thirdArg = child.getArguments()[3].asRegister();
    RegisterOperand expectedLocalForIntParam = child.makeLocal(4, thirdArg);
    assertTrue(thirdArg.sameRegisterPropertiesAs(expectedLocalForIntParam));
    RegisterOperand fourthArg = child.getArguments()[4].asRegister();
    RegisterOperand expectedLocalForLongParam = child.makeLocal(5, fourthArg);
    assertTrue(fourthArg.sameRegisterPropertiesAs(expectedLocalForLongParam));
    InlineSequence expectedInlineSequence = new InlineSequence(callee, callInstr.position(), callInstr);
    assertEquals(expectedInlineSequence, child.getInlineSequence());
    assertThatPrologueAndEpilogueAreWiredCorrectlyForChildContext(ebag, nodeNumber, child);
    Enumeration<Instruction> prologueRealInstr = child.getPrologue().forwardRealInstrEnumerator();
    Instruction receiverMove = prologueRealInstr.nextElement();
    RegisterOperand expectedReceiver = receiver.copy().asRegister();
    narrowRegOpToCalleeClass(expectedReceiver, calleeClass);
    assertMoveOperationIsCorrect(callInstr, REF_MOVE, expectedLocalForReceiverParam, expectedReceiver, receiverMove);
    Instruction objectMove = prologueRealInstr.nextElement();
    RegisterOperand objectParamCopy = objectParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, REF_MOVE, expectedLocalForObjectParam, objectParamCopy, objectMove);
    Instruction doubleMove = prologueRealInstr.nextElement();
    RegisterOperand doubleParamCopy = doubleParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, DOUBLE_MOVE, expectedLocalForDoubleParam, doubleParamCopy, doubleMove);
    Instruction intMove = prologueRealInstr.nextElement();
    RegisterOperand intParamCopy = intParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, INT_MOVE, expectedLocalForIntParam, intParamCopy, intMove);
    Instruction longMove = prologueRealInstr.nextElement();
    RegisterOperand longParamCopy = longParam.copy().asRegister();
    assertMoveOperationIsCorrect(callInstr, LONG_MOVE, expectedLocalForLongParam, longParamCopy, longMove);
    assertThatNoMoreInstructionsExist(prologueRealInstr);
    BasicBlock epilogue = child.getEpilogue();
    assertThatEpilogueLabelIsCorrectForInlinedMethod(child, expectedInlineSequence, epilogue);
    assertThatEpilogueIsEmpty(epilogue);
    assertThatNoRethrowBlockExists(child);
    assertThatChecksWontBeSkipped(gc);
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineOracle(org.jikesrvm.compilers.opt.inlining.InlineOracle) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) OptOptions(org.jikesrvm.compilers.opt.OptOptions) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) CompiledMethod(org.jikesrvm.compilers.common.CompiledMethod) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) NormalMethod(org.jikesrvm.classloader.NormalMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineSequence(org.jikesrvm.compilers.opt.inlining.InlineSequence) TypeReference(org.jikesrvm.classloader.TypeReference) Test(org.junit.Test)

Example 25 with MethodOperand

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

the class ConvertToLowLevelIR method convert.

/**
 * Converts the given HIR to LIR.
 *
 * @param ir IR to convert
 * @param options the options for the conversion
 */
static void convert(IR ir, OptOptions options) {
    boolean didArrayStoreCheck = false;
    for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
        switch(s.getOpcode()) {
            case GETSTATIC_opcode:
                {
                    LocationOperand loc = GetStatic.getClearLocation(s);
                    RegisterOperand result = GetStatic.getClearResult(s);
                    Operand address = ir.regpool.makeJTOCOp();
                    Operand offset = GetStatic.getClearOffset(s);
                    Load.mutate(s, IRTools.getLoadOp(loc.getFieldRef(), true), result, address, offset, loc);
                }
                break;
            case PUTSTATIC_opcode:
                {
                    LocationOperand loc = PutStatic.getClearLocation(s);
                    Operand value = PutStatic.getClearValue(s);
                    Operand address = ir.regpool.makeJTOCOp();
                    Operand offset = PutStatic.getClearOffset(s);
                    Store.mutate(s, IRTools.getStoreOp(loc.getFieldRef(), true), value, address, offset, loc);
                }
                break;
            case PUTFIELD_opcode:
                {
                    LocationOperand loc = PutField.getClearLocation(s);
                    Operand value = PutField.getClearValue(s);
                    Operand address = PutField.getClearRef(s);
                    Operand offset = PutField.getClearOffset(s);
                    Store.mutate(s, IRTools.getStoreOp(loc.getFieldRef(), false), value, address, offset, loc, PutField.getClearGuard(s));
                }
                break;
            case GETFIELD_opcode:
                {
                    LocationOperand loc = GetField.getClearLocation(s);
                    RegisterOperand result = GetField.getClearResult(s);
                    Operand address = GetField.getClearRef(s);
                    Operand offset = GetField.getClearOffset(s);
                    Load.mutate(s, IRTools.getLoadOp(loc.getFieldRef(), false), result, address, offset, loc, GetField.getClearGuard(s));
                }
                break;
            case INT_ALOAD_opcode:
                doArrayLoad(s, ir, INT_LOAD, 2);
                break;
            case LONG_ALOAD_opcode:
                doArrayLoad(s, ir, LONG_LOAD, 3);
                break;
            case FLOAT_ALOAD_opcode:
                doArrayLoad(s, ir, FLOAT_LOAD, 2);
                break;
            case DOUBLE_ALOAD_opcode:
                doArrayLoad(s, ir, DOUBLE_LOAD, 3);
                break;
            case REF_ALOAD_opcode:
                doArrayLoad(s, ir, REF_LOAD, LOG_BYTES_IN_ADDRESS);
                break;
            case BYTE_ALOAD_opcode:
                doArrayLoad(s, ir, BYTE_LOAD, 0);
                break;
            case UBYTE_ALOAD_opcode:
                doArrayLoad(s, ir, UBYTE_LOAD, 0);
                break;
            case USHORT_ALOAD_opcode:
                doArrayLoad(s, ir, USHORT_LOAD, 1);
                break;
            case SHORT_ALOAD_opcode:
                doArrayLoad(s, ir, SHORT_LOAD, 1);
                break;
            case INT_ASTORE_opcode:
                doArrayStore(s, ir, INT_STORE, 2);
                break;
            case LONG_ASTORE_opcode:
                doArrayStore(s, ir, LONG_STORE, 3);
                break;
            case FLOAT_ASTORE_opcode:
                doArrayStore(s, ir, FLOAT_STORE, 2);
                break;
            case DOUBLE_ASTORE_opcode:
                doArrayStore(s, ir, DOUBLE_STORE, 3);
                break;
            case REF_ASTORE_opcode:
                doArrayStore(s, ir, REF_STORE, LOG_BYTES_IN_ADDRESS);
                break;
            case BYTE_ASTORE_opcode:
                doArrayStore(s, ir, BYTE_STORE, 0);
                break;
            case SHORT_ASTORE_opcode:
                doArrayStore(s, ir, SHORT_STORE, 1);
                break;
            case CALL_opcode:
                s = callHelper(s, ir);
                break;
            case SYSCALL_opcode:
                // a sequence of loads off the BootRecord to find the appropriate field.
                if (Call.getMethod(s) != null) {
                    expandSysCallTarget(s, ir);
                }
                break;
            case TABLESWITCH_opcode:
                s = tableswitch(s, ir);
                break;
            case LOOKUPSWITCH_opcode:
                s = lookup(s, ir);
                break;
            case OBJARRAY_STORE_CHECK_opcode:
                s = DynamicTypeCheckExpansion.arrayStoreCheck(s, ir, true);
                didArrayStoreCheck = true;
                break;
            case OBJARRAY_STORE_CHECK_NOTNULL_opcode:
                s = DynamicTypeCheckExpansion.arrayStoreCheck(s, ir, false);
                didArrayStoreCheck = true;
                break;
            case CHECKCAST_opcode:
            case CHECKCAST_UNRESOLVED_opcode:
                s = DynamicTypeCheckExpansion.checkcast(s, ir);
                break;
            case CHECKCAST_NOTNULL_opcode:
                s = DynamicTypeCheckExpansion.checkcastNotNull(s, ir);
                break;
            case MUST_IMPLEMENT_INTERFACE_opcode:
                s = DynamicTypeCheckExpansion.mustImplementInterface(s, ir);
                break;
            case IG_CLASS_TEST_opcode:
                IfCmp.mutate(s, REF_IFCMP, ir.regpool.makeTempValidation(), getTIB(s, ir, InlineGuard.getClearValue(s), InlineGuard.getClearGuard(s)), getTIB(s, ir, InlineGuard.getGoal(s).asType()), ConditionOperand.NOT_EQUAL(), InlineGuard.getClearTarget(s), InlineGuard.getClearBranchProfile(s));
                break;
            case IG_METHOD_TEST_opcode:
                {
                    MethodOperand methOp = InlineGuard.getClearGoal(s).asMethod();
                    Operand t1 = getTIB(s, ir, InlineGuard.getClearValue(s), InlineGuard.getClearGuard(s));
                    Operand t2 = getTIB(s, ir, methOp.getTarget().getDeclaringClass());
                    IfCmp.mutate(s, REF_IFCMP, ir.regpool.makeTempValidation(), getInstanceMethod(s, ir, t1, methOp.getTarget()), getInstanceMethod(s, ir, t2, methOp.getTarget()), ConditionOperand.NOT_EQUAL(), InlineGuard.getClearTarget(s), InlineGuard.getClearBranchProfile(s));
                    break;
                }
            case INSTANCEOF_opcode:
            case INSTANCEOF_UNRESOLVED_opcode:
                s = DynamicTypeCheckExpansion.instanceOf(s, ir);
                break;
            case INSTANCEOF_NOTNULL_opcode:
                s = DynamicTypeCheckExpansion.instanceOfNotNull(s, ir);
                break;
            case INT_ZERO_CHECK_opcode:
                {
                    TrapIf.mutate(s, TRAP_IF, ZeroCheck.getClearGuardResult(s), ZeroCheck.getClearValue(s), IC(0), ConditionOperand.EQUAL(), TrapCodeOperand.DivByZero());
                }
                break;
            case LONG_ZERO_CHECK_opcode:
                {
                    TrapIf.mutate(s, TRAP_IF, ZeroCheck.getClearGuardResult(s), ZeroCheck.getClearValue(s), LC(0), ConditionOperand.EQUAL(), TrapCodeOperand.DivByZero());
                }
                break;
            case BOUNDS_CHECK_opcode:
                {
                    // get array_length from array_ref
                    RegisterOperand array_length = InsertGuardedUnary(s, ir, ARRAYLENGTH, TypeReference.Int, BoundsCheck.getClearRef(s), BoundsCheck.getClearGuard(s));
                    // In UN-signed comparison, a negative index will look like a very
                    // large positive number, greater than array length.
                    // Thus length LLT index is false iff 0 <= index <= length
                    TrapIf.mutate(s, TRAP_IF, BoundsCheck.getClearGuardResult(s), array_length.copyD2U(), BoundsCheck.getClearIndex(s), ConditionOperand.LOWER_EQUAL(), TrapCodeOperand.ArrayBounds());
                }
                break;
            case RESOLVE_MEMBER_opcode:
                s = resolveMember(s, ir);
                break;
            default:
                break;
        }
    }
    // Eliminate possible redundant trap block from array store checks
    if (didArrayStoreCheck) {
        branchOpts.perform(ir, true);
    }
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Aggregations

MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)34 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)26 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)26 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)17 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)12 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)11 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)11 NormalMethod (org.jikesrvm.classloader.NormalMethod)10 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)10 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)10 Test (org.junit.Test)10 CompiledMethod (org.jikesrvm.compilers.common.CompiledMethod)9 InlineSequence (org.jikesrvm.compilers.opt.inlining.InlineSequence)9 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)9 ExceptionHandlerBasicBlockBag (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)9 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)9 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)9 RVMMethod (org.jikesrvm.classloader.RVMMethod)8 TypeReference (org.jikesrvm.classloader.TypeReference)8 OptOptions (org.jikesrvm.compilers.opt.OptOptions)8