Search in sources :

Example 6 with TrueGuardOperand

use of org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand 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)

Example 7 with TrueGuardOperand

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

the class GenerationContext method createChildContext.

/**
 * Creates a child generation context from this context
 * and callerBB to generate IR for callsite.
 *
 * @param ebag the enclosing exception handlers (null if none)
 * @param callee the callee method to be inlined
 *        (may _not_ be equal to Call.getMethod(callSite).method)
 * @param callSite the Call instruction to be inlined.
 * @return the child context
 */
public GenerationContext createChildContext(ExceptionHandlerBasicBlockBag ebag, NormalMethod callee, Instruction callSite) {
    // Note: In this method, use "this" explicitly to refer to parent fields in order
    // to avoid confusing parent/child fields.
    GenerationContext child = new GenerationContext();
    child.method = callee;
    if (this.options.frequencyCounters() || this.options.inverseFrequencyCounters()) {
        child.branchProfiles = EdgeCounts.getBranchProfiles(callee);
    }
    child.parent = this;
    child.original_cm = this.original_cm;
    // Some state gets directly copied to the child
    child.options = this.options;
    child.temps = this.temps;
    child._ncGuards = this._ncGuards;
    child.exit = this.exit;
    child.inlinePlan = this.inlinePlan;
    // Now inherit state based on callSite
    child.inlineSequence = new InlineSequence(child.method, callSite.position(), callSite);
    child.enclosingHandlers = ebag;
    child.arguments = new Operand[Call.getNumberOfParams(callSite)];
    for (int i = 0; i < child.arguments.length; i++) {
        // copy instead
        child.arguments[i] = Call.getParam(callSite, i).copy();
    // of clearing in case inlining aborts.
    }
    if (Call.hasResult(callSite)) {
        child.resultReg = Call.getResult(callSite).copyD2D().getRegister();
        // it will...
        child.resultReg.setSpansBasicBlock();
    }
    // Initialize the child CFG, prologue, and epilogue blocks
    child.cfg = new ControlFlowGraph(this.cfg.numberOfNodes());
    child.prologue = new BasicBlock(PROLOGUE_BCI, child.inlineSequence, child.cfg);
    child.prologue.setExceptionHandlers(ebag);
    child.epilogue = new BasicBlock(EPILOGUE_BCI, child.inlineSequence, child.cfg);
    child.epilogue.setExceptionHandlers(ebag);
    child.cfg.addLastInCodeOrder(child.prologue);
    child.cfg.addLastInCodeOrder(child.epilogue);
    // Set up the local pool
    child.initLocalPool();
    // Insert moves from child.arguments to child's locals in prologue
    TypeReference[] params = child.method.getParameterTypes();
    int numParams = params.length;
    int argIdx = 0;
    int localNum = 0;
    if (!child.method.isStatic()) {
        Operand receiver = child.arguments[argIdx];
        argIdx++;
        RegisterOperand local = null;
        if (receiver.isRegister()) {
            RegisterOperand objPtr = receiver.asRegister();
            if (ClassLoaderProxy.includesType(child.method.getDeclaringClass().getTypeRef(), objPtr.getType()) != YES) {
                // narrow type of actual to match formal static type implied by method
                // Can be precise but not assignable if enough classes aren't loaded
                objPtr.clearPreciseType();
                objPtr.setDeclaredType();
                objPtr.setType(child.method.getDeclaringClass().getTypeRef());
            }
            local = child.makeLocal(localNum, objPtr);
            localNum++;
            // Avoid confusion in BC2IR of callee
            child.arguments[0] = local;
        // when objPtr is a local in the caller.
        } else if (receiver.isConstant()) {
            local = child.makeLocal(localNum, receiver.getType());
            localNum++;
            local.setPreciseType();
            // Constants trivially non-null
            RegisterOperand guard = child.makeNullCheckGuard(local.getRegister());
            BC2IR.setGuardForRegOp(local, guard);
            child.prologue.appendInstruction(Move.create(GUARD_MOVE, guard.copyRO(), new TrueGuardOperand()));
        } else {
            OptimizingCompilerException.UNREACHABLE("Unexpected receiver operand");
        }
        Instruction s = Move.create(REF_MOVE, local, receiver);
        s.setSourcePosition(PROLOGUE_BCI, callSite.position());
        child.prologue.appendInstruction(s);
    }
    for (int paramIdx = 0; paramIdx < numParams; paramIdx++, argIdx++) {
        TypeReference argType = params[paramIdx];
        RegisterOperand formal;
        Operand actual = child.arguments[argIdx];
        if (actual.isRegister()) {
            RegisterOperand rActual = actual.asRegister();
            if (ClassLoaderProxy.includesType(argType, rActual.getType()) != YES) {
                // narrow type of actual to match formal static type implied by method
                // Can be precise but not
                rActual.clearPreciseType();
                // assignable if enough classes aren't loaded
                rActual.setDeclaredType();
                rActual.setType(argType);
            }
            formal = child.makeLocal(localNum, rActual);
            localNum++;
            // Avoid confusion in BC2IR of
            child.arguments[argIdx] = formal;
        // callee when arg is a local in the caller.
        } else {
            formal = child.makeLocal(localNum, argType);
            localNum++;
        }
        Instruction s = Move.create(IRTools.getMoveOp(argType), formal, actual);
        s.setSourcePosition(PROLOGUE_BCI, callSite.position());
        child.prologue.appendInstruction(s);
        if (argType.isLongType() || argType.isDoubleType()) {
            // longs and doubles take two local words
            localNum++;
        }
    }
    child.completePrologue(false);
    child.completeEpilogue(false);
    child.completeExceptionHandlers(false);
    return child;
}
Also used : RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) ControlFlowGraph(org.jikesrvm.compilers.opt.ir.ControlFlowGraph) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) InlineSequence(org.jikesrvm.compilers.opt.inlining.InlineSequence) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 8 with TrueGuardOperand

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

