Search in sources :

Example 1 with TIBConstantOperand

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

the class ObjectReplacer method scalarReplace.

/**
 * Replace a given use of a object with its scalar equivalent
 *
 * @param use the use to replace
 * @param scalars an array of scalar register operands to replace
 *                  the object's fields with
 * @param fields the object's fields
 * @param visited the registers that were already seen
 */
private void scalarReplace(RegisterOperand use, RegisterOperand[] scalars, ArrayList<RVMField> fields, Set<Register> visited) {
    Instruction inst = use.instruction;
    try {
        switch(inst.getOpcode()) {
            case PUTFIELD_opcode:
                {
                    FieldReference fr = PutField.getLocation(inst).getFieldRef();
                    if (VM.VerifyAssertions)
                        VM._assert(fr.isResolved());
                    RVMField f = fr.peekResolvedField();
                    int index = fields.indexOf(f);
                    TypeReference type = scalars[index].getType();
                    Operator moveOp = IRTools.getMoveOp(type);
                    Instruction i = Move.create(moveOp, scalars[index].copyRO(), PutField.getClearValue(inst));
                    inst.insertBefore(i);
                    DefUse.removeInstructionAndUpdateDU(inst);
                    DefUse.updateDUForNewInstruction(i);
                }
                break;
            case GETFIELD_opcode:
                {
                    FieldReference fr = GetField.getLocation(inst).getFieldRef();
                    if (VM.VerifyAssertions)
                        VM._assert(fr.isResolved());
                    RVMField f = fr.peekResolvedField();
                    int index = fields.indexOf(f);
                    TypeReference type = scalars[index].getType();
                    Operator moveOp = IRTools.getMoveOp(type);
                    Instruction i = Move.create(moveOp, GetField.getClearResult(inst), scalars[index].copyRO());
                    inst.insertBefore(i);
                    DefUse.removeInstructionAndUpdateDU(inst);
                    DefUse.updateDUForNewInstruction(i);
                }
                break;
            case MONITORENTER_opcode:
                inst.insertBefore(Empty.create(READ_CEILING));
                DefUse.removeInstructionAndUpdateDU(inst);
                break;
            case MONITOREXIT_opcode:
                inst.insertBefore(Empty.create(WRITE_FLOOR));
                DefUse.removeInstructionAndUpdateDU(inst);
                break;
            case CALL_opcode:
            case NULL_CHECK_opcode:
                // (SJF) TODO: Why wasn't this caught by BC2IR for
                // java.lang.Double.<init> (Ljava/lang/String;)V ?
                DefUse.removeInstructionAndUpdateDU(inst);
                break;
            case CHECKCAST_opcode:
            case CHECKCAST_NOTNULL_opcode:
            case CHECKCAST_UNRESOLVED_opcode:
                {
                    // We cannot handle removing the checkcast if the result of the
                    // checkcast test is unknown
                    TypeReference lhsType = TypeCheck.getType(inst).getTypeRef();
                    if (ClassLoaderProxy.includesType(lhsType, klass.getTypeRef()) == YES) {
                        if (visited == null) {
                            visited = new HashSet<Register>();
                        }
                        Register copy = TypeCheck.getResult(inst).getRegister();
                        if (!visited.contains(copy)) {
                            visited.add(copy);
                            transform2(copy, inst, scalars, fields, visited);
                        // NB will remove inst
                        } else {
                            DefUse.removeInstructionAndUpdateDU(inst);
                        }
                    } else {
                        Instruction i2 = Trap.create(TRAP, null, TrapCodeOperand.CheckCast());
                        DefUse.replaceInstructionAndUpdateDU(inst, i2);
                    }
                }
                break;
            case INSTANCEOF_opcode:
            case INSTANCEOF_NOTNULL_opcode:
            case INSTANCEOF_UNRESOLVED_opcode:
                {
                    // We cannot handle removing the instanceof if the result of the
                    // instanceof test is unknown
                    TypeReference lhsType = InstanceOf.getType(inst).getTypeRef();
                    Instruction i2;
                    if (ClassLoaderProxy.includesType(lhsType, klass.getTypeRef()) == YES) {
                        i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(1));
                    } else {
                        i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(0));
                    }
                    DefUse.replaceInstructionAndUpdateDU(inst, i2);
                }
                break;
            case GET_OBJ_TIB_opcode:
                {
                    Instruction i2 = Move.create(REF_MOVE, GuardedUnary.getClearResult(inst), new TIBConstantOperand(klass));
                    DefUse.replaceInstructionAndUpdateDU(inst, i2);
                }
                break;
            case REF_MOVE_opcode:
                {
                    if (visited == null) {
                        visited = new HashSet<Register>();
                    }
                    Register copy = Move.getResult(use.instruction).getRegister();
                    if (!visited.contains(copy)) {
                        visited.add(copy);
                        transform2(copy, inst, scalars, fields, visited);
                    // NB will remove inst
                    } else {
                        DefUse.removeInstructionAndUpdateDU(inst);
                    }
                }
                break;
            default:
                throw new OptimizingCompilerException("ObjectReplacer: unexpected use " + inst);
        }
    } catch (Exception e) {
        OptimizingCompilerException oe = new OptimizingCompilerException("Error handling use (" + use + ") of: " + inst);
        oe.initCause(e);
        throw oe;
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) FieldReference(org.jikesrvm.classloader.FieldReference) Register(org.jikesrvm.compilers.opt.ir.Register) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) RVMField(org.jikesrvm.classloader.RVMField) TypeReference(org.jikesrvm.classloader.TypeReference) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) HashSet(java.util.HashSet)

