Search in sources :

Example 71 with Operand

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

the class ConvertToLowLevelIR method doArrayStore.

/**
 * Expand an array store.
 * @param s the instruction to expand
 * @param ir the containing IR
 * @param op the store operator to use
 * @param logwidth the log base 2 of the element type's size
 */
public static void doArrayStore(Instruction s, IR ir, Operator op, int logwidth) {
    if (LOWER_ARRAY_ACCESS) {
        Operand value = AStore.getClearValue(s);
        Operand array = AStore.getClearArray(s);
        Operand index = AStore.getClearIndex(s);
        Operand offset;
        LocationOperand loc = AStore.getClearLocation(s);
        if (index instanceof IntConstantOperand) {
            // constant propagation
            offset = AC(Address.fromIntZeroExtend(((IntConstantOperand) index).value << logwidth));
        } else {
            if (logwidth != 0) {
                offset = insertBinary(s, ir, INT_SHL, TypeReference.Int, index, IC(logwidth));
                offset = InsertUnary(s, ir, INT_2ADDRZerExt, TypeReference.Offset, offset.copy());
            } else {
                offset = InsertUnary(s, ir, INT_2ADDRZerExt, TypeReference.Offset, index);
            }
        }
        Store.mutate(s, op, value, array, offset, loc, AStore.getClearGuard(s));
    }
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) 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)

Example 72 with Operand

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

the class ConvertToLowLevelIR method resolveMember.

/**
 * Generate the code to resolve a member (field/method) reference.
 * @param s the RESOLVE_MEMBER instruction to expand
 * @param ir the containing ir object
 * @return the last expanded instruction
 */
private static Instruction resolveMember(Instruction s, IR ir) {
    Operand memberOp = Unary.getClearVal(s);
    RegisterOperand offset = Unary.getClearResult(s);
    int dictId;
    if (memberOp instanceof LocationOperand) {
        dictId = ((LocationOperand) memberOp).getFieldRef().getId();
    } else {
        dictId = ((MethodOperand) memberOp).getMemberRef().getId();
    }
    BranchProfileOperand bp = BranchProfileOperand.never();
    BasicBlock predBB = s.getBasicBlock();
    BasicBlock succBB = predBB.splitNodeAt(s.prevInstructionInCodeOrder(), ir);
    BasicBlock testBB = predBB.createSubBlock(s.getBytecodeIndex(), ir, 1f - bp.takenProbability);
    BasicBlock resolveBB = predBB.createSubBlock(s.getBytecodeIndex(), ir, bp.takenProbability);
    s.remove();
    // Get the offset from the appropriate RVMClassLoader array
    // and check to see if it is valid
    RegisterOperand offsetTable = getStatic(testBB.lastInstruction(), ir, Entrypoints.memberOffsetsField);
    testBB.appendInstruction(Load.create(INT_LOAD, offset.copyRO(), offsetTable, AC(Offset.fromIntZeroExtend(dictId << LOG_BYTES_IN_INT)), new LocationOperand(TypeReference.Int), TG()));
    testBB.appendInstruction(Unary.create(INT_2ADDRSigExt, offset, offset.copy()));
    testBB.appendInstruction(IfCmp.create(REF_IFCMP, ir.regpool.makeTempValidation(), offset.copy(), AC(Address.fromIntSignExtend(NEEDS_DYNAMIC_LINK)), ConditionOperand.EQUAL(), resolveBB.makeJumpTarget(), bp));
    // Handle the offset being invalid
    resolveBB.appendInstruction(CacheOp.mutate(s, RESOLVE, memberOp));
    resolveBB.appendInstruction(testBB.makeGOTO());
    // Put together the CFG links & code order
    predBB.insertOut(testBB);
    ir.cfg.linkInCodeOrder(predBB, testBB);
    testBB.insertOut(succBB);
    testBB.insertOut(resolveBB);
    ir.cfg.linkInCodeOrder(testBB, succBB);
    // backedge
    resolveBB.insertOut(testBB);
    // stick resolution code in outer space.
    ir.cfg.addLastInCodeOrder(resolveBB);
    return testBB.lastInstruction();
}
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) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 73 with Operand

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

the class ConvertToLowLevelIR method doArrayLoad.

/**
 * Expand an array load.
 * @param s the instruction to expand
 * @param ir the containing IR
 * @param op the load operator to use
 * @param logwidth the log base 2 of the element type's size
 */
