Search in sources :

Example 1 with MethodOperand

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

the class Inliner method execute.

/**
 * Return a generation context that represents the
 * execution of inlDec in the context <code>&lt;parent,ebag&gt;</code> for
 * the call instruction callSite.
 * <p> PRECONDITION: inlDec.isYes()
 * <p> POSTCONDITIONS:
 * Let gc be the returned generation context.
 * <ul>
 *  <li> gc.cfg.firstInCodeOrder is the entry to the inlined context
 *  <li>gc.cfg.lastInCodeOrder is the exit from the inlined context
 *  <li> GenerationContext.transferState(parent, child) has been called.
 * </ul>
 *
 * @param inlDec the inlining decision to execute
 * @param parent the caller generation context
 * @param ebag exception handler scope for the caller
 * @param callSite the callsite to execute
 * @return a generation context that represents the execution of the
 *         inline decision in the given context
 */
public static GenerationContext execute(InlineDecision inlDec, GenerationContext parent, ExceptionHandlerBasicBlockBag ebag, Instruction callSite) {
    if (inlDec.needsGuard()) {
        // Step 1: create the synthetic generation context we'll
        // return to our caller.
        GenerationContext container = GenerationContext.createSynthetic(parent, ebag);
        container.getCfg().breakCodeOrder(container.getPrologue(), container.getEpilogue());
        // Step 2: (a) Print a message (optional)
        // (b) Generate the child GC for each target
        RVMMethod[] targets = inlDec.getTargets();
        byte[] guards = inlDec.getGuards();
        GenerationContext[] children = new GenerationContext[targets.length];
        for (int i = 0; i < targets.length; i++) {
            NormalMethod callee = (NormalMethod) targets[i];
            // (a)
            if (parent.getOptions().PRINT_INLINE_REPORT) {
                String guard = guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST ? " (class test) " : " (method test) ";
                VM.sysWriteln("\tGuarded inline" + guard + " " + callee + " into " + callSite.position().getMethod() + " at bytecode " + callSite.getBytecodeIndex());
            }
            // (b)
            children[i] = parent.createChildContext(ebag, callee, callSite);
            BC2IR.generateHIR(children[i]);
            children[i].transferStateToParent();
        }
        // special purpose coding wrapping the calls to Operand.meet.
        if (Call.hasResult(callSite)) {
            Register reg = Call.getResult(callSite).getRegister();
            container.setResult(children[0].getResult());
            for (int i = 1; i < targets.length; i++) {
                if (children[i].getResult() != null) {
                    container.setResult((container.getResult() == null) ? children[i].getResult() : Operand.meet(container.getResult(), children[i].getResult(), reg));
                }
            }
            if (!inlDec.OSRTestFailed()) {
                // Account for the non-predicted case as well...
                RegisterOperand failureCaseResult = Call.getResult(callSite).copyRO();
                container.setResult((container.getResult() == null) ? failureCaseResult : Operand.meet(container.getResult(), failureCaseResult, reg));
            }
        }
        // Step 4: Create a block to contain a copy of the original call or an OSR_Yieldpoint
        // to cover the case that all predictions fail.
        BasicBlock testFailed = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
        testFailed.setExceptionHandlers(ebag);
        if (COUNT_FAILED_GUARDS && Controller.options.INSERT_DEBUGGING_COUNTERS) {
            // Get a dynamic count of how many times guards fail at runtime.
            // Need a name for the event to count.  In this example, a
            // separate counter for each method by using the method name
            // as the event name.  You could also have used just the string
            // "Guarded inline failed" to keep only one counter.
            String eventName = "Guarded inline failed: " + callSite.position().getMethod().toString();
            // Create instruction that will increment the counter
            // corresponding to the named event.
            Instruction counterInst = AOSDatabase.debuggingCounterData.getCounterInstructionForEvent(eventName);
            testFailed.appendInstruction(counterInst);
        }
        if (inlDec.OSRTestFailed()) {
            // note where we're storing the osr barrier instruction
            Instruction lastOsrBarrier = parent.getOSRBarrierFromInst(callSite);
            Instruction s = BC2IR._osrHelper(lastOsrBarrier, parent);
            s.copyPosition(callSite);
            testFailed.appendInstruction(s);
            testFailed.insertOut(parent.getExit());
        } else {
            Instruction call = callSite.copyWithoutLinks();
            Call.getMethod(call).setIsGuardedInlineOffBranch(true);
            call.copyPosition(callSite);
            testFailed.appendInstruction(call);
            testFailed.insertOut(container.getEpilogue());
            // BC2IR.maybeInlineMethod).
            if (ebag != null) {
                for (Enumeration<BasicBlock> e = ebag.enumerator(); e.hasMoreElements(); ) {
                    BasicBlock handler = e.nextElement();
                    testFailed.insertOut(handler);
                }
            }
            testFailed.setCanThrowExceptions();
            testFailed.setMayThrowUncaughtException();
        }
        container.getCfg().linkInCodeOrder(testFailed, container.getEpilogue());
        testFailed.setInfrequent();
        // Step 5: Patch together all the callees by generating guard blocks
        BasicBlock firstIfBlock = testFailed;
        // Note: We know that receiver must be a register
        // operand (and not a string constant) because we are doing a
        // guarded inlining....if it was a string constant we'd have
        // been able to inline without a guard.
        Operand receiver = Call.getParam(callSite, 0);
        MethodOperand mo = Call.getMethod(callSite);
        boolean isInterface = mo.isInterface();
        if (isInterface) {
            if (VM.BuildForIMTInterfaceInvocation) {
                RVMType interfaceType = mo.getTarget().getDeclaringClass();
                TypeReference recTypeRef = receiver.getType();
                RVMClass recType = (RVMClass) recTypeRef.peekType();
                // Attempt to avoid inserting the check by seeing if the
                // known static type of the receiver implements the interface.
                boolean requiresImplementsTest = true;
                if (recType != null && recType.isResolved() && !recType.isInterface()) {
                    byte doesImplement = ClassLoaderProxy.includesType(interfaceType.getTypeRef(), recTypeRef);
                    requiresImplementsTest = doesImplement != YES;
                }
                if (requiresImplementsTest) {
                    RegisterOperand checkedReceiver = parent.getTemps().makeTemp(receiver);
                    Instruction dtc = TypeCheck.create(MUST_IMPLEMENT_INTERFACE, checkedReceiver, receiver.copy(), new TypeOperand(interfaceType), Call.getGuard(callSite).copy());
                    dtc.copyPosition(callSite);
                    checkedReceiver.refine(interfaceType.getTypeRef());
                    Call.setParam(callSite, 0, checkedReceiver.copyRO());
                    testFailed.prependInstruction(dtc);
                }
            }
        }
        // "logical" test and to share test insertion for interfaces/virtuals.
        for (int i = children.length - 1; i >= 0; i--, testFailed = firstIfBlock) {
            firstIfBlock = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
            firstIfBlock.setExceptionHandlers(ebag);
            BasicBlock lastIfBlock = firstIfBlock;
            RVMMethod target = children[i].getMethod();
            Instruction tmp;
            if (isInterface) {
                RVMClass callDeclClass = mo.getTarget().getDeclaringClass();
                if (!callDeclClass.isInterface()) {
                    // the entire compilation.
                    throw new OptimizingCompilerException("Attempted guarded inline of invoke interface when decl class of target method may not be an interface");
                }
                // We potentially have to generate IR to perform two tests here:
                // (1) Does the receiver object implement callDeclClass?
                // (2) Given that it does, is target the method that would
                // be invoked for this receiver?
                // It is quite common to be able to answer (1) "YES" at compile
                // time, in which case we only have to generate IR to establish
                // (2) at runtime.
                byte doesImplement = ClassLoaderProxy.includesType(callDeclClass.getTypeRef(), target.getDeclaringClass().getTypeRef());
                if (doesImplement != YES) {
                    // implements the interface).
                    if (parent.getOptions().PRINT_INLINE_REPORT) {
                        VM.sysWriteln("\t\tRequired additional instanceof " + callDeclClass + " test");
                    }
                    firstIfBlock = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
                    firstIfBlock.setExceptionHandlers(ebag);
                    RegisterOperand instanceOfResult = parent.getTemps().makeTempInt();
                    tmp = InstanceOf.create(INSTANCEOF_NOTNULL, instanceOfResult, new TypeOperand(callDeclClass), receiver.copy(), Call.getGuard(callSite));
                    tmp.copyPosition(callSite);
                    firstIfBlock.appendInstruction(tmp);
                    tmp = IfCmp.create(INT_IFCMP, parent.getTemps().makeTempValidation(), instanceOfResult.copyD2U(), new IntConstantOperand(0), ConditionOperand.EQUAL(), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
                    tmp.copyPosition(callSite);
                    firstIfBlock.appendInstruction(tmp);
                    firstIfBlock.insertOut(testFailed);
                    firstIfBlock.insertOut(lastIfBlock);
                    container.getCfg().linkInCodeOrder(firstIfBlock, lastIfBlock);
                }
            }
            if (guards[i] == OptOptions.INLINE_GUARD_CLASS_TEST) {
                tmp = InlineGuard.create(IG_CLASS_TEST, receiver.copy(), Call.getGuard(callSite).copy(), new TypeOperand(target.getDeclaringClass()), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
            } else if (guards[i] == OptOptions.INLINE_GUARD_METHOD_TEST) {
                // declaring class.
                if (isInterface) {
                    RegisterOperand t = parent.getTemps().makeTempInt();
                    Instruction test = InstanceOf.create(INSTANCEOF_NOTNULL, t, new TypeOperand(target.getDeclaringClass().getTypeRef()), receiver.copy());
                    test.copyPosition(callSite);
                    lastIfBlock.appendInstruction(test);
                    Instruction cmp = IfCmp.create(INT_IFCMP, parent.getTemps().makeTempValidation(), t.copyD2U(), new IntConstantOperand(0), ConditionOperand.EQUAL(), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
                    cmp.copyPosition(callSite);
                    lastIfBlock.appendInstruction(cmp);
                    BasicBlock subclassTest = new BasicBlock(callSite.getBytecodeIndex(), callSite.position(), parent.getCfg());
                    lastIfBlock.insertOut(testFailed);
                    lastIfBlock.insertOut(subclassTest);
                    container.getCfg().linkInCodeOrder(lastIfBlock, subclassTest);
                    lastIfBlock = subclassTest;
                }
                tmp = InlineGuard.create(IG_METHOD_TEST, receiver.copy(), Call.getGuard(callSite).copy(), MethodOperand.VIRTUAL(target.getMemberRef().asMethodReference(), target), testFailed.makeJumpTarget(), BranchProfileOperand.unlikely());
            } else {
                tmp = InlineGuard.create(IG_PATCH_POINT, receiver.copy(), Call.getGuard(callSite).copy(), MethodOperand.VIRTUAL(target.getMemberRef().asMethodReference(), target), testFailed.makeJumpTarget(), inlDec.OSRTestFailed() ? BranchProfileOperand.never() : BranchProfileOperand.unlikely());
            }
            tmp.copyPosition(callSite);
            lastIfBlock.appendInstruction(tmp);
            lastIfBlock.insertOut(testFailed);
            lastIfBlock.insertOut(children[i].getPrologue());
            container.getCfg().linkInCodeOrder(lastIfBlock, children[i].getCfg().firstInCodeOrder());
            if (children[i].getEpilogue() != null) {
                children[i].getEpilogue().appendInstruction(container.getEpilogue().makeGOTO());
                children[i].getEpilogue().insertOut(container.getEpilogue());
            }
            container.getCfg().linkInCodeOrder(children[i].getCfg().lastInCodeOrder(), testFailed);
        }
        // Step 6: finish by linking container.prologue & testFailed
        container.getPrologue().insertOut(testFailed);
        container.getCfg().linkInCodeOrder(container.getPrologue(), testFailed);
        return container;
    } else {
        if (VM.VerifyAssertions)
            VM._assert(inlDec.getNumberOfTargets() == 1);
        NormalMethod callee = (NormalMethod) inlDec.getTargets()[0];
        if (parent.getOptions().PRINT_INLINE_REPORT) {
            VM.sysWriteln("\tInline " + callee + " into " + callSite.position().getMethod() + " at bytecode " + callSite.getBytecodeIndex());
        }
        GenerationContext child = parent.createChildContext(ebag, callee, callSite);
        BC2IR.generateHIR(child);
        child.transferStateToParent();
        return child;
    }
}
Also used : GenerationContext(org.jikesrvm.compilers.opt.bc2ir.GenerationContext) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) RVMClass(org.jikesrvm.classloader.RVMClass) RVMMethod(org.jikesrvm.classloader.RVMMethod) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) NormalMethod(org.jikesrvm.classloader.NormalMethod) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) TypeReference(org.jikesrvm.classloader.TypeReference) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException)