Example 2 with TIBConstantOperand

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

the class ShortArrayReplacer method scalarReplace.

/**
 * Replace a given use of an array with its scalar equivalent.
 *
 * @param use the use to replace
 * @param scalars an array of scalar register operands to replace
 *                  the array with
 * @param visited TODO currently useless. Is this parameter
 *  necessary or should it be removed?
 */
private void scalarReplace(RegisterOperand use, RegisterOperand[] scalars, Set<Register> visited) {
    Instruction inst = use.instruction;
    RVMType type = vmArray.getElementType();
    switch(inst.getOpcode()) {
        case INT_ALOAD_opcode:
        case LONG_ALOAD_opcode:
        case FLOAT_ALOAD_opcode:
        case DOUBLE_ALOAD_opcode:
        case BYTE_ALOAD_opcode:
        case UBYTE_ALOAD_opcode:
        case USHORT_ALOAD_opcode:
        case SHORT_ALOAD_opcode:
        case REF_ALOAD_opcode:
            {
                // of a trap
                if (ALoad.getIndex(inst).isIntConstant()) {
                    Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
                    int index = ALoad.getIndex(inst).asIntConstant().value;
                    if (index >= 0 && index < size) {
                        Instruction i2 = Move.create(moveOp, ALoad.getClearResult(inst), scalars[index].copyRO());
                        DefUse.replaceInstructionAndUpdateDU(inst, i2);
                    } else {
                        DefUse.removeInstructionAndUpdateDU(inst);
                    }
                } else {
                    if (VM.BuildForIA32) {
                        if (size == 0) {
                            DefUse.removeInstructionAndUpdateDU(inst);
                        } else if (size == 1) {
                            int index = 0;
                            Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
                            Instruction i2 = Move.create(moveOp, ALoad.getClearResult(inst), scalars[index].copyRO());
                            DefUse.replaceInstructionAndUpdateDU(inst, i2);
                        } else {
                            Operator moveOp = IRTools.getCondMoveOp(type.getTypeRef());
                            Instruction i2 = CondMove.create(moveOp, ALoad.getClearResult(inst), ALoad.getClearIndex(inst), IC(0), ConditionOperand.EQUAL(), scalars[0].copyRO(), scalars[1].copyRO());
                            DefUse.replaceInstructionAndUpdateDU(inst, i2);
                        }
                    } else {
                        if (size == 1) {
                            int index = 0;
                            Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
                            Instruction i2 = Move.create(moveOp, ALoad.getClearResult(inst), scalars[index].copyRO());
                            DefUse.replaceInstructionAndUpdateDU(inst, i2);
                        } else {
                            DefUse.removeInstructionAndUpdateDU(inst);
                        }
                    }
                }
            }
            break;
        case INT_ASTORE_opcode:
        case LONG_ASTORE_opcode:
        case FLOAT_ASTORE_opcode:
        case DOUBLE_ASTORE_opcode:
        case BYTE_ASTORE_opcode:
        case SHORT_ASTORE_opcode:
        case REF_ASTORE_opcode:
            {
                // of a trap
                if (AStore.getIndex(inst).isIntConstant()) {
                    int index = AStore.getIndex(inst).asIntConstant().value;
                    if (index >= 0 && index < size) {
                        Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
                        Instruction i2 = Move.create(moveOp, scalars[index].copyRO(), AStore.getClearValue(inst));
                        DefUse.replaceInstructionAndUpdateDU(inst, i2);
                    } else {
                        DefUse.removeInstructionAndUpdateDU(inst);
                    }
                } else {
                    if (VM.BuildForIA32) {
                        if (size == 0) {
                            DefUse.removeInstructionAndUpdateDU(inst);
                        } else if (size == 1) {
                            int index = 0;
                            Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
                            Instruction i2 = Move.create(moveOp, scalars[index].copyRO(), AStore.getClearValue(inst));
                            DefUse.replaceInstructionAndUpdateDU(inst, i2);
                        } else {
                            Operator moveOp = IRTools.getCondMoveOp(type.getTypeRef());
                            Operand value = AStore.getClearValue(inst);
                            Instruction i2 = CondMove.create(moveOp, scalars[0].copyRO(), AStore.getIndex(inst), IC(0), ConditionOperand.EQUAL(), value, scalars[0].copyRO());
                            DefUse.replaceInstructionAndUpdateDU(inst, i2);
                            Instruction i3 = CondMove.create(moveOp, scalars[1].copyRO(), AStore.getIndex(inst), IC(0), ConditionOperand.NOT_EQUAL(), value, scalars[1].copyRO());
                            i2.insertAfter(i3);
                            DefUse.updateDUForNewInstruction(i3);
                        }
                    } else {
                        if (size == 1) {
                            int index = 0;
                            Operator moveOp = IRTools.getMoveOp(type.getTypeRef());
                            Instruction i2 = Move.create(moveOp, scalars[index].copyRO(), AStore.getClearValue(inst));
                            DefUse.replaceInstructionAndUpdateDU(inst, i2);
                        } else {
                            DefUse.removeInstructionAndUpdateDU(inst);
                        }
                    }
                }
            }
            break;
        case NULL_CHECK_opcode:
            {
                // Null check on result of new array must succeed
                Instruction i2 = Move.create(GUARD_MOVE, NullCheck.getClearGuardResult(inst), new TrueGuardOperand());
                DefUse.replaceInstructionAndUpdateDU(inst, i2);
            }
            break;
        case BOUNDS_CHECK_opcode:
            {
                // Remove or create trap as appropriate
                Instruction i2 = TrapIf.create(TRAP_IF, BoundsCheck.getClearGuardResult(inst), IC(size), BoundsCheck.getClearIndex(inst), ConditionOperand.LOWER_EQUAL(), TrapCodeOperand.ArrayBounds());
                DefUse.replaceInstructionAndUpdateDU(inst, i2);
            }
            break;
        case CHECKCAST_opcode:
        case CHECKCAST_NOTNULL_opcode:
        case CHECKCAST_UNRESOLVED_opcode:
            {
                // We cannot handle removing the checkcast if the result of the
                // checkcast test is unknown
                TypeReference lhsType = TypeCheck.getType(inst).getTypeRef();
                if (ClassLoaderProxy.includesType(lhsType, vmArray.getTypeRef()) == YES) {
                    if (visited == null) {
                        visited = new HashSet<Register>();
                    }
                    Register copy = TypeCheck.getResult(inst).getRegister();
                    if (!visited.contains(copy)) {
                        visited.add(copy);
                        transform2(copy, inst, scalars);
                    // NB will remove inst
                    } else {
                        DefUse.removeInstructionAndUpdateDU(inst);
                    }
                } else {
                    Instruction i2 = Trap.create(TRAP, null, TrapCodeOperand.CheckCast());
                    DefUse.replaceInstructionAndUpdateDU(inst, i2);
                }
            }
            break;
        case INSTANCEOF_opcode:
        case INSTANCEOF_NOTNULL_opcode:
        case INSTANCEOF_UNRESOLVED_opcode:
            {
                // We cannot handle removing the instanceof if the result of the
                // instanceof test is unknown
                TypeReference lhsType = InstanceOf.getType(inst).getTypeRef();
                Instruction i2;
                if (ClassLoaderProxy.includesType(lhsType, vmArray.getTypeRef()) == YES) {
                    i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(1));
                } else {
                    i2 = Move.create(INT_MOVE, InstanceOf.getClearResult(inst), IC(0));
                }
                DefUse.replaceInstructionAndUpdateDU(inst, i2);
            }
            break;
        case GET_OBJ_TIB_opcode:
            {
                Instruction i2 = Move.create(REF_MOVE, GuardedUnary.getClearResult(inst), new TIBConstantOperand(vmArray));
                DefUse.replaceInstructionAndUpdateDU(inst, i2);
            }
            break;
        case REF_MOVE_opcode:
            {
                if (visited == null) {
                    visited = new HashSet<Register>();
                }
                Register copy = Move.getResult(inst).getRegister();
                if (!visited.contains(copy)) {
                    visited.add(copy);
                    transform2(copy, inst, scalars);
                // NB will remove inst
                } else {
                    DefUse.removeInstructionAndUpdateDU(inst);
                }
            }
            break;
        default:
            throw new OptimizingCompilerException("Unexpected instruction: " + inst);
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) Register(org.jikesrvm.compilers.opt.ir.Register) 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) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) RVMType(org.jikesrvm.classloader.RVMType) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) TypeReference(org.jikesrvm.classloader.TypeReference) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) HashSet(java.util.HashSet)

