Search in sources :

Example 26 with Operator

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

the class BURS_Helpers method SSE2_FCMP_FCMOV.

protected final void SSE2_FCMP_FCMOV(Instruction s, RegisterOperand result, Operand lhsCmp, Operand rhsCmp, ConditionOperand cond, Operand trueValue, Operand falseValue) {
    final boolean singleResult = result.isFloat();
    final boolean singleCmp = lhsCmp.isFloat();
    // TODO: support for the MAXSS/MAXSD instructions taking care of NaN cases
    // find cmpOperator flipping code or operands as necessary
    Operator cmpOperator = SSE2_CMP_OP(cond, singleCmp);
    boolean needFlipOperands = false;
    boolean needFlipCode = false;
    if (cmpOperator == null) {
        needFlipOperands = !needFlipOperands;
        cmpOperator = SSE2_CMP_OP(cond.flipOperands(), singleCmp);
        if (cmpOperator == null) {
            needFlipCode = !needFlipCode;
            cmpOperator = SSE2_CMP_OP(cond.flipCode(), singleCmp);
            if (cmpOperator == null) {
                needFlipOperands = !needFlipOperands;
                cmpOperator = SSE2_CMP_OP(cond.flipOperands(), singleCmp);
                if (VM.VerifyAssertions)
                    opt_assert(cmpOperator != null);
            }
        }
    }
    if (needFlipOperands) {
        Operand temp = lhsCmp;
        lhsCmp = rhsCmp;
        rhsCmp = temp;
    }
    if (needFlipCode) {
        Operand temp = falseValue;
        falseValue = trueValue;
        trueValue = temp;
    }
    // place true value in a temporary register to be used for generation of result
    RegisterOperand temp = regpool.makeTemp(result);
    EMIT(CPOS(s, MIR_Move.create(singleResult ? IA32_MOVSS : IA32_MOVSD, temp, trueValue)));
    // do compare ensuring size is >= size of result
    if (!singleResult && singleCmp) {
        RegisterOperand temp2 = regpool.makeTemp(result);
        EMIT(CPOS(s, MIR_Unary.create(IA32_CVTSS2SD, temp2, rhsCmp)));
        EMIT(CPOS(s, MIR_Unary.create(IA32_CVTSS2SD, result.copyRO(), lhsCmp)));
        rhsCmp = temp2;
        cmpOperator = SSE2_CMP_OP(cond, false);
    } else {
        if (!result.similar(lhsCmp)) {
            EMIT(CPOS(s, MIR_Move.create(singleResult ? IA32_MOVSS : IA32_MOVSD, result.copyRO(), lhsCmp)));
        }
    }
    EMIT(MIR_BinaryAcc.mutate(s, cmpOperator, result, rhsCmp));
    // result contains all 1s or 0s, use masks and OR to perform conditional move
    EMIT(CPOS(s, MIR_BinaryAcc.create(singleResult ? IA32_ANDPS : IA32_ANDPD, temp.copyRO(), result.copyRO())));
    EMIT(CPOS(s, MIR_BinaryAcc.create(singleResult ? IA32_ANDNPS : IA32_ANDNPD, result.copyRO(), falseValue)));
    EMIT(CPOS(s, MIR_BinaryAcc.create(singleResult ? IA32_ORPS : IA32_ORPD, result.copyRO(), temp.copyRO())));
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LongConstantOperand(org.jikesrvm.compilers.opt.ir.operand.LongConstantOperand) DoubleConstantOperand(org.jikesrvm.compilers.opt.ir.operand.DoubleConstantOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) IA32ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ia32.IA32ConditionOperand) FloatConstantOperand(org.jikesrvm.compilers.opt.ir.operand.FloatConstantOperand) StackLocationOperand(org.jikesrvm.compilers.opt.ir.operand.StackLocationOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) MemoryOperand(org.jikesrvm.compilers.opt.ir.operand.MemoryOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) 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) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) InlinedOsrTypeInfoOperand(org.jikesrvm.compilers.opt.ir.operand.InlinedOsrTypeInfoOperand) TrapCodeOperand(org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand) BURSManagedFPROperand(org.jikesrvm.compilers.opt.ir.operand.ia32.BURSManagedFPROperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) ConstantOperand(org.jikesrvm.compilers.opt.ir.operand.ConstantOperand)

Example 27 with Operator

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

the class AnnotatedLSTNode method generateLoopInvariantOperand.