the class GenerationContext method completePrologue.

/**
 * Fills in the rest of the method prologue.
 * PRECONDITION: arguments &amp; temps have been setup/initialized.
 *
 * @param isOutermost is this the outermost context (i.e. not an inlined context)
 */
private void completePrologue(boolean isOutermost) {
    // Deal with Uninteruptible code.
    if (!isOutermost && requiresUnintMarker()) {
        Instruction s = Empty.create(UNINT_BEGIN);
        appendInstruction(prologue, s, PROLOGUE_BCI);
    }
    // since it's the second time reenter
    if (method.isForOsrSpecialization()) {
    // do nothing
    } else if (method.isSynchronized() && !options.ESCAPE_INVOKEE_THREAD_LOCAL) {
        Operand lockObject = getLockObject();
        Instruction s = MonitorOp.create(MONITORENTER, lockObject, new TrueGuardOperand());
        appendInstruction(prologue, s, SYNCHRONIZED_MONITORENTER_BCI);
    }
}
Also used : MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 9 with TrueGuardOperand

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

the class GenerateMachineSpecificMagic method generateMagic.

/**
 * "Semantic inlining" of methods of the Magic class.
 * Based on the methodName, generate a sequence of opt instructions
 * that implement the magic, updating the stack as necessary
 *
 * @param bc2ir the bc2ir object generating the ir containing this magic
 * @param gc == bc2ir.gc
 * @param meth the RVMMethod that is the magic method
 * @return {@code true} if and only if magic was generated
 */