Example 2 with MethodOperand

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

the class SimpleEscape method checkEscapesThread.

/**
 * Checks a single use, to see if this use may cause the object
 * referenced to escape from this thread.
 *
 * @param use the use to check
 * @param ir the governing IR
 * @param visited visited registers
 * @return {@code true} if it may escape, {@code false} otherwise
 */
private static boolean checkEscapesThread(RegisterOperand use, IR ir, Set<Register> visited) {
    Instruction inst = use.instruction;
    switch(inst.getOpcode()) {
        case INT_ASTORE_opcode:
        case LONG_ASTORE_opcode:
        case FLOAT_ASTORE_opcode:
        case DOUBLE_ASTORE_opcode:
        case BYTE_ASTORE_opcode:
        case SHORT_ASTORE_opcode:
        case REF_ASTORE_opcode:
            // as long as we don't store this operand elsewhere, all
            // is OK
            Operand value = AStore.getValue(inst);
            return value == use;
        case GETFIELD_opcode:
        case GETSTATIC_opcode:
        case INT_ALOAD_opcode:
        case LONG_ALOAD_opcode:
        case FLOAT_ALOAD_opcode:
        case DOUBLE_ALOAD_opcode:
        case BYTE_ALOAD_opcode:
        case UBYTE_ALOAD_opcode:
        case BYTE_LOAD_opcode:
        case UBYTE_LOAD_opcode:
        case SHORT_ALOAD_opcode:
        case USHORT_ALOAD_opcode:
        case SHORT_LOAD_opcode:
        case USHORT_LOAD_opcode:
        case REF_ALOAD_opcode:
        case INT_LOAD_opcode:
        case LONG_LOAD_opcode:
        case FLOAT_LOAD_opcode:
        case DOUBLE_LOAD_opcode:
        case REF_LOAD_opcode:
            // all is OK, unless we load this register from memory
            Operand result = ResultCarrier.getResult(inst);
            return result == use;
        case PUTFIELD_opcode:
            // as long as we don't store this operand elsewhere, all
            // is OK. TODO: add more smarts.
            value = PutField.getValue(inst);
            return value == use;
        case PUTSTATIC_opcode:
            // as long as we don't store this operand elsewhere, all
            // is OK. TODO: add more smarts.
            value = PutStatic.getValue(inst);
            return value == use;
        case BYTE_STORE_opcode:
        case SHORT_STORE_opcode:
        case REF_STORE_opcode:
        case INT_STORE_opcode:
        case LONG_STORE_opcode:
        case FLOAT_STORE_opcode:
        case DOUBLE_STORE_opcode:
            // as long as we don't store this operand elsewhere, all
            // is OK. TODO: add more smarts.
            value = Store.getValue(inst);
            return value == use;
        // escape
        case BOUNDS_CHECK_opcode:
        case MONITORENTER_opcode:
        case MONITOREXIT_opcode:
        case NULL_CHECK_opcode:
        case ARRAYLENGTH_opcode:
        case REF_IFCMP_opcode:
        case INT_IFCMP_opcode:
        case IG_PATCH_POINT_opcode:
        case IG_CLASS_TEST_opcode:
        case IG_METHOD_TEST_opcode:
        case BOOLEAN_CMP_INT_opcode:
        case BOOLEAN_CMP_ADDR_opcode:
        case OBJARRAY_STORE_CHECK_opcode:
        case OBJARRAY_STORE_CHECK_NOTNULL_opcode:
        case GET_OBJ_TIB_opcode:
        case GET_TYPE_FROM_TIB_opcode:
        case NEW_opcode:
        case NEWARRAY_opcode:
        case NEWOBJMULTIARRAY_opcode:
        case NEW_UNRESOLVED_opcode:
        case NEWARRAY_UNRESOLVED_opcode:
        case INSTANCEOF_opcode:
        case INSTANCEOF_NOTNULL_opcode:
        case INSTANCEOF_UNRESOLVED_opcode:
        case MUST_IMPLEMENT_INTERFACE_opcode:
        case GET_CAUGHT_EXCEPTION_opcode:
        case IR_PROLOGUE_opcode:
            return false;
        case RETURN_opcode:
            // by caller)
            return !ir.isParameter(use);
        case CALL_opcode:
            MethodOperand mop = Call.getMethod(inst);
            if (mop == null) {
                return true;
            }
            if (!mop.hasPreciseTarget()) {
                // if we're not sure of the dynamic target, give up
                return true;
            }
            // pure methods don't let object escape
            if (mop.getTarget().isPure()) {
                return false;
            }
            // Assume non-annotated native methods let object escape
            if (mop.getTarget().isNative()) {
                return true;
            }
            // try to get a method summary for the called method
            MethodSummary summ = getMethodSummaryIfAvailable(mop.getTarget(), ir.options);
            if (summ == null) {
                // couldn't get one. assume the object escapes
                return true;
            }
            // if use is result of the call...
            if (use == Call.getResult(inst)) {
                return summ.resultMayEscapeThread();
            }
            // use is a parameter to the call.  Find out which one.
            int p = getParameterIndex(use, inst);
            return summ.parameterMayEscapeThread(p);
        case CHECKCAST_opcode:
        case CHECKCAST_NOTNULL_opcode:
        case CHECKCAST_UNRESOLVED_opcode:
        case REF_MOVE_opcode:
            {
                Register copy = ResultCarrier.getResult(inst).getRegister();
                if (!copy.isSSA()) {
                    return true;
                } else {
                    if (visited == null) {
                        visited = new HashSet<Register>();
                    }
                    visited.add(use.getRegister());
                    if (visited.contains(copy)) {
                        return false;
                    } else {
                        return checkIfUseEscapesThread(copy, ir, visited);
                    }
                }
            }
        case ATHROW_opcode:
        case PREPARE_INT_opcode:
        case PREPARE_ADDR_opcode:
        case PREPARE_LONG_opcode:
        case ATTEMPT_LONG_opcode:
        case ATTEMPT_INT_opcode:
        case ATTEMPT_ADDR_opcode:
        case INT_MOVE_opcode:
        case INT_ADD_opcode:
        case REF_ADD_opcode:
        case INT_MUL_opcode:
        case INT_DIV_opcode:
        case INT_REM_opcode:
        case INT_NEG_opcode:
        case INT_ZERO_CHECK_opcode:
        case INT_OR_opcode:
        case INT_AND_opcode:
        case INT_XOR_opcode:
        case REF_OR_opcode:
        case REF_AND_opcode:
        case REF_XOR_opcode:
        case INT_SUB_opcode:
        case REF_SUB_opcode:
        case INT_SHL_opcode:
        case INT_SHR_opcode:
        case INT_USHR_opcode:
        case SYSCALL_opcode:
        case REF_SHL_opcode:
        case REF_SHR_opcode:
        case REF_USHR_opcode:
        case SET_CAUGHT_EXCEPTION_opcode:
        case PHI_opcode:
        case INT_2LONG_opcode:
        case REF_COND_MOVE_opcode:
        case INT_COND_MOVE_opcode:
        case INT_2ADDRSigExt_opcode:
        case INT_2ADDRZerExt_opcode:
        case ADDR_2INT_opcode:
        case ADDR_2LONG_opcode:
        case LONG_OR_opcode:
        case LONG_AND_opcode:
        case LONG_XOR_opcode:
        case LONG_SUB_opcode:
        case LONG_SHL_opcode:
        case LONG_ADD_opcode:
        case LONG_SHR_opcode:
        case LONG_USHR_opcode:
        case LONG_NEG_opcode:
        case LONG_MOVE_opcode:
        case LONG_2ADDR_opcode:
        // TODO: add more smarts
        case YIELDPOINT_OSR_opcode:
            // we do not know exactly, so be conservative
            return true;
        default:
            if (VM.BuildForPowerPC) {
                switch(inst.getOpcode()) {
                    case DCBST_opcode:
                    case DCBT_opcode:
                    case DCBTST_opcode:
                    case DCBZ_opcode:
                    case DCBZL_opcode:
                    case ICBI_opcode:
                        return false;
                }
            } else {
                switch(inst.getOpcode()) {
                    case PREFETCH_opcode:
                        return false;
                }
            }
            throw new OptimizingCompilerException("SimpleEscapge: Unexpected " + inst);
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) HashSet(java.util.HashSet)

Example 3 with MethodOperand

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

the class Instruction method isNonPureCall.

/**
 * Is the instruction a call but not a pure call (one kind of interprocedural branch)?
 *
 * @return <code>true</code> if the instruction is a nonpure call
 *         or <code>false</code> if it is not.
 */
public boolean isNonPureCall() {
    if (operator.isCall()) {
        MethodOperand methOp = Call.getMethod(this);
        boolean isPure = methOp != null && methOp.hasPreciseTarget() && methOp.getTarget().isPure();
        return !isPure;
    }
    return false;
}
Also used : MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 4 with MethodOperand

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

the class BURS_Helpers method mutateTrapToCall.

private void mutateTrapToCall(Instruction s, RVMMethod target) {
    Offset offset = target.getOffset();
    RegisterOperand tmp = regpool.makeTemp(TypeReference.JavaLangObjectArray);
    Register JTOC = regpool.getPhysicalRegisterSet().asPPC().getJTOC();
    MethodOperand meth = MethodOperand.STATIC(target);
    meth.setIsNonReturningCall(true);
    int valueLow = PPCMaskLower16(offset);
    if (fits(offset, 16)) {
        EMIT(MIR_Load.create(PPC_LAddr, tmp, A(JTOC), IC(valueLow)));
    } else {
        int valueHigh = PPCMaskUpper16(offset);
        if (VM.VerifyAssertions)
            VM._assert(fits(offset, 32));
        Register reg = regpool.getAddress();
        EMIT(MIR_Binary.create(PPC_ADDIS, A(reg), A(JTOC), IC(valueHigh)));
        EMIT(MIR_Load.create(PPC_LAddr, tmp, A(reg), IC(valueLow)));
    }
    EMIT(MIR_Move.create(PPC_MTSPR, A(CTR), tmp.copyD2U()));
    EMIT(MIR_Call.mutate0(s, PPC_BCTRL, null, null, meth));
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) Offset(org.vmmagic.unboxed.Offset) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 5 with MethodOperand

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

the class GenerationContextTest method childContextsQueryOSRBarrierInformationViaOutermostParent.

@Test
public void childContextsQueryOSRBarrierInformationViaOutermostParent() throws Exception {
    NormalMethod nm = getNormalMethodForTest("methodForInliningTests");
    CompiledMethod cm = new OptCompiledMethod(-1, nm);
    OptOptions opts = new OptOptions();
    InlineOracle io = new DefaultInlineOracle();
    GenerationContext outermost = new GenerationContext(nm, null, cm, opts, io);
    Class<?>[] classArgs = { Object.class };
    NormalMethod callee = getNormalMethodForTest("emptyStaticMethodWithObjectParamAndReturnValue", classArgs);
    MethodOperand methOp = MethodOperand.STATIC(callee);
    RegisterOperand result = createMockRegisterOperand(TypeReference.JavaLangObject);
    Instruction callInstr = Call.create(CALL, result, null, methOp, 1);
    RegisterOperand objectParam = createMockRegisterOperand(TypeReference.JavaLangObject);
    Call.setParam(callInstr, 0, objectParam);
    callInstr.setPosition(new InlineSequence(nm));
    ExceptionHandlerBasicBlockBag ebag = getMockEbag();
    GenerationContext child = outermost.createChildContext(ebag, callee, callInstr);
    Instruction osrBarrier = createMockOSRBarrier();
    Instruction call = createMockCall();
    child.saveOSRBarrierForInst(osrBarrier, call);
    assertThat(outermost.getOSRBarrierFromInst(call), is(osrBarrier));
    assertThat(child.getOSRBarrierFromInst(call), is(osrBarrier));
    GenerationContext child2 = outermost.createChildContext(ebag, callee, callInstr);
    assertThat(child2.getOSRBarrierFromInst(call), is(osrBarrier));
}
Also used : OptCompiledMethod(org.jikesrvm.compilers.opt.runtimesupport.OptCompiledMethod) DefaultInlineOracle(org.jikesrvm.compilers.opt.inlining.DefaultInlineOracle) InlineOracle(org.jikesrvm.compilers.opt.inlining.InlineOracle) 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) Test(org.junit.Test)

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