Search in sources :

Example 11 with IntConstantOperand

use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand 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 12 with IntConstantOperand

use of org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand 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 13 with IntConstantOperand

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

the class ConvertToLowLevelIR method _lookupswitchHelper.

/**
 * Helper function to generate the binary search tree for
 * a lookupswitch bytecode
 *
 * @param switchInstr the lookupswitch instruction
 * @param defaultBB the basic block of the default case
 * @param ir the ir object
 * @param curBlock the basic block to insert instructions into
 * @param reg the RegisterOperand that contains the valued being switched on
 * @param low the low index of cases (operands of switchInstr)
 * @param high the high index of cases (operands of switchInstr)
 * @param min minimum for the current case
 * @param max maximum for the current case
 * @return the last basic block created
 */
private static BasicBlock _lookupswitchHelper(Instruction switchInstr, RegisterOperand reg, BasicBlock defaultBB, IR ir, BasicBlock curBlock, int low, int high, int min, int max) {
    if (VM.VerifyAssertions) {
        VM._assert(low <= high, "broken control logic in _lookupswitchHelper");
    }
    // find middle
    int middle = (low + high) >> 1;
    // The following are used below to store the computed branch
    // probabilities for the branches that are created to implement
    // the binary search.  Used only if basic block frequencies available
    float lessProb = 0.0f;
    float greaterProb = 0.0f;
    float equalProb = 0.0f;
    float sum = 0.0f;
    // Sum the probabilities for all targets < middle
    for (int i = low; i < middle; i++) {
        lessProb += LookupSwitch.getBranchProfile(switchInstr, i).takenProbability;
    }
    // Sum the probabilities for all targets > middle
    for (int i = middle + 1; i <= high; i++) {
        greaterProb += LookupSwitch.getBranchProfile(switchInstr, i).takenProbability;
    }
    equalProb = LookupSwitch.getBranchProfile(switchInstr, middle).takenProbability;
    // generated may not).
    if (low == 0) {
        lessProb += LookupSwitch.getDefaultBranchProfile(switchInstr).takenProbability;
    }
    // Now normalize them so they are relative to the sum of the
    // branches being considered in this piece of the subtree
    sum = lessProb + equalProb + greaterProb;
    if (sum > 0) {
        // check for divide by zero
        lessProb /= sum;
        equalProb /= sum;
        greaterProb /= sum;
    }
    IntConstantOperand val = LookupSwitch.getClearMatch(switchInstr, middle);
    int value = val.value;
    BasicBlock greaterBlock = middle == high ? defaultBB : curBlock.createSubBlock(0, ir);
    BasicBlock lesserBlock = low == middle ? defaultBB : curBlock.createSubBlock(0, ir);
    // Generate this level of tests
    BranchOperand branch = LookupSwitch.getClearTarget(switchInstr, middle);
    BasicBlock branchBB = branch.target.getBasicBlock();
    curBlock.insertOut(branchBB);
    if (low != high) {
        if (value == min) {
            curBlock.appendInstruction(IfCmp.create(INT_IFCMP, ir.regpool.makeTempValidation(), reg.copy(), val, ConditionOperand.EQUAL(), branchBB.makeJumpTarget(), new BranchProfileOperand(equalProb)));
        } else {
            // To compute the probability of the second compare, the first
            // probability must be removed since the second branch is
            // considered only if the first fails.
            float secondIfProb = 0.0f;
            sum = equalProb + greaterProb;
            if (sum > 0) {
                // if divide by zero, leave as is
                secondIfProb = equalProb / sum;
            }
            curBlock.appendInstruction(IfCmp2.create(INT_IFCMP2, ir.regpool.makeTempValidation(), reg.copy(), val, ConditionOperand.LESS(), lesserBlock.makeJumpTarget(), new BranchProfileOperand(lessProb), ConditionOperand.EQUAL(), branchBB.makeJumpTarget(), new BranchProfileOperand(secondIfProb)));
            curBlock.insertOut(lesserBlock);
        }
    } else {
        // Base case: middle was the only case left to consider
        if (min == max) {
            curBlock.appendInstruction(Goto.create(GOTO, branch));
            curBlock.insertOut(branchBB);
        } else {
            curBlock.appendInstruction(IfCmp.create(INT_IFCMP, ir.regpool.makeTempValidation(), reg.copy(), val, ConditionOperand.EQUAL(), branchBB.makeJumpTarget(), new BranchProfileOperand(equalProb)));
            BasicBlock newBlock = curBlock.createSubBlock(0, ir);
            curBlock.insertOut(newBlock);
            ir.cfg.linkInCodeOrder(curBlock, newBlock);
            curBlock = newBlock;
            curBlock.appendInstruction(defaultBB.makeGOTO());
            curBlock.insertOut(defaultBB);
        }
    }
    // Generate sublevels as needed and splice together instr & bblist
    if (middle < high) {
        curBlock.insertOut(greaterBlock);
        ir.cfg.linkInCodeOrder(curBlock, greaterBlock);
        curBlock = _lookupswitchHelper(switchInstr, reg, defaultBB, ir, greaterBlock, middle + 1, high, value + 1, max);
    }
    if (low < middle) {
        ir.cfg.linkInCodeOrder(curBlock, lesserBlock);
        curBlock = _lookupswitchHelper(switchInstr, reg, defaultBB, ir, lesserBlock, low, middle - 1, min, value - 1);
    }
    return curBlock;
}
Also used : IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

