Search in sources :

Example 21 with Operator

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

the class NullCheckCombining method perform.

/**
 * Perform nullcheck combining and validation register removal.
 *
 * @param ir the IR to transform
 */
@Override
public void perform(IR ir) {
    for (BasicBlock bb = ir.firstBasicBlockInCodeOrder(); bb != null; bb = bb.nextBasicBlockInCodeOrder()) {
        if (!bb.isEmpty()) {
            Instruction lastInstr = bb.lastInstruction();
            boolean combined;
            boolean remaining;
            // handler-visible state.
            do {
                combined = remaining = false;
                Instruction activeNullCheck = null;
                Operand activeGuard = null;
                for (Instruction instr = bb.firstRealInstruction(), nextInstr = null; instr != lastInstr; instr = nextInstr) {
                    nextInstr = instr.nextInstructionInCodeOrder();
                    Operator op = instr.operator();
                    if (op == GUARD_MOVE) {
                        if (activeGuard != null && Move.getVal(instr).similar(activeGuard)) {
                            activeGuard = Move.getResult(instr);
                        }
                    } else if (op == GUARD_COMBINE) {
                        if (activeGuard != null && (Binary.getVal1(instr) == activeGuard || Binary.getVal2(instr) == activeGuard)) {
                            activeGuard = null;
                        }
                    } else if (op == NULL_CHECK) {
                        remaining |= (activeGuard == null);
                        activeGuard = NullCheck.getGuardResult(instr);
                        activeNullCheck = instr;
                    } else if (isExplicitStore(instr, op)) {
                        if (instr.isPEI()) {
                            // can't reorder PEI's
                            // NOTE: don't mark remaining, since we'd hit the same problem instr again.
                            activeGuard = null;
                        } else {
                            if (activeGuard != null && canFold(instr, activeGuard, true)) {
                                instr.markAsPEI();
                                activeNullCheck.remove();
                                activeGuard = null;
                                combined = true;
                            }
                            remaining |= (activeGuard == null);
                            // don't attempt to move PEI past a store; could do better.
                            activeGuard = null;
                        }
                    } else if (isExplicitLoad(instr, op)) {
                        if (activeGuard != null && canFold(instr, activeGuard, false)) {
                            instr.markAsPEI();
                            activeNullCheck.remove();
                            activeGuard = null;
                            combined = true;
                        } else if (instr.isPEI()) {
                            // can't reorder PEI's
                            // NOTE: don't mark remaining, since we'd hit the same problem instr again.
                            activeGuard = null;
                        }
                    } else {
                        if (op.isImplicitStore() || op.isPEI()) {
                            // NOTE: don't mark remaining, since we'd hit the same problem instr again.
                            // don't reorder PEI's; be conservative about stores.
                            activeGuard = null;
                        }
                    }
                }
            } while (combined & remaining);
            // (2) Blow away all validation registers in bb.
            for (Instruction instr = bb.firstRealInstruction(), nextInstr = null; instr != lastInstr; instr = nextInstr) {
                nextInstr = instr.nextInstructionInCodeOrder();
                Operator op = instr.operator();
                if (op == GUARD_MOVE || op == GUARD_COMBINE) {
                    instr.remove();
                } else {
                    if (GuardResultCarrier.conforms(op)) {
                        GuardResultCarrier.setGuardResult(instr, null);
                    }
                    if (GuardCarrier.conforms(op)) {
                        GuardCarrier.setGuard(instr, null);
                    }
                }
            }
        }
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 22 with Operator

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

the class BURS_Helpers method CMP64.

/**
 * emit basic code to handle an INT_IFCMP when no folding
 * of the compare into some other computation is possible.
 */
protected final void CMP64(Instruction s, RegisterOperand val1, Operand val2, ConditionOperand cond, boolean immediate) {
    if (VM.VerifyAssertions)
        VM._assert(VM.BuildFor64Addr);
    RegisterOperand cr = regpool.makeTempCondition();
    Operator op;
    if (immediate) {
        op = cond.isUNSIGNED() ? PPC64_CMPLI : PPC64_CMPI;
    } else {
        op = cond.isUNSIGNED() ? PPC64_CMPL : PPC64_CMP;
    }
    EMIT(MIR_Binary.create(op, cr, val1, val2));
    EMIT(MIR_CondBranch.mutate(s, PPC_BCOND, cr.copyD2U(), new PowerPCConditionOperand(cond), IfCmp.getTarget(s), IfCmp.getBranchProfile(s)));
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand)

Example 23 with Operator

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

the class BURS_Helpers method CALL.

/**
 * Expand a call instruction.
 */
protected final void CALL(Instruction s) {
    Operand target = Call.getClearAddress(s);
    MethodOperand meth = Call.getClearMethod(s);
    // Step 1: Find out how many parameters we're going to have.
    int numParams = Call.getNumberOfParams(s);
    int longParams = 0;
    if (VM.BuildFor32Addr) {
        for (int pNum = 0; pNum < numParams; pNum++) {
            if (Call.getParam(s, pNum).getType().isLongType()) {
                longParams++;
            }
        }
    }
    // Step 2: Figure out what the result and result2 values will be
    RegisterOperand result = Call.getClearResult(s);
    RegisterOperand result2 = null;
    if (VM.BuildFor32Addr) {
        if (result != null && result.getType().isLongType()) {
            result2 = I(regpool.getSecondReg(result.getRegister()));
        }
    }
    // Step 3: Figure out what the operator is going to be
    Operator callOp;
    if (target instanceof RegisterOperand) {
        // indirect call through target (contains code addr)
        Register ctr = regpool.getPhysicalRegisterSet().asPPC().getCTR();
        EMIT(MIR_Move.create(PPC_MTSPR, A(ctr), (RegisterOperand) target));
        target = null;
        callOp = PPC_BCTRL;
    } else if (target instanceof BranchOperand) {
        // Earlier analysis has tagged this call as recursive,
        // set up for a direct call.
        callOp = PPC_BL;
    } else {
        throw new OptimizingCompilerException("Unexpected target operand " + target + " to call " + s);
    }
    // Step 4: Mutate the Call to an MIR_Call.
    // Note MIR_Call and Call have a different number of fixed
    // arguments, so some amount of copying is required. We'll hope the
    // opt compiler can manage to make this more efficient than it looks.
    Operand[] params = new Operand[numParams];
    for (int i = 0; i < numParams; i++) {
        params[i] = Call.getClearParam(s, i);
    }
    // see step 3: callTarget is either null or already a BranchOperand
    BranchOperand callTarget = (BranchOperand) target;
    EMIT(MIR_Call.mutate(s, callOp, result, result2, callTarget, meth, numParams + longParams));
    for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
        Operand param = params[paramIdx++];
        MIR_Call.setParam(s, mirCallIdx++, param);
        if (VM.BuildFor32Addr) {
            if (param instanceof RegisterOperand) {
                RegisterOperand rparam = (RegisterOperand) param;
                if (rparam.getType().isLongType()) {
                    MIR_Call.setParam(s, mirCallIdx++, L(regpool.getSecondReg(rparam.getRegister())));
                }
            }
        }
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) PowerPCTrapOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCTrapOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Example 24 with Operator

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

the class BURS_Helpers method EMIT_BOOLCMP_BRANCH.

protected final void EMIT_BOOLCMP_BRANCH(BranchOperand target, BranchProfileOperand bp) {
    if (VM.VerifyAssertions)
        VM._assert(cc != null);
    RegisterOperand cr = regpool.makeTempCondition();
    Operator op;
    if (VM.BuildFor64Addr && isAddress) {
        if (val2 instanceof IntConstantOperand) {
            op = cc.isUNSIGNED() ? PPC64_CMPLI : PPC64_CMPI;
        } else {
            op = cc.isUNSIGNED() ? PPC64_CMPL : PPC64_CMP;
        }
    } else if (val2 instanceof IntConstantOperand) {
        op = cc.isUNSIGNED() ? PPC_CMPLI : PPC_CMPI;
    } else {
        op = cc.isUNSIGNED() ? PPC_CMPL : PPC_CMP;
    }
    EMIT(MIR_Binary.create(op, cr, R(val1), val2));
    EMIT(MIR_CondBranch.create(PPC_BCOND, cr.copyD2U(), new PowerPCConditionOperand(cc), target, bp));
    if (VM.VerifyAssertions) {
        cc = null;
        val1 = null;
        val2 = null;
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand)

Example 25 with Operator

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

the class BURS_Helpers method SYSCALL.

/**
 * Expand a syscall instruction.
 */
protected final void SYSCALL(Instruction s) {
    burs.ir.setHasSysCall(true);
    Operand target = Call.getClearAddress(s);
    MethodOperand meth = Call.getClearMethod(s);
    // Step 1: Find out how many parameters we're going to have.
    int numParams = Call.getNumberOfParams(s);
    int longParams = 0;
    if (VM.BuildFor32Addr) {
        for (int pNum = 0; pNum < numParams; pNum++) {
            if (Call.getParam(s, pNum).getType().isLongType()) {
                longParams++;
            }
        }
    }
    // Step 2: Figure out what the result and result2 values will be
    RegisterOperand result = Call.getClearResult(s);
    RegisterOperand result2 = null;
    if (VM.BuildFor32Addr) {
        if (result != null && result.getType().isLongType()) {
            result2 = I(regpool.getSecondReg(result.getRegister()));
        }
    }
    // Step 3: Figure out what the operator is going to be
    Operator callOp;
    if (target instanceof RegisterOperand) {
        // indirect call through target (contains code addr)
        Register ctr = regpool.getPhysicalRegisterSet().asPPC().getCTR();
        EMIT(MIR_Move.create(PPC_MTSPR, A(ctr), (RegisterOperand) target));
        target = null;
        callOp = PPC_BCTRL_SYS;
    } else if (target instanceof BranchOperand) {
        // Earlier analysis has tagged this call as recursive,
        // set up for a direct call.
        callOp = PPC_BL_SYS;
    } else {
        throw new OptimizingCompilerException("Unexpected target operand " + target + " to call " + s);
    }
    // Step 4: Mutate the SysCall to an MIR_Call.
    // Note MIR_Call and Call have a different number of fixed
    // arguments, so some amount of copying is required. We'll hope the
    // opt compiler can manage to make this more efficient than it looks.
    Operand[] params = new Operand[numParams];
    for (int i = 0; i < numParams; i++) {
        params[i] = Call.getClearParam(s, i);
    }
    // see step 3: callTarget is either null or already a BranchOperand
    BranchOperand callTarget = (BranchOperand) target;
    EMIT(MIR_Call.mutate(s, callOp, result, result2, callTarget, meth, numParams + longParams));
    for (int paramIdx = 0, mirCallIdx = 0; paramIdx < numParams; ) {
        Operand param = params[paramIdx++];
        MIR_Call.setParam(s, mirCallIdx++, param);
        if (VM.BuildFor32Addr) {
            if (param instanceof RegisterOperand) {
                RegisterOperand rparam = (RegisterOperand) param;
                if (rparam.getType().isLongType()) {
                    MIR_Call.setParam(s, mirCallIdx++, L(regpool.getSecondReg(rparam.getRegister())));
                }
            }
        }
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) PowerPCConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) AddressConstantOperand(org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand) TrueGuardOperand(org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) PowerPCTrapOperand(org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCTrapOperand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand) OptimizingCompilerException(org.jikesrvm.compilers.opt.OptimizingCompilerException) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) OsrPoint(org.jikesrvm.compilers.opt.ir.OsrPoint) MethodOperand(org.jikesrvm.compilers.opt.ir.operand.MethodOperand)

Aggregations

Operator (org.jikesrvm.compilers.opt.ir.Operator)28 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)25 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)17 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)15 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)12 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)9 Register (org.jikesrvm.compilers.opt.ir.Register)8 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)8 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)8 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)7 ConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)7 LongConstantOperand (org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand)7 PowerPCConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ppc.PowerPCConditionOperand)7 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)6 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)6 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)5 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)5 TypeReference (org.jikesrvm.classloader.TypeReference)4 OptimizingCompilerException (org.jikesrvm.compilers.opt.OptimizingCompilerException)4 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)4