Search in sources :

Example 11 with NullConstantOperand

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

the class NormalizeConstants method perform.

/**
 * Only thing we do for IA32 is to restrict the usage of
 * String, Float, and Double constants.  The rules are prepared
 * to deal with everything else.
 *
 * @param ir IR to normalize
 */
public static void perform(IR ir) {
    for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
        // Get 'large' constants into a form the the BURS rules are
        // prepared to deal with.
        // Constants can't appear as defs, so only scan the uses.
        // 
        int numUses = s.getNumberOfUses();
        if (numUses > 0) {
            int numDefs = s.getNumberOfDefs();
            for (int idx = numDefs; idx < numUses + numDefs; idx++) {
                Operand use = s.getOperand(idx);
                if (use != null) {
                    if (use instanceof ObjectConstantOperand) {
                        ObjectConstantOperand oc = (ObjectConstantOperand) use;
                        if (oc.isMovableObjectConstant()) {
                            RegisterOperand rop = ir.regpool.makeTemp(use.getType());
                            Operand jtoc = ir.regpool.makeJTOCOp();
                            Offset offset = oc.offset;
                            if (offset.isZero()) {
                                if (use instanceof StringConstantOperand) {
                                    throw new OptimizingCompilerException("String constant w/o valid JTOC offset");
                                } else if (use instanceof ClassConstantOperand) {
                                    throw new OptimizingCompilerException("Class constant w/o valid JTOC offset");
                                }
                                offset = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(oc.value));
                            }
                            LocationOperand loc = new LocationOperand(offset);
                            s.insertBefore(Load.create(IA32_REF_LOAD, rop, jtoc, wordOperandForReference(offset.toWord()), loc));
                            s.putOperand(idx, rop.copyD2U());
                        } else {
                            // Ensure object is in JTOC to keep it alive
                            Statics.findOrCreateObjectLiteral(oc.value);
                            s.putOperand(idx, wordOperandForReference(Magic.objectAsAddress(oc.value).toWord()));
                        }
                    } else if (use instanceof DoubleConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Double);
                        Operand jtoc = ir.regpool.makeJTOCOp();
                        DoubleConstantOperand dc = (DoubleConstantOperand) use.copy();
                        if (dc.offset.isZero()) {
                            dc.offset = Offset.fromIntSignExtend(Statics.findOrCreateLongSizeLiteral(Double.doubleToLongBits(dc.value)));
                        }
                        s.insertBefore(Binary.create(MATERIALIZE_FP_CONSTANT, rop, jtoc, dc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof FloatConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Float);
                        Operand jtoc = ir.regpool.makeJTOCOp();
                        FloatConstantOperand fc = (FloatConstantOperand) use.copy();
                        if (fc.offset.isZero()) {
                            fc.offset = Offset.fromIntSignExtend(Statics.findOrCreateIntSizeLiteral(Float.floatToIntBits(fc.value)));
                        }
                        s.insertBefore(Binary.create(MATERIALIZE_FP_CONSTANT, rop, jtoc, fc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof NullConstantOperand) {
                        s.putOperand(idx, wordOperandForReference(Word.zero()));
                    } else if (use instanceof AddressConstantOperand) {
                        s.putOperand(idx, wordOperandForReference(((AddressConstantOperand) use).value.toWord()));
                    } else if (use instanceof TIBConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.TIB);
                        Operand jtoc = ir.regpool.makeJTOCOp();
                        Offset offset = ((TIBConstantOperand) use).value.getTibOffset();
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(IA32_REF_LOAD, rop, jtoc, wordOperandForReference(offset.toWord()), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof CodeConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.CodeArray);
                        Operand jtoc = ir.regpool.makeJTOCOp();
                        Offset offset = ((CodeConstantOperand) use).value.findOrCreateJtocOffset();
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(IA32_REF_LOAD, rop, jtoc, wordOperandForReference(offset.toWord()), loc));
                        s.putOperand(idx, rop.copyD2U());
                    }
                }
            }
        }
    }
}
Also used : StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) Offset(org.vmmagic.unboxed.Offset) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)