Example 3 with TIBConstantOperand

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

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

the class ValueGraph method findOrCreateVertex.

/**
 * Find or create an ValueGraphVertex corresponding to a
 * given constant operand
 *
 * @param op the constant operand
 * @return a value graph vertex corresponding to this variable
 */
private ValueGraphVertex findOrCreateVertex(ConstantOperand op) {
    Object name;
    if (op.isAddressConstant()) {
        name = (VM.BuildFor32Addr) ? op.asAddressConstant().value.toInt() : op.asAddressConstant().value.toLong();
    } else if (op.isIntConstant()) {
        name = op.asIntConstant().value;
    } else if (op.isFloatConstant()) {
        name = op.asFloatConstant().value;
    } else if (op.isLongConstant()) {
        name = op.asLongConstant().value;
    } else if (op.isDoubleConstant()) {
        name = op.asDoubleConstant().value;
    } else if (op instanceof ObjectConstantOperand) {
        name = op.asObjectConstant().value;
    } else if (op instanceof TIBConstantOperand) {
        name = op.asTIBConstant().value;
    } else if (op.isNullConstant()) {
        name = op;
    } else if (op instanceof TrueGuardOperand) {
        name = op;
    } else if (op instanceof UnreachableOperand) {
        name = op;
    } else {
        throw new OptimizingCompilerException("ValueGraph.findOrCreateVertex: unexpected constant operand: " + op);
    }
    ValueGraphVertex v = getVertex(name);
    if (v == null) {
        v = new ValueGraphVertex(op);
        v.setLabel(op, 0);
        graph.addGraphNode(v);
        nameMap.put(name, v);
    }
    return v;
}
Also used : ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)