/**
 * Loop invariants may not be accessible before a loop, so generate
 * the instructions so they are
 *
 * @param block to generate instructions into
 * @param op the operand we hope to use before the loop
 * @return a (possibly new) operand
 */
public Operand generateLoopInvariantOperand(BasicBlock block, Operand op) {
    Instruction instr = definingInstruction(op);
    if (op.isConstant() || !CFGTransformations.inLoop(instr.getBasicBlock(), loop)) {
        // the operand is already invariant
        return op;
    } else {
        RegisterOperand result;
        Instruction opInstr = definingInstruction(op);
        // create result of correct type
        if (ResultCarrier.conforms(opInstr)) {
            result = ResultCarrier.getResult(opInstr).copyRO();
            result.setRegister(ir.regpool.getReg(result));
        } else {
            if (VM.VerifyAssertions)
                VM._assert(GuardResultCarrier.conforms(opInstr));
            result = GuardResultCarrier.getGuardResult(opInstr).copyRO();
            result.setRegister(ir.regpool.getReg(result));
        }
        Instruction resultInstruction;
        Operator operator = instr.operator();
        switch(operator.format) {
            case InstructionFormat.Binary_format:
                resultInstruction = Binary.create(operator, result, generateLoopInvariantOperand(block, Binary.getVal1(instr)), generateLoopInvariantOperand(block, Binary.getVal2(instr)));
                break;
            case InstructionFormat.BoundsCheck_format:
                resultInstruction = BoundsCheck.create(operator, result, generateLoopInvariantOperand(block, BoundsCheck.getRef(instr)), generateLoopInvariantOperand(block, BoundsCheck.getIndex(instr)), generateLoopInvariantOperand(block, BoundsCheck.getGuard(instr)));
                break;
            case InstructionFormat.GuardedBinary_format:
                resultInstruction = GuardedBinary.create(operator, result, generateLoopInvariantOperand(block, GuardedBinary.getVal1(instr)), generateLoopInvariantOperand(block, GuardedBinary.getVal2(instr)), generateLoopInvariantOperand(block, GuardedBinary.getGuard(instr)));
                break;
            case InstructionFormat.GuardedUnary_format:
                resultInstruction = GuardedUnary.create(operator, result, generateLoopInvariantOperand(block, GuardedUnary.getVal(instr)), generateLoopInvariantOperand(block, GuardedUnary.getGuard(instr)));
                break;
            case InstructionFormat.Move_format:
                resultInstruction = Move.create(operator, result, generateLoopInvariantOperand(block, Move.getVal(instr)));
                break;
            case InstructionFormat.NullCheck_format:
                resultInstruction = NullCheck.create(operator, result, generateLoopInvariantOperand(block, NullCheck.getRef(instr)));
                break;
            case InstructionFormat.Unary_format:
                resultInstruction = Unary.create(operator, result, generateLoopInvariantOperand(block, Unary.getVal(instr)));
                break;
            default:
                // Unknown instruction format so leave
                throw new Error("TODO: generate loop invariant for operator " + operator);
        }
        resultInstruction.copyPosition(instr);
        block.appendInstruction(resultInstruction);
        DefUse.updateDUForNewInstruction(resultInstruction);
        return result.copyRO();
    }
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 28 with Operator

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

the class BranchOptimizations method doCondMove.

/**
 * Perform the transformation to replace conditional branch with a
 * sequence using conditional moves.
 *
 * @param ir governing IR
 * @param diamond the IR diamond structure to replace
 * @param cb conditional branch instruction at the head of the diamond
 */
private void doCondMove(IR ir, Diamond diamond, Instruction cb) {
    BasicBlock taken = diamond.getTaken();
    BasicBlock notTaken = diamond.getNotTaken();
    // for each non-branch instruction s in the diamond,
    // copy s to a new instruction s'
    // and store a mapping from s to s'
    HashMap<Instruction, Instruction> takenInstructions = new HashMap<Instruction, Instruction>();
    Instruction[] takenInstructionList = copyAndMapInstructions(taken, takenInstructions);
    HashMap<Instruction, Instruction> notTakenInstructions = new HashMap<Instruction, Instruction>();
    Instruction[] notTakenInstructionList = copyAndMapInstructions(notTaken, notTakenInstructions);
    // Extract the values and condition from the conditional branch.
    Operand val1 = IfCmp.getVal1(cb);
    Operand val2 = IfCmp.getVal2(cb);
    ConditionOperand cond = IfCmp.getCond(cb);
    // Copy val1 and val2 to temporaries, just in case they're defined in
    // the diamond.  If they're not defined in the diamond, copy prop
    // should clean these moves up.
    RegisterOperand tempVal1 = ir.regpool.makeTemp(val1);
    Operator op = IRTools.getMoveOp(tempVal1.getType());
    cb.insertBefore(Move.create(op, tempVal1.copyRO(), val1.copy()));
    RegisterOperand tempVal2 = ir.regpool.makeTemp(val2);
    op = IRTools.getMoveOp(tempVal2.getType());
    cb.insertBefore(Move.create(op, tempVal2.copyRO(), val2.copy()));
    // For each instruction in each temporary set, rewrite it to def a new
    // temporary, and insert it before the branch.
    rewriteWithTemporaries(takenInstructionList, ir);
    rewriteWithTemporaries(notTakenInstructionList, ir);
    insertBefore(takenInstructionList, cb);
    insertBefore(notTakenInstructionList, cb);
    // For each register defined in the TAKEN branch, save a mapping to
    // the corresponding conditional move.
    HashMap<Register, Instruction> takenMap = new HashMap<Register, Instruction>();
    // First handle the taken branch.
    if (taken != null) {
        for (Enumeration<Instruction> e = taken.forwardRealInstrEnumerator(); e.hasMoreElements(); ) {
            Instruction s = e.nextElement();
            if (s.isBranch())
                continue;
            Operand def = s.getDefs().nextElement();
            // that will now be dead
            if (def.asRegister().getRegister().spansBasicBlock()) {
                Instruction tempS = takenInstructions.get(s);
                RegisterOperand temp = (RegisterOperand) tempS.getDefs().nextElement();
                op = IRTools.getCondMoveOp(def.asRegister().getType());
                Instruction cmov = CondMove.create(op, def.copy().asRegister(), tempVal1.copy(), tempVal2.copy(), cond.copy().asCondition(), temp.copy(), def.copy());
                takenMap.put(def.asRegister().getRegister(), cmov);
                cb.insertBefore(cmov);
            }
            s.remove();
        }
    }
    // For each register defined in the NOT-TAKEN branch, save a mapping to
    // the corresponding conditional move.
    HashMap<Register, Instruction> notTakenMap = new HashMap<Register, Instruction>();
    // Next handle the not taken branch.
    if (notTaken != null) {
        for (Enumeration<Instruction> e = notTaken.forwardRealInstrEnumerator(); e.hasMoreElements(); ) {
            Instruction s = e.nextElement();
            if (s.isBranch())
                continue;
            Operand def = s.getDefs().nextElement();
            // that will now be dead
            if (def.asRegister().getRegister().spansBasicBlock()) {
                Instruction tempS = notTakenInstructions.get(s);
                RegisterOperand temp = (RegisterOperand) tempS.getDefs().nextElement();
                Instruction prevCmov = takenMap.get(def.asRegister().getRegister());
                if (prevCmov != null) {
                    // if this register was also defined in the taken branch, change
                    // the previous cmov with a different 'False' Value
                    CondMove.setFalseValue(prevCmov, temp.copy());
                    notTakenMap.put(def.asRegister().getRegister(), prevCmov);
                } else {
                    // create a new cmov instruction
                    op = IRTools.getCondMoveOp(def.asRegister().getType());
                    Instruction cmov = CondMove.create(op, def.asRegister(), tempVal1.copy(), tempVal2.copy(), cond.copy().asCondition(), def.copy(), temp.copy());
                    cb.insertBefore(cmov);
                    notTakenMap.put(def.asRegister().getRegister(), cmov);
                }
            }
            s.remove();
        }
    }
    // Mutate the conditional branch into a GOTO.
    BranchOperand target = diamond.getBottom().makeJumpTarget();
    Goto.mutate(cb, GOTO, target);
    // Delete a potential GOTO after cb.
    Instruction next = cb.nextInstructionInCodeOrder();
    if (next.operator() != BBEND) {
        next.remove();
    }
    // Recompute the CFG.
    // fix the CFG
    diamond.getTop().recomputeNormalOut(ir);
}
Also used : Operator(org.jikesrvm.compilers.opt.ir.Operator) HashMap(java.util.HashMap) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) BranchProfileOperand(org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand) IntConstantOperand(org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ConditionOperand(org.jikesrvm.compilers.opt.ir.operand.ConditionOperand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) Register(org.jikesrvm.compilers.opt.ir.Register) BranchOperand(org.jikesrvm.compilers.opt.ir.operand.BranchOperand)

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