public static boolean generateMagic(BC2IR bc2ir, GenerationContext gc, MethodReference meth) throws MagicNotImplementedException {
    Atom methodName = meth.getName();
    PhysicalRegisterSet phys = gc.getTemps().getPhysicalRegisterSet().asIA32();
    if (methodName == MagicNames.getESIAsThread) {
        RegisterOperand rop = gc.getTemps().makeTROp();
        bc2ir.markGuardlessNonNull(rop);
        bc2ir.push(rop);
    } else if (methodName == MagicNames.setESIAsThread) {
        Operand val = bc2ir.popRef();
        if (val instanceof RegisterOperand) {
            bc2ir.appendInstruction(Move.create(REF_MOVE, gc.getTemps().makeTROp(), val));
        } else {
            String msg = " Unexpected operand Magic.setESIAsThread";
            throw MagicNotImplementedException.UNEXPECTED(msg);
        }
    } else if (methodName == MagicNames.getFramePointer) {
        gc.forceFrameAllocation();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        RVMField f = ArchEntrypoints.framePointerField;
        RegisterOperand pr = new RegisterOperand(phys.getESI(), TypeReference.Address);
        bc2ir.appendInstruction(GetField.create(GETFIELD, val, pr.copy(), new AddressConstantOperand(f.getOffset()), new LocationOperand(f), new TrueGuardOperand()));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.getJTOC || methodName == MagicNames.getTocPointer) {
        TypeReference t = (methodName == MagicNames.getJTOC ? TypeReference.IntArray : TypeReference.Address);
        RegisterOperand val = gc.getTemps().makeTemp(t);
        AddressConstantOperand addr = new AddressConstantOperand(Magic.getTocPointer());
        bc2ir.appendInstruction(Move.create(REF_MOVE, val, addr));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.synchronizeInstructionCache) {
    // nothing required on Intel
    } else if (methodName == MagicNames.prefetch) {
        bc2ir.appendInstruction(CacheOp.create(PREFETCH, bc2ir.popAddress()));
    } else if (methodName == MagicNames.pause) {
        bc2ir.appendInstruction(Empty.create(PAUSE));
    } else if (methodName == MagicNames.illegalInstruction) {
        bc2ir.appendInstruction(Empty.create(ILLEGAL_INSTRUCTION));
    } else if (methodName == MagicNames.getCallerFramePointer) {
        Operand fp = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTemp(TypeReference.Address);
        bc2ir.appendInstruction(Load.create(REF_LOAD, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setCallerFramePointer) {
        Operand val = bc2ir.popAddress();
        Operand fp = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(REF_STORE, val, fp, offsetOperand(STACKFRAME_FRAME_POINTER_OFFSET), null));
    } else if (methodName == MagicNames.getCompiledMethodID) {
        Operand fp = bc2ir.popAddress();
        RegisterOperand val = gc.getTemps().makeTempInt();
        bc2ir.appendInstruction(Load.create(INT_LOAD, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
        bc2ir.push(val.copyD2U());
    } else if (methodName == MagicNames.setCompiledMethodID) {
        Operand val = bc2ir.popInt();
        Operand fp = bc2ir.popAddress();
        bc2ir.appendInstruction(Store.create(INT_STORE, val, fp, offsetOperand(STACKFRAME_METHOD_ID_OFFSET), null));
    } else if (methodName == MagicNames.getReturnAddressLocation) {
        Operand fp = bc2ir.popAddress();
        Instruction s = bc2ir._binaryHelper(REF_ADD, fp, offsetOperand(STACKFRAME_RETURN_ADDRESS_OFFSET), TypeReference.Address);
        bc2ir.appendInstruction(s);
    } else {
        // Distinguish between magics that we know we don't implement
        // (and never plan to implement) and those (usually new ones)
        // that we want to be warned that we don't implement.
        String msg = " Magic method not implemented: " + meth;
        if (methodName == MagicNames.returnToNewStack) {
            throw MagicNotImplementedException.EXPECTED(msg);
        } else {
            return false;
        // throw MagicNotImplementedException.UNEXPECTED(msg);
        }
    }
    return true;
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) IRTools.offsetOperand(org.jikesrvm.compilers.opt.ir.IRTools.offsetOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) PhysicalRegisterSet(org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Atom(org.jikesrvm.classloader.Atom) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 10 with TrueGuardOperand

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

the class Simplifier method guardCombine.

private static DefUseEffect guardCombine(Instruction s, OptOptions opts) {
    Operand op1 = Binary.getVal1(s);
    Operand op2 = Binary.getVal2(s);
    if (op1.similar(op2) || (op2 instanceof TrueGuardOperand)) {
        Move.mutate(s, GUARD_MOVE, Binary.getClearResult(s), op1);
        if (op1 instanceof TrueGuardOperand) {
            // BOTH true guards: FOLD
            return DefUseEffect.MOVE_FOLDED;
        } else {
            // ONLY OP2 IS TrueGuard: MOVE REDUCE
            return DefUseEffect.MOVE_REDUCED;
        }
    } else if (op1 instanceof TrueGuardOperand) {
        // ONLY OP1 IS TrueGuard: MOVE REDUCE
        Move.mutate(s, GUARD_MOVE, Binary.getClearResult(s), op2);
        return DefUseEffect.MOVE_REDUCED;
    } else {
        return DefUseEffect.UNCHANGED;
    }
}
Also used : MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Aggregations

TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)26 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)22 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)16 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)11 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)10 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)9 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)9 TypeReference (org.jikesrvm.classloader.TypeReference)8 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)8 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)7 Register (org.jikesrvm.compilers.opt.ir.Register)6 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)6 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)6 ClassConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand)5 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)5 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)5 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)5 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)5 UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)4