Example 12 with NullConstantOperand

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

the class DynamicTypeCheckExpansion method arrayStoreCheck.

/**
 * Expand an object array store check into the LIR sequence that
 * implements it.
 *
 * @param s an OBJARRAY_STORE_CHECK instruction to expand
 * @param ir the enclosing IR
 * @param couldBeNull is it possible that the element being stored is null?
 * @return the last Instruction in the generated LIR sequence.
 */
static Instruction arrayStoreCheck(Instruction s, IR ir, boolean couldBeNull) {
    RegisterOperand guardResult = StoreCheck.getGuardResult(s);
    Operand arrayRef = StoreCheck.getClearRef(s);
    Operand elemRef = StoreCheck.getClearVal(s);
    Operand guard = StoreCheck.getClearGuard(s);
    if (elemRef instanceof NullConstantOperand) {
        Instruction continueAt = s.prevInstructionInCodeOrder();
        s.remove();
        return continueAt;
    }
    BasicBlock myBlock = s.getBasicBlock();
    BasicBlock contBlock = myBlock.splitNodeAt(s, ir);
    BasicBlock trapBlock = myBlock.createSubBlock(s.getBytecodeIndex(), ir, .0001f);
    BasicBlock curBlock = myBlock;
    Move.mutate(s, GUARD_MOVE, guardResult, new TrueGuardOperand());
    // Set up a block with a trap instruction that we can jump to if the
    // store check fails
    Instruction trap = Trap.create(TRAP, null, TrapCodeOperand.StoreCheck());
    trap.copyPosition(s);
    trapBlock.appendInstruction(trap);
    ir.cfg.addLastInCodeOrder(trapBlock);
    Operand rhsGuard = guard;
    if (couldBeNull) {
        // if rhs is null, then the checkcast succeeds
        rhsGuard = ir.regpool.makeTempValidation();
        contBlock.prependInstruction(Binary.create(GUARD_COMBINE, guardResult.copyRO(), guardResult.copyRO(), rhsGuard.copy()));
        curBlock.appendInstruction(IfCmp.create(REF_IFCMP, rhsGuard.asRegister(), elemRef, new NullConstantOperand(), ConditionOperand.EQUAL(), contBlock.makeJumpTarget(), new BranchProfileOperand()));
        curBlock.insertOut(contBlock);
        curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
    }
    // Find out what we think the compile time type of the lhs is.
    // Based on this, we can do one of several things:
    // (1) If the compile time element type is a final proper class, then a
    // TIB comparision of the runtime elemRef type and the
    // compile time element type is definitive.
    // (2) If the compile time type is known to be the declared type,
    // then inject a short-circuit test to see if the
    // runtime lhs type is the same as the compile-time lhs type.
    // (3) If the compile time element type is a proper class other than
    // java.lang.Object, then a subclass test of the runtime LHS elem type
    // and the runtime elemRef type is definitive.  Note: we must exclude
    // java.lang.Object because if the compile time element type is
    // java.lang.Object, then the runtime-element type might actually be
    // an interface (ie not a proper class), and we won't be testing the right thing!
    // If we think the compile time type is JavaLangObjectType then
    // we lost type information due to unloaded classes causing
    // imprecise meets.  This should only happen once in a blue moon,
    // so don't bother trying anything clever when it does.
    RVMType compType = arrayRef.getType().peekType();
    if (compType != null && !compType.isJavaLangObjectType()) {
        // optionally (1) from above
        if (compType.getDimensionality() == 1) {
            RVMClass etc = (RVMClass) compType.asArray().getElementType();
            if (etc.isResolved() && etc.isFinal()) {
                if (VM.VerifyAssertions)
                    VM._assert(!etc.isInterface());
                Operand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());
                Operand etTIB = getTIB(curBlock.lastInstruction(), ir, etc);
                curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), rhsTIB, etTIB, ConditionOperand.NOT_EQUAL(), trapBlock.makeJumpTarget(), BranchProfileOperand.never()));
                curBlock.insertOut(trapBlock);
                curBlock.insertOut(contBlock);
                ir.cfg.linkInCodeOrder(curBlock, contBlock);
                return curBlock.lastInstruction();
            }
        }
        // optionally (2) from above
        Operand lhsTIB = getTIB(curBlock.lastInstruction(), ir, arrayRef, guard);
        if (((arrayRef instanceof RegisterOperand) && ((RegisterOperand) arrayRef).isDeclaredType()) || compType == RVMType.JavaLangObjectArrayType) {
            Operand declTIB = getTIB(curBlock.lastInstruction(), ir, compType);
            curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), declTIB, lhsTIB, ConditionOperand.EQUAL(), contBlock.makeJumpTarget(), new BranchProfileOperand()));
            curBlock.insertOut(contBlock);
            curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
        }
        // On our way to doing (3) from above attempt another short-circuit.
        // If lhsElemTIB == rhsTIB, then we are done.
        Operand rhsTIB = getTIB(curBlock.lastInstruction(), ir, elemRef.copy(), rhsGuard.copy());
        RegisterOperand lhsElemTIB = InsertUnary(curBlock.lastInstruction(), ir, GET_ARRAY_ELEMENT_TIB_FROM_TIB, TypeReference.TIB, lhsTIB.copy());
        curBlock.appendInstruction(IfCmp.create(REF_IFCMP, guardResult.copyRO(), rhsTIB, lhsElemTIB, ConditionOperand.EQUAL(), contBlock.makeJumpTarget(), new BranchProfileOperand()));
        curBlock.insertOut(contBlock);
        curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
        // Optionally (3) from above
        if (compType.getDimensionality() == 1) {
            RVMClass etc = (RVMClass) compType.asArray().getElementType();
            if (etc.isResolved() && !etc.isInterface() && !etc.isJavaLangObjectType()) {
                RegisterOperand lhsElemType = InsertUnary(curBlock.lastInstruction(), ir, GET_TYPE_FROM_TIB, TypeReference.Type, lhsElemTIB.copyU2U());
                RegisterOperand rhsSuperclassIds = InsertUnary(curBlock.lastInstruction(), ir, GET_SUPERCLASS_IDS_FROM_TIB, TypeReference.ShortArray, rhsTIB.copy());
                RegisterOperand lhsElemDepth = getField(curBlock.lastInstruction(), ir, lhsElemType, Entrypoints.depthField, TG());
                RegisterOperand rhsSuperclassIdsLength = InsertGuardedUnary(curBlock.lastInstruction(), ir, ARRAYLENGTH, TypeReference.Int, rhsSuperclassIds.copyD2U(), TG());
                curBlock.appendInstruction(IfCmp.create(INT_IFCMP, guardResult.copyRO(), lhsElemDepth, rhsSuperclassIdsLength, ConditionOperand.GREATER_EQUAL(), trapBlock.makeJumpTarget(), BranchProfileOperand.never()));
                curBlock.insertOut(trapBlock);
                curBlock = advanceBlock(s.getBytecodeIndex(), curBlock, ir);
                RegisterOperand lhsElemId = getField(curBlock.lastInstruction(), ir, lhsElemType.copyD2U(), Entrypoints.idField, TG());
                RegisterOperand refCandidate = ir.regpool.makeTemp(TypeReference.Short);
                LocationOperand loc = new LocationOperand(TypeReference.Short);
                if (LOWER_ARRAY_ACCESS) {
                    RegisterOperand lhsDepthOffset = insertBinary(curBlock.lastInstruction(), ir, INT_SHL, TypeReference.Int, lhsElemDepth.copyD2U(), IC(1));
                    lhsDepthOffset = InsertUnary(curBlock.lastInstruction(), ir, INT_2ADDRZerExt, TypeReference.Offset, lhsDepthOffset.copy());
                    curBlock.appendInstruction(Load.create(USHORT_LOAD, refCandidate, rhsSuperclassIds, lhsDepthOffset, loc, TG()));
                } else {
                    curBlock.appendInstruction(ALoad.create(USHORT_ALOAD, refCandidate, rhsSuperclassIds, lhsElemDepth.copyRO(), loc, TG()));
                }
                curBlock.appendInstruction(IfCmp.create(INT_IFCMP, guardResult.copyRO(), refCandidate.copyD2U(), lhsElemId, ConditionOperand.NOT_EQUAL(), trapBlock.makeJumpTarget(), BranchProfileOperand.never()));
                curBlock.insertOut(trapBlock);
                curBlock.insertOut(contBlock);
                ir.cfg.linkInCodeOrder(curBlock, contBlock);
                return curBlock.lastInstruction();
            }
        }
    }
    // Call RuntimeEntrypoints.checkstore.
    RVMMethod target = Entrypoints.checkstoreMethod;
    Instruction call = Call.create2(CALL, null, AC(target.getOffset()), MethodOperand.STATIC(target), rhsGuard.copy(), arrayRef.copy(), elemRef.copy());
    call.copyPosition(s);
    curBlock.appendInstruction(call);
    curBlock.insertOut(contBlock);
    ir.cfg.linkInCodeOrder(curBlock, contBlock);
    return callHelper(call, ir);
}
Also used : NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) RVMMethod(org.jikesrvm.classloader.RVMMethod) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) 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) 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) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) RVMClass(org.jikesrvm.classloader.RVMClass)