Example 5 with TIBConstantOperand

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

the class Simplifier method refLoad.

private static DefUseEffect refLoad(Instruction s, OptOptions opts) {
    if (opts.SIMPLIFY_TIB_OPS) {
        Operand base = Load.getAddress(s);
        if (base.isTIBConstant()) {
            TIBConstantOperand tib = base.asTIBConstant();
            Operand offset = Load.getOffset(s);
            if (tib.value.isInstantiated() && offset.isConstant()) {
                // Reading from a fixed offset from an effectively
                // constant array
                int intOffset;
                if (offset.isIntConstant()) {
                    intOffset = offset.asIntConstant().value;
                } else {
                    intOffset = offset.asAddressConstant().value.toInt();
                }
                int intSlot = intOffset >> LOG_BYTES_IN_ADDRESS;
                // Create appropriate constant operand for TIB slot
                ConstantOperand result;
                TIB tibArray = tib.value.getTypeInformationBlock();
                if (tibArray.slotContainsTib(intSlot)) {
                    RVMType typeOfTIB = ((TIB) tibArray.get(intSlot)).getType();
                    result = new TIBConstantOperand(typeOfTIB);
                } else if (tibArray.slotContainsCode(intSlot)) {
                    // some virtual calls go via the JTOC
                    if (opts.H2L_CALL_VIA_JTOC) {
                        RVMMethod method = tib.value.getTIBMethodAtSlot(intSlot);
                        result = new CodeConstantOperand(method);
                    } else {
                        return DefUseEffect.UNCHANGED;
                    }
                } else {
                    if (tibArray.get(intSlot) == null) {
                        result = new NullConstantOperand();
                    } else {
                        result = new ObjectConstantOperand(tibArray.get(intSlot), Offset.zero());
                    }
                }
                Move.mutate(s, REF_MOVE, Load.getClearResult(s), result);
                return DefUseEffect.MOVE_FOLDED;
            }
        }
    }
    return DefUseEffect.UNCHANGED;
}
Also used : LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) RVMMethod(org.jikesrvm.classloader.RVMMethod) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) UnreachableOperand(org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) TypeOperand(org.jikesrvm.compilers.opt.ir.operand.TypeOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) NullConstantOperand(org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) TIBConstantOperand(org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand) RVMType(org.jikesrvm.classloader.RVMType) ObjectConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand) TIB(org.jikesrvm.objectmodel.TIB) CodeConstantOperand(org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)

Aggregations

TIBConstantOperand (org.jikesrvm.compilers.opt.ir.operand.TIBConstantOperand)12 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)10 ObjectConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ObjectConstantOperand)9 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)9 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)8 CodeConstantOperand (org.jikesrvm.compilers.opt.ir.operand.CodeConstantOperand)8 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)8 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)8 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)8 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)8 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)7 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)7 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)7 UnreachableOperand (org.jikesrvm.compilers.opt.ir.operand.UnreachableOperand)7 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)6 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)6 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)6 OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)5 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)5 RVMType (org.jikesrvm.classloader.RVMType)3