Example 14 with IntConstantOperand

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

Example 15 with IntConstantOperand

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

the class DynamicTypeCheckExpansion method generateBranchingTypeCheck.

/**
 * Generate a branching dynamic type check.
 * This routine assumes that the CFG and code order are already
 * correctly established.
 * This routine must either remove s or mutate it.
 *
 * @param s          The Instruction that is to be replaced by a
 *                   branching type check
 * @param ir         The IR containing the instruction to be expanded.
 * @param RHSobj     The RegisterOperand containing the rhs object.
 * @param LHStype    The TypeReference to be tested against.
 * @param RHStib     The Operand containing the TIB of the rhs.
 * @param trueBlock  The BasicBlock to continue at if the typecheck
 *                   evaluates to true
 * @param falseBlock The BasicBlock to continue at if the typecheck
 *                   evaluates to false.
 * @param oldGuard   A suitable guard operand (not necessarily related
 *                   the instruction that is to be replaced).
 * @param falseProb   The probability that typecheck will branch to the falseBlock
 * @return the opt instruction immediately before the instruction to
 *         continue expansion.
 */
private static Instruction generateBranchingTypeCheck(Instruction s, IR ir, Operand RHSobj, TypeReference LHStype, Operand RHStib, BasicBlock trueBlock, BasicBlock falseBlock, RegisterOperand oldGuard, BranchProfileOperand falseProb) {
    Instruction continueAt = Goto.create(GOTO, trueBlock.makeJumpTarget());
    continueAt.copyPosition(s);
    s.insertBefore(continueAt);
    s.remove();
    if (LHStype.isClassType()) {
        RVMClass LHSclass = (RVMClass) LHStype.peekType();
        if (LHSclass != null && LHSclass.isResolved()) {
            // class or interface
            if (LHSclass.isInterface()) {
                // A resolved interface (case 4)
                int interfaceIndex = LHSclass.getDoesImplementIndex();
                int interfaceMask = LHSclass.getDoesImplementBitMask();
                RegisterOperand doesImpl = InsertUnary(continueAt, ir, GET_DOES_IMPLEMENT_FROM_TIB, TypeReference.IntArray, RHStib);
                if (DynamicTypeCheck.MIN_DOES_IMPLEMENT_SIZE <= interfaceIndex) {
                    RegisterOperand doesImplLength = InsertGuardedUnary(continueAt, ir, ARRAYLENGTH, TypeReference.Int, doesImpl.copyD2U(), TG());
                    Instruction lengthCheck = IfCmp.create(INT_IFCMP, oldGuard, doesImplLength, IC(interfaceIndex), ConditionOperand.LESS_EQUAL(), falseBlock.makeJumpTarget(), BranchProfileOperand.unlikely());
                    if (oldGuard != null) {
                        oldGuard = oldGuard.copyD2D();
                    }
                    continueAt.insertBefore(lengthCheck);
                    BasicBlock oldBlock = continueAt.getBasicBlock();
                    oldBlock.splitNodeWithLinksAt(lengthCheck, ir);
                    // required due to splitNode!
                    oldBlock.insertOut(falseBlock);
                }
                RegisterOperand entry = InsertLoadOffset(continueAt, ir, INT_LOAD, TypeReference.Int, doesImpl, Offset.fromIntZeroExtend(interfaceIndex << 2), new LocationOperand(TypeReference.Int), TG());
                RegisterOperand bit = insertBinary(continueAt, ir, INT_AND, TypeReference.Int, entry, IC(interfaceMask));
                continueAt.insertBefore(IfCmp.create(INT_IFCMP, oldGuard, bit, IC(0), ConditionOperand.EQUAL(), falseBlock.makeJumpTarget(), falseProb));
                return continueAt;
            } else {
                // A resolved class (cases 5 and 6 in DynamicTypeCheck)
                if (LHSclass.isFinal()) {
                    // For a final class, we can do a PTR compare of
                    // rhsTIB and the TIB of the class
                    Operand classTIB = getTIB(continueAt, ir, LHSclass);
                    continueAt.insertBefore(IfCmp.create(REF_IFCMP, oldGuard, RHStib, classTIB, ConditionOperand.NOT_EQUAL(), falseBlock.makeJumpTarget(), falseProb));
                    return continueAt;
                } else {
                    // Do the full blown case 5 or 6 typecheck.
                    int LHSDepth = LHSclass.getTypeDepth();
                    int LHSId = LHSclass.getId();
                    RegisterOperand superclassIds = InsertUnary(continueAt, ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.ShortArray, RHStib);
                    if (DynamicTypeCheck.MIN_SUPERCLASS_IDS_SIZE <= LHSDepth) {
                        RegisterOperand superclassIdsLength = InsertGuardedUnary(continueAt, ir, ARRAYLENGTH, TypeReference.Int, superclassIds.copyD2U(), TG());
                        Instruction lengthCheck = IfCmp.create(INT_IFCMP, oldGuard, superclassIdsLength, IC(LHSDepth), ConditionOperand.LESS(), falseBlock.makeJumpTarget(), BranchProfileOperand.unlikely());
                        if (oldGuard != null) {
                            oldGuard = oldGuard.copyD2D();
                        }
                        continueAt.insertBefore(lengthCheck);
                        BasicBlock oldBlock = continueAt.getBasicBlock();
                        oldBlock.splitNodeWithLinksAt(lengthCheck, ir);
                        // required due to splitNode!
                        oldBlock.insertOut(falseBlock);
                    }
                    RegisterOperand refCandidate = InsertLoadOffset(continueAt, ir, USHORT_LOAD, TypeReference.Short, superclassIds, Offset.fromIntZeroExtend(LHSDepth << 1), new LocationOperand(TypeReference.Short), TG());
                    continueAt.insertBefore(IfCmp.create(INT_IFCMP, oldGuard, refCandidate, IC(LHSId), ConditionOperand.NOT_EQUAL(), falseBlock.makeJumpTarget(), falseProb));
                    return continueAt;
                }
            }
        } else {
            // A non-resolved class or interface. Case 3 of DynamicTypeCheck
            // Branch on the result of a call to
            // RuntimeEntrypoints.instance
            RegisterOperand result = ir.regpool.makeTempInt();
            RVMMethod target = Entrypoints.instanceOfMethod;
            Instruction call = Call.create2(CALL, result, AC(target.getOffset()), MethodOperand.STATIC(target), RHSobj, IC(LHStype.getId()));
            call.copyPosition(continueAt);
            continueAt.insertBefore(call);
            call = callHelper(call, ir);
            continueAt.insertBefore(IfCmp.create(INT_IFCMP, oldGuard, result.copyD2U(), IC(0), ConditionOperand.EQUAL(), falseBlock.makeJumpTarget(), falseProb));
            return continueAt;
        }
    }
    if (LHStype.isArrayType()) {
        // Case 2 of DynamicTypeCheck: LHS is an array.
        RVMArray LHSArray = (RVMArray) LHStype.peekType();
        if (LHSArray != null) {
            Operand classTIB = getTIB(continueAt, ir, LHSArray);
            RVMType innermostElementType = LHSArray.getInnermostElementType();
            if (innermostElementType.isPrimitiveType() || innermostElementType.isUnboxedType() || (innermostElementType.asClass().isResolved() && innermostElementType.asClass().isFinal())) {
                // [^k of primitive or [^k of final class. Just like final classes,
                // a PTR compare of rhsTIB and the TIB of the class gives the answer.
                continueAt.insertBefore(IfCmp.create(REF_IFCMP, oldGuard, RHStib, classTIB, ConditionOperand.NOT_EQUAL(), falseBlock.makeJumpTarget(), falseProb));
                return continueAt;
            }
            // TODO: branch probability calculation is somewhat bogus for this case.
            Instruction shortcircuit = IfCmp.create(REF_IFCMP, oldGuard, RHStib, classTIB, ConditionOperand.EQUAL(), trueBlock.makeJumpTarget(), new BranchProfileOperand());
            if (oldGuard != null) {
                oldGuard = oldGuard.copyD2D();
            }
            continueAt.insertBefore(shortcircuit);
            BasicBlock myBlock = shortcircuit.getBasicBlock();
            BasicBlock mainBlock = myBlock.splitNodeWithLinksAt(shortcircuit, ir);
            // must come after the splitNodeAt
            myBlock.insertOut(trueBlock);
            RegisterOperand rhsType = InsertUnary(continueAt, ir, GET_TYPE_FROM_TIB, TypeReference.Type, RHStib.copy());
            if (innermostElementType.isJavaLangObjectType()) {
                IntConstantOperand lhsDimension = IC(LHStype.getDimensionality());
                RegisterOperand rhsDimension = getField(continueAt, ir, rhsType, Entrypoints.dimensionField);
                Instruction dimTest = IfCmp2.create(INT_IFCMP2, oldGuard, rhsDimension, lhsDimension, ConditionOperand.GREATER(), trueBlock.makeJumpTarget(), ((BranchProfileOperand) falseProb.copy()).flip(), ConditionOperand.LESS(), falseBlock.makeJumpTarget(), (BranchProfileOperand) falseProb.copy());
                if (oldGuard != null) {
                    oldGuard = oldGuard.copyD2D();
                }
                continueAt.insertBefore(dimTest);
                // BasicBlock testBlock =
                mainBlock.splitNodeWithLinksAt(dimTest, ir);
                mainBlock.insertOut(trueBlock);
                mainBlock.insertOut(falseBlock);
                RegisterOperand rhsInnermostElementTypeDimension = getField(continueAt, ir, rhsType.copyU2U(), Entrypoints.innermostElementTypeDimensionField);
                continueAt.insertBefore(IfCmp.create(INT_IFCMP, oldGuard, rhsInnermostElementTypeDimension, IC(0), ConditionOperand.NOT_EQUAL(), falseBlock.makeJumpTarget(), falseProb));
                return continueAt;
            }
        }
        // Not a case we want to handle inline
        RVMMethod target = Entrypoints.instanceOfMethod;
        RegisterOperand callResult = ir.regpool.makeTempInt();
        Instruction call = Call.create2(CALL, callResult, AC(target.getOffset()), MethodOperand.STATIC(target), RHSobj, IC(LHStype.getId()));
        call.copyPosition(continueAt);
        continueAt.insertBefore(call);
        call = callHelper(call, ir);
        continueAt.insertBefore(IfCmp.create(INT_IFCMP, oldGuard, callResult.copyD2U(), IC(0), ConditionOperand.EQUAL(), falseBlock.makeJumpTarget(), falseProb));
        return continueAt;
    }
    OptimizingCompilerException.UNREACHABLE();
    return null;
}
Also used : RVMMethod(org.jikesrvm.classloader.RVMMethod) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) 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) RVMArray(org.jikesrvm.classloader.RVMArray) RVMType(org.jikesrvm.classloader.RVMType) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RVMClass(org.jikesrvm.classloader.RVMClass)

Aggregations

IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)49 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)41 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)28 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)23 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)21 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)21 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)19 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)18 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)17 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)16 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)16 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)15 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)15 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)15 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)14 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)13 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)12 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)11 TypeReference (org.jikesrvm.classloader.TypeReference)10 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)9