public static void doArrayLoad(Instruction s, IR ir, Operator op, int logwidth) {
    if (LOWER_ARRAY_ACCESS) {
        RegisterOperand result = ALoad.getClearResult(s);
        Operand array = ALoad.getClearArray(s);
        Operand index = ALoad.getClearIndex(s);
        Operand offset;
        LocationOperand loc = ALoad.getClearLocation(s);
        if (index instanceof IntConstantOperand) {
            // constant propagation
            offset = AC(Address.fromIntZeroExtend(((IntConstantOperand) index).value << logwidth));
        } else {
            if (logwidth != 0) {
                offset = insertBinary(s, ir, INT_SHL, TypeReference.Int, index, IC(logwidth));
                offset = InsertUnary(s, ir, INT_2ADDRZerExt, TypeReference.Offset, offset.copy());
            } else {
                offset = InsertUnary(s, ir, INT_2ADDRZerExt, TypeReference.Offset, index);
            }
        }
        Load.mutate(s, op, result, array, offset, loc, ALoad.getClearGuard(s));
    }
}
Also used : LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) 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)

Example 74 with Operand

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

the class ConvertToLowLevelIR method tableswitch.

/**
 * Expand a tableswitch.
 * @param s the instruction to expand
 * @param ir the containing IR
 * @return the last Instruction in the generated LIR sequence.
 */
static Instruction tableswitch(Instruction s, IR ir) {
    Instruction s2;
    int lowLimit = TableSwitch.getLow(s).value;
    int highLimit = TableSwitch.getHigh(s).value;
    int number = highLimit - lowLimit + 1;
    if (VM.VerifyAssertions) {
        // also checks that there are < 2^31 targets
        VM._assert(number > 0);
    }
    Operand val = TableSwitch.getClearValue(s);
    BranchOperand defaultLabel = TableSwitch.getClearDefault(s);
    if (number < ir.options.CONTROL_TABLESWITCH_CUTOFF) {
        // convert into a lookupswitch
        Instruction l = LookupSwitch.create(LOOKUPSWITCH, val, null, null, defaultLabel, TableSwitch.getClearDefaultBranchProfile(s), number * 3);
        for (int i = 0; i < number; i++) {
            LookupSwitch.setMatch(l, i, IC(lowLimit + i));
            LookupSwitch.setTarget(l, i, TableSwitch.getClearTarget(s, i));
            LookupSwitch.setBranchProfile(l, i, TableSwitch.getClearBranchProfile(s, i));
        }
        s.insertAfter(CPOS(s, l));
        return s.remove();
    }
    RegisterOperand reg = val.asRegister();
    BasicBlock BB1 = s.getBasicBlock();
    BasicBlock BB2 = BB1.splitNodeAt(s, ir);
    BasicBlock defaultBB = defaultLabel.target.getBasicBlock();
    /**
     ***** First basic block
     */
    RegisterOperand t;
    if (lowLimit != 0) {
        t = insertBinary(s, ir, INT_ADD, TypeReference.Int, reg, IC(-lowLimit));
    } else {
        t = reg.copyU2U();
    }
    BranchProfileOperand defaultProb = TableSwitch.getClearDefaultBranchProfile(s);
    s.replace(CPOS(s, IfCmp.create(INT_IFCMP, ir.regpool.makeTempValidation(), t, IC(highLimit - lowLimit), ConditionOperand.HIGHER(), defaultLabel, defaultProb)));
    // Reweight branches to account for the default branch going. If
    // the default probability was ALWAYS then when we recompute the
    // weight to be a proportion of the total number of branches.
    final boolean defaultIsAlways = defaultProb.takenProbability >= 1f;
    final float weight = defaultIsAlways ? 1f / number : 1f / (1f - defaultProb.takenProbability);
    /**
     ******** second Basic Block *****
     */
    s2 = CPOS(s, LowTableSwitch.create(LOWTABLESWITCH, t.copyRO(), number * 2));
    boolean containsDefault = false;
    for (int i = 0; i < number; i++) {
        BranchOperand b = TableSwitch.getClearTarget(s, i);
        LowTableSwitch.setTarget(s2, i, b);
        BranchProfileOperand bp = TableSwitch.getClearBranchProfile(s, i);
        if (defaultIsAlways) {
            bp.takenProbability = weight;
        } else {
            bp.takenProbability *= weight;
        }
        LowTableSwitch.setBranchProfile(s2, i, bp);
        if (b.target == defaultLabel.target) {
            containsDefault = true;
        }
    }
    // Fixup the CFG and code order.
    BB1.insertOut(BB2);
    BB1.insertOut(defaultBB);
    ir.cfg.linkInCodeOrder(BB1, BB2);
    if (!containsDefault) {
        BB2.deleteOut(defaultBB);
    }
    // This actually happens (very occasionally), and is easy to test for.
    if (BB2.getNumberOfNormalOut() == 1) {
        BB2.appendInstruction(CPOS(s, Goto.create(GOTO, LowTableSwitch.getClearTarget(s2, 0))));
    } else {
        BB2.appendInstruction(s2);
    }
    // continue at next BB
    s = BB2.lastInstruction();
    return s;
}
Also used : 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) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 75 with Operand

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

the class DynamicTypeCheckExpansion method instanceOf.

/**
 * Expand an instanceof instruction into the LIR sequence that implements
 * the dynamic type check.  Ref may contain a null ptr at runtime.
 *
 * @param s an INSTANCEOF or INSTANCEOF_UNRESOLVED instruction to expand
 * @param ir the enclosing IR
 * @return the last Instruction in the generated LIR sequence.
 */
static Instruction instanceOf(Instruction s, IR ir) {
    RegisterOperand result = InstanceOf.getClearResult(s);
    TypeReference LHStype = InstanceOf.getType(s).getTypeRef();
    Operand ref = InstanceOf.getClearRef(s);
    Instruction next = s.nextInstructionInCodeOrder();
    if (next.operator() == INT_IFCMP && IfCmp.getVal1(next) instanceof RegisterOperand && result.similar(IfCmp.getVal1(next))) {
        // The result of instanceof is being consumed by a conditional branch.
        // Optimize this case by generating a branching type check
        // instead of producing a value.
        // TODO: This is really not safe: suppose the if is NOT the
        // only use of the result of the instanceof.
        // The way to fix this is to add ifInstanceOf and ifNotInstanceOf
        // operators to the IR and have Simple transform
        // instanceof, intIfCmp based on the U/D chains.
        // See defect 2114.
        Operand val2 = IfCmp.getVal2(next);
        if (VM.VerifyAssertions)
            VM._assert(val2.isIntConstant());
        int ival2 = ((IntConstantOperand) val2).value;
        ConditionOperand cond = IfCmp.getCond(next);
        boolean branchCondition = (((ival2 == 0) && (cond.isNOT_EQUAL() || cond.isLESS_EQUAL())) || ((ival2 == 1) && (cond.isEQUAL() || cond.isGREATER_EQUAL())));
        BasicBlock branchBB = next.getBranchTarget();
        RegisterOperand oldGuard = IfCmp.getGuardResult(next);
        next.remove();
        BasicBlock fallThroughBB = fallThroughBB(s, ir);
        BasicBlock falseBranch = branchCondition ? fallThroughBB : branchBB;
        BasicBlock trueBranch = branchCondition ? branchBB : fallThroughBB;
        BranchProfileOperand bp = IfCmp.getClearBranchProfile(next);
        if (branchCondition)
            bp = bp.flip();
        Instruction nullComp = IfCmp.create(REF_IFCMP, oldGuard.copyRO(), ref.copy(), new NullConstantOperand(), ConditionOperand.EQUAL(), falseBranch.makeJumpTarget(), BranchProfileOperand.unlikely());
        s.insertBefore(nullComp);
        BasicBlock myBlock = s.getBasicBlock();
        BasicBlock instanceOfBlock = myBlock.splitNodeAt(nullComp, ir);
        myBlock.insertOut(instanceOfBlock);
        myBlock.insertOut(falseBranch);
        ir.cfg.linkInCodeOrder(myBlock, instanceOfBlock);
        Operand RHStib = getTIB(s, ir, ref, oldGuard.copyRO());
        return generateBranchingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, trueBranch, falseBranch, oldGuard.copy().asRegister(), bp);
    } else {
        // Not a branching pattern
        RegisterOperand guard = ir.regpool.makeTempValidation();
        BasicBlock instanceOfBlock = s.getBasicBlock().segregateInstruction(s, ir);
        BasicBlock prevBB = instanceOfBlock.prevBasicBlockInCodeOrder();
        BasicBlock nextBB = instanceOfBlock.nextBasicBlockInCodeOrder();
        BasicBlock nullCaseBB = instanceOfBlock.createSubBlock(s.getBytecodeIndex(), ir, .01f);
        prevBB.appendInstruction(IfCmp.create(REF_IFCMP, guard, ref.copy(), new NullConstantOperand(), ConditionOperand.EQUAL(), nullCaseBB.makeJumpTarget(), BranchProfileOperand.unlikely()));
        nullCaseBB.appendInstruction(Move.create(INT_MOVE, result.copyD2D(), IC(0)));
        nullCaseBB.appendInstruction(Goto.create(GOTO, nextBB.makeJumpTarget()));
        // Stitch together the CFG; add nullCaseBB to the end of code array.
        prevBB.insertOut(nullCaseBB);
        nullCaseBB.insertOut(nextBB);
        ir.cfg.addLastInCodeOrder(nullCaseBB);
        Operand RHStib = getTIB(s, ir, ref, guard.copyD2U());
        return generateValueProducingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, result);
    }
}
Also used : NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) 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) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TypeReference(org.jikesrvm.classloader.TypeReference) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)355 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)328 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)242 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)217 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)212 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)210 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)207 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)185 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)174 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)165 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)153 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)144 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)143 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)141 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)128 TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)121 UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)117 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)102 CodeConstantOperand (org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)98 Register (org.jikesrvm.compilers.opt.ir.Register)82