Example 13 with NullConstantOperand

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

the class DynamicTypeCheckExpansion method checkcast.

/**
 * Expand a checkcast instruction into the LIR sequence that implements the
 * dynamic type check, raising a ClassCastException when the type check
 * fails. Ref may contain a null ptr at runtime.
 *
 * @param s a CHECKCAST or CHECKCAST_UNRESOLVED instruction to expand
 * @param ir the enclosing IR
 * @return the last Instruction in the generated LIR sequence.
 */
static Instruction checkcast(Instruction s, IR ir) {
    Operand ref = TypeCheck.getClearRef(s);
    TypeReference LHStype = TypeCheck.getType(s).getTypeRef();
    RegisterOperand guard = ir.regpool.makeTempValidation();
    Instruction nullCond = IfCmp.create(REF_IFCMP, guard, ref.copy(), new NullConstantOperand(), ConditionOperand.EQUAL(), null, // KLUDGE...we haven't created the block yet!
    new BranchProfileOperand());
    s.insertBefore(nullCond);
    BasicBlock myBlock = s.getBasicBlock();
    BasicBlock failBlock = myBlock.createSubBlock(s.getBytecodeIndex(), ir, .0001f);
    BasicBlock instanceOfBlock = myBlock.splitNodeAt(nullCond, ir);
    BasicBlock succBlock = instanceOfBlock.splitNodeAt(s, ir);
    succBlock.firstInstruction().insertAfter(Move.create(REF_MOVE, TypeCheck.getClearResult(s), ref.copy()));
    // fixup KLUDGE
    IfCmp.setTarget(nullCond, succBlock.makeJumpTarget());
    myBlock.insertOut(instanceOfBlock);
    myBlock.insertOut(succBlock);
    instanceOfBlock.insertOut(failBlock);
    instanceOfBlock.insertOut(succBlock);
    ir.cfg.linkInCodeOrder(myBlock, instanceOfBlock);
    ir.cfg.linkInCodeOrder(instanceOfBlock, succBlock);
    ir.cfg.addLastInCodeOrder(failBlock);
    Instruction raiseError = Trap.create(TRAP, null, TrapCodeOperand.CheckCast());
    raiseError.copyPosition(s);
    failBlock.appendInstruction(raiseError);
    Operand RHStib = getTIB(s, ir, ref, guard.copyD2U());
    return generateBranchingTypeCheck(s, ir, ref.copy(), LHStype, RHStib, succBlock, failBlock, guard.copyRO(), BranchProfileOperand.never());
}
Also used : NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) 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) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)13 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)12 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)11 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)10 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)9 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)8 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)8 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)8 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)8 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)7 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)7 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)7 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)7 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)7 TypeReference (org.jikesrvm.classloader.TypeReference)6 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)6 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)5 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)5 RVMType (org.jikesrvm.classloader.RVMType)4