Search in sources :

Example 1 with ClassConstantOperand

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

the class NormalizeConstants method perform.

/**
 * Doit.
 *
 * @param ir IR to normalize
 */
public static void perform(IR ir) {
    // This greatly reduces the number of cases we have to worry about below.
    if (VM.VerifyAssertions)
        VM._assert(ir.options.SIMPLIFY_INTEGER_OPS && ir.options.SIMPLIFY_LONG_OPS && ir.options.SIMPLIFY_REF_OPS);
    for (Instruction s = ir.firstInstructionInCodeOrder(); s != null; s = s.nextInstructionInCodeOrder()) {
        // STEP ONE: Get 'large' constants into a form that the PPC 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) {
                        RegisterOperand rop = ir.regpool.makeTemp(use.getType());
                        RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
                        ObjectConstantOperand oc = (ObjectConstantOperand) use;
                        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(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof DoubleConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Double);
                        RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
                        DoubleConstantOperand dc = (DoubleConstantOperand) use;
                        Offset offset = dc.offset;
                        if (offset.isZero()) {
                            offset = Offset.fromIntSignExtend(Statics.findOrCreateLongSizeLiteral(Double.doubleToLongBits(dc.value)));
                        }
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(DOUBLE_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof FloatConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Float);
                        RegisterOperand jtoc = (RegisterOperand) ir.regpool.makeJTOCOp();
                        FloatConstantOperand fc = (FloatConstantOperand) use;
                        Offset offset = fc.offset;
                        if (offset.isZero()) {
                            offset = Offset.fromIntSignExtend(Statics.findOrCreateIntSizeLiteral(Float.floatToIntBits(fc.value)));
                        }
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(FLOAT_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    } else if (use instanceof LongConstantOperand) {
                        if (!VM.BuildFor64Addr) {
                            if (s.getOpcode() != TRAP_IF_opcode) {
                                RegisterOperand rop = ir.regpool.makeTemp(TypeReference.Long);
                                s.insertBefore(Move.create(LONG_MOVE, rop, use.copy()));
                                s.putOperand(idx, rop.copyD2U());
                            }
                        }
                    } else if (use instanceof NullConstantOperand) {
                        s.putOperand(idx, AC(Address.zero()));
                    } else if (use instanceof TIBConstantOperand) {
                        RegisterOperand rop = ir.regpool.makeTemp(TypeReference.JavaLangObjectArray);
                        Operand jtoc = ir.regpool.makeJTOCOp();
                        Offset offset = ((TIBConstantOperand) use).value.getTibOffset();
                        LocationOperand loc = new LocationOperand(offset);
                        s.insertBefore(Load.create(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), 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(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD, rop, jtoc, asImmediateOrRegOffset(AC(offset), s, ir, true), loc));
                        s.putOperand(idx, rop.copyD2U());
                    }
                }
            }
        }
        // Calling Simplifier.simplify ensures that the instruction is
        // in normalized form. This reduces the number of cases we have to
        // worry about (and does last minute constant folding on the off chance
        // we've missed an opportunity...)
        Simplifier.simplify(false, ir.regpool, ir.options, s);
        switch(s.getOpcode()) {
            // ////////
            case REF_STORE_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_STORE : LONG_STORE);
                // On PowerPC, the value being stored must be in a register
                Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
                // Supported addressing modes are quite limited.
                Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
                Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
                break;
            case BYTE_STORE_opcode:
            case SHORT_STORE_opcode:
            case INT_STORE_opcode:
            case LONG_STORE_opcode:
                // On PowerPC, the value being stored must be in a register
                Store.setValue(s, asRegPolymorphic(Store.getClearValue(s), s, ir));
                // Supported addressing modes are quite limited.
                Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
                Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
                break;
            case FLOAT_STORE_opcode:
            case DOUBLE_STORE_opcode:
                // Supported addressing modes are quite limited.
                Store.setAddress(s, asRegAddress(Store.getClearAddress(s), s, ir));
                Store.setOffset(s, asImmediateOrRegOffset(Store.getClearOffset(s), s, ir, true));
                break;
            case REF_LOAD_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_LOAD : LONG_LOAD);
                // Supported addressing modes are quite limited.
                Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
                Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
                break;
            case BYTE_LOAD_opcode:
            case UBYTE_LOAD_opcode:
            case SHORT_LOAD_opcode:
            case USHORT_LOAD_opcode:
            case INT_LOAD_opcode:
            case LONG_LOAD_opcode:
            case FLOAT_LOAD_opcode:
            case DOUBLE_LOAD_opcode:
                // Supported addressing modes are quite limited.
                Load.setAddress(s, asRegAddress(Load.getClearAddress(s), s, ir));
                Load.setOffset(s, asImmediateOrRegOffset(Load.getClearOffset(s), s, ir, true));
                break;
            case ATTEMPT_INT_opcode:
            case ATTEMPT_LONG_opcode:
            case ATTEMPT_ADDR_opcode:
                // On PowerPC, the value being stored must be in a register
                Attempt.setNewValue(s, asRegPolymorphic(Attempt.getClearNewValue(s), s, ir));
                // not used on powerpc.
                Attempt.setOldValue(s, null);
                // Supported addressing modes are quite limited.
                Attempt.setAddress(s, asRegAddress(Attempt.getClearAddress(s), s, ir));
                Attempt.setOffset(s, asRegOffset(Attempt.getClearOffset(s), s, ir));
                break;
            case PREPARE_INT_opcode:
            case PREPARE_LONG_opcode:
            case PREPARE_ADDR_opcode:
                // Supported addressing modes are quite limited.
                Prepare.setAddress(s, asRegAddress(Prepare.getClearAddress(s), s, ir));
                Prepare.setOffset(s, asRegOffset(Prepare.getClearOffset(s), s, ir));
                break;
            case LONG_MOVE_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_MOVE);
                }
                break;
            case INT_MOVE_opcode:
                s.changeOperatorTo(REF_MOVE);
                break;
            case REF_COND_MOVE_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_COND_MOVE : LONG_COND_MOVE);
                break;
            case REF_IFCMP_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_IFCMP : LONG_IFCMP);
                // val1 can't be a constant, val2 must be small enough.
                IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
                IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
            case LONG_IFCMP_opcode:
                if (VM.BuildFor64Addr) {
                    // val1 can't be a constant, val2 must be small enough.
                    IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
                    IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
                }
                break;
            case INT_IFCMP_opcode:
                // val1 can't be a constant, val2 must be small enough.
                IfCmp.setVal1(s, asRegPolymorphic(IfCmp.getClearVal1(s), s, ir));
                IfCmp.setVal2(s, asImmediateOrRegPolymorphic(IfCmp.getClearVal2(s), s, ir, true));
                break;
            case INT_IFCMP2_opcode:
                // val1 can't be a constant, val2 must be small enough.
                IfCmp2.setVal1(s, asRegInt(IfCmp2.getClearVal1(s), s, ir));
                IfCmp2.setVal2(s, asImmediateOrRegInt(IfCmp2.getClearVal2(s), s, ir, true));
                break;
            case BOOLEAN_CMP_INT_opcode:
            case BOOLEAN_CMP_ADDR_opcode:
                // val2 must be small enough.
                BooleanCmp.setVal2(s, asImmediateOrRegPolymorphic(BooleanCmp.getClearVal2(s), s, ir, !BooleanCmp.getCond(s).isUNSIGNED()));
                break;
            case LONG_CMP_opcode:
                Binary.setVal1(s, asRegPolymorphic(Binary.getVal1(s), s, ir));
                Binary.setVal2(s, asRegPolymorphic(Binary.getVal2(s), s, ir));
                break;
            case LONG_ADD_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_ADD);
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
                }
                break;
            case INT_ADD_opcode:
                s.changeOperatorTo(REF_ADD);
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
                break;
            case REF_ADD_opcode:
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, true));
                break;
            case LONG_SUB_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_SUB);
                    Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
                // val2 isn't be constant (if it were, Simplifier would have
                // converted this into an ADD of -Val2).
                }
                break;
            case INT_SUB_opcode:
                s.changeOperatorTo(REF_SUB);
                Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
                // converted this into an ADD of -Val2).
                break;
            case REF_SUB_opcode:
                Binary.setVal1(s, asImmediateOrRegPolymorphic(Binary.getClearVal1(s), s, ir, true));
                // converted this into an ADD of -Val2).
                break;
            case INT_MUL_opcode:
                Binary.setVal2(s, asImmediateOrRegInt(Binary.getClearVal2(s), s, ir, true));
                break;
            case LONG_MUL_opcode:
                if (VM.BuildFor64Addr) {
                    Binary.setVal2(s, asImmediateOrRegLong(Binary.getClearVal2(s), s, ir, true));
                }
                break;
            // seem to expect constant operands at all.
            case INT_REM_opcode:
            case INT_DIV_opcode:
                GuardedBinary.setVal1(s, asRegInt(GuardedBinary.getClearVal1(s), s, ir));
                GuardedBinary.setVal2(s, asRegInt(GuardedBinary.getClearVal2(s), s, ir));
                break;
            case LONG_REM_opcode:
            case LONG_DIV_opcode:
                if (VM.BuildFor64Addr) {
                    GuardedBinary.setVal1(s, asRegLong(GuardedBinary.getClearVal1(s), s, ir));
                    GuardedBinary.setVal2(s, asRegLong(GuardedBinary.getClearVal2(s), s, ir));
                }
                break;
            case LONG_NEG_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_NEG);
                }
                break;
            case INT_NEG_opcode:
                s.changeOperatorTo(REF_NEG);
                break;
            case LONG_NOT_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_NOT);
                }
                break;
            case INT_NOT_opcode:
                s.changeOperatorTo(REF_NOT);
                break;
            case LONG_AND_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_AND);
                    // unsigned immediate
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                }
                break;
            case INT_AND_opcode:
                s.changeOperatorTo(REF_AND);
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_AND_opcode:
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case LONG_OR_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_OR);
                    // unsigned immediate
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                }
                break;
            case INT_OR_opcode:
                s.changeOperatorTo(REF_OR);
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_OR_opcode:
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case LONG_XOR_opcode:
                if (VM.BuildFor64Addr) {
                    s.changeOperatorTo(REF_XOR);
                    // unsigned immediate
                    Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                }
                break;
            case INT_XOR_opcode:
                s.changeOperatorTo(REF_XOR);
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_XOR_opcode:
                // unsigned immediate
                Binary.setVal2(s, asImmediateOrRegPolymorphic(Binary.getClearVal2(s), s, ir, false));
                break;
            case REF_SHL_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHL : LONG_SHL);
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case LONG_SHL_opcode:
                if (VM.BuildFor64Addr) {
                    // Val2 could be a constant, but Val1 apparently can't be.
                    Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                }
                break;
            case INT_SHL_opcode:
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case REF_SHR_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_SHR : LONG_SHR);
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case LONG_SHR_opcode:
                if (VM.BuildFor64Addr) {
                    // Val2 could be a constant, but Val1 apparently can't be.
                    Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                }
                break;
            case INT_SHR_opcode:
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case REF_USHR_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_USHR : LONG_USHR);
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            case LONG_USHR_opcode:
                if (VM.BuildFor64Addr) {
                    // Val2 could be a constant, but Val1 apparently can't be.
                    Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                }
                break;
            case INT_USHR_opcode:
                // Val2 could be a constant, but Val1 apparently can't be.
                Binary.setVal1(s, asRegPolymorphic(Binary.getClearVal1(s), s, ir));
                break;
            // Deal with Simplifier.CF_FLOAT or Simplifier.CF_DOUBLE being false
            case INT_2DOUBLE_opcode:
            case INT_2FLOAT_opcode:
            case INT_BITS_AS_FLOAT_opcode:
                Unary.setVal(s, asRegInt(Unary.getVal(s), s, ir));
                break;
            case ADDR_2INT_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : LONG_2INT);
                break;
            case ADDR_2LONG_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? INT_2LONG : REF_MOVE);
                break;
            case INT_2ADDRSigExt_opcode:
                s.changeOperatorTo(VM.BuildFor32Addr ? REF_MOVE : INT_2LONG);
                break;
            case INT_2ADDRZerExt_opcode:
                if (VM.BuildFor32Addr) {
                    s.changeOperatorTo(REF_MOVE);
                }
                break;
            case LONG_2ADDR_opcode:
                s.changeOperatorTo(VM.BuildFor64Addr ? REF_MOVE : LONG_2INT);
                break;
            case NULL_CHECK_opcode:
                NullCheck.setRef(s, asRegAddress(NullCheck.getClearRef(s), s, ir));
                break;
            // Force all call parameters to be in registers
            case SYSCALL_opcode:
            case CALL_opcode:
                {
                    int numArgs = Call.getNumberOfParams(s);
                    for (int i = 0; i < numArgs; i++) {
                        Call.setParam(s, i, asRegPolymorphic(Call.getClearParam(s, i), s, ir));
                    }
                }
                break;
            case RETURN_opcode:
                if (Return.hasVal(s)) {
                    Return.setVal(s, asRegPolymorphic(Return.getClearVal(s), s, ir));
                }
                break;
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) 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 2 with ClassConstantOperand

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

the class GenerationContextTest method buildLockObjectForStaticMethod.

private Operand buildLockObjectForStaticMethod(NormalMethod nm) {
    Class<?> klass = nm.getDeclaringClass().getClassForType();
    Offset offs = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(klass));
    Operand expectedLockObject = new ClassConstantOperand(klass, offs);
    return expectedLockObject;
}
Also used : ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) 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) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) Offset(org.vmmagic.unboxed.Offset)

Example 3 with ClassConstantOperand

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

the class GenerationContext method getLockObject.

/**
 * Get the object for locking for synchronized methods.
 * either the class object or the this ptr.
 *
 * @return an operand for the appropriate lock object
 */
private Operand getLockObject() {
    if (method.isStatic()) {
        Class<?> klass = method.getDeclaringClass().getClassForType();
        Offset offs = Offset.fromIntSignExtend(Statics.findOrCreateObjectLiteral(klass));
        return new ClassConstantOperand(klass, offs);
    } else {
        return makeLocal(0, arguments[0].getType());
    }
}
Also used : ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) Offset(org.vmmagic.unboxed.Offset)

Example 4 with ClassConstantOperand

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

the class StaticFieldReader method getStaticFieldValue.

/**
 * Returns a constant operand with the current value of a static field.
 *
 * @param field the static field whose current value we want to read
 * @return a constant operand representing the current value of the field.
 * @throws NoSuchFieldException when the field could not be found
 */
public static ConstantOperand getStaticFieldValue(RVMField field) throws NoSuchFieldException {
    if (VM.VerifyAssertions) {
        boolean fieldIsReady = field.getDeclaringClass().isInitialized() || field.getDeclaringClass().isInBootImage();
        boolean isFinalField = field.isFinal();
        boolean isStaticField = field.isStatic();
        if (!(isFinalField && isStaticField && fieldIsReady)) {
            String msg = "Error reading field " + field;
            VM._assert(VM.NOT_REACHED, msg);
        }
    }
    TypeReference fieldType = field.getType();
    Offset off = field.getOffset();
    if ((fieldType == TypeReference.Address) || (fieldType == TypeReference.Word) || (fieldType == TypeReference.Offset) || (fieldType == TypeReference.Extent)) {
        Address val = getAddressStaticFieldValue(field);
        return new AddressConstantOperand(val);
    } else if (fieldType.isIntLikeType()) {
        int val = getIntStaticFieldValue(field);
        return new IntConstantOperand(val);
    } else if (fieldType.isLongType()) {
        long val = getLongStaticFieldValue(field);
        return new LongConstantOperand(val);
    } else if (fieldType.isFloatType()) {
        float val = getFloatStaticFieldValue(field);
        return new FloatConstantOperand(val, off);
    } else if (fieldType.isDoubleType()) {
        double val = getDoubleStaticFieldValue(field);
        return new DoubleConstantOperand(val, off);
    } else {
        // Reference type
        if (VM.VerifyAssertions)
            VM._assert(fieldType.isReferenceType());
        Object val = getObjectStaticFieldValue(field);
        if (val == null) {
            return new NullConstantOperand();
        } else if (fieldType == TypeReference.JavaLangString) {
            return new StringConstantOperand((String) val, off);
        } else if (fieldType == TypeReference.JavaLangClass) {
            Class<?> klass = (Class<?>) getObjectStaticFieldValue(field);
            RVMType type;
            if (VM.runningVM) {
                type = java.lang.JikesRVMSupport.getTypeForClass(klass);
            } else {
                type = TypeReference.findOrCreate(klass).resolve();
            }
            return new ClassConstantOperand(type.getClassForType(), off);
        } else {
            return new ObjectConstantOperand(val, off);
        }
    }
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) StringConstantOperand(org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) Address(org.vmmagic.unboxed.Address) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) Offset(org.vmmagic.unboxed.Offset) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) ClassConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) TypeReference(org.jikesrvm.classloader.TypeReference)

Example 5 with ClassConstantOperand

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

Aggregations

ClassConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand)5 Offset (org.vmmagic.unboxed.Offset)5 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)4 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)3 DoubleConstantOperand (org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand)3 FloatConstantOperand (org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand)3 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)3 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)3 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)3 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)3 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)3 StringConstantOperand (org.jikesrvm.compilers.opt.ir.operand.StringConstantOperand)3 OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)2 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)2 CodeConstantOperand (org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)2 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)2 TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)2 RVMType (org.jikesrvm.classloader.RVMType)1 TypeReference (org.jikesrvm.classloader.TypeReference)1 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)1