Search in sources :

Example 71 with Instruction

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

the class ValueGraph method bypassMoves.

/**
 * Bypass MOVE instructions that def an operand: return the first def
 * in the chain that is not the result of a MOVE instruction.
 * <p>
 * Note: treat PI instructions like MOVES
 *
 * @param op the RegisterOperand
 * @return the first def in the chain that is not the result of
 *  move if it can be found, the original operand otherwise
 */
private Operand bypassMoves(Operand op) {
    if (!op.isRegister())
        return op;
    Register r = op.asRegister().getRegister();
    Instruction def = r.getFirstDef();
    if (def == null) {
        return op;
    }
    if (r.isPhysical()) {
        return op;
    }
    if (Move.conforms(def)) {
        // infinite mutual recursion.
        return op;
    } else if (def.operator() == PI) {
        return bypassMoves(GuardedUnary.getVal(def));
    } else {
        return op;
    }
}
Also used : Register(org.jikesrvm.compilers.opt.ir.Register) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 72 with Instruction

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

the class LICM method scheduleEarly.

/**
 * Schedule this instruction as early as possible
 * @param inst the instruction to schedule
 * @return the instruction that serves as the new lower bound (exclusive)
 *  for further scheduling
 */
private Instruction scheduleEarly(Instruction inst) {
    Instruction _earlyPos;
    if (getState(inst) >= early)
        return getEarlyPos(inst);
    setState(inst, early);
    setEarlyPos(inst, inst);
    if (ir.options.FREQ_FOCUS_EFFORT && getOrigBlock(inst).getInfrequent()) {
        return inst;
    }
    // explicitly INCLUDE instructions
    if (!shouldMove(inst, ir)) {
        return inst;
    }
    // dependencies via scalar operands
    _earlyPos = scheduleScalarDefsEarly(inst.getUses(), ir.firstInstructionInCodeOrder(), inst);
    if (VM.VerifyAssertions)
        VM._assert(_earlyPos != null);
    // memory dependencies
    if (ir.isHIR()) {
        _earlyPos = scheduleHeapDefsEarly(ssad.getHeapUses(inst), _earlyPos, inst);
        if (VM.VerifyAssertions)
            VM._assert(_earlyPos != null);
    }
    /* don't put memory stores or PEIs on speculative path */
    if ((inst.isPEI() && !ir.options.SSA_LICM_IGNORE_PEI) || inst.isImplicitStore()) {
        while (!postDominates(getBlock(inst), getBlock(_earlyPos), ir)) {
            _earlyPos = dominanceSuccessor(_earlyPos, inst);
        }
    }
    setEarlyPos(inst, _earlyPos);
    if (DEBUG && getBlock(_earlyPos) != getBlock(inst)) {
        VM.sysWriteln("new earlyBlock: " + getBlock(_earlyPos) + " for " + getBlock(inst) + ": " + inst);
    }
    setBlock(inst, getBlock(_earlyPos));
    return _earlyPos;
}
Also used : Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 73 with Instruction

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

the class LICM method simplify.

private boolean simplify(Instruction inst, BasicBlock block) {
    // no phi
    if (!Phi.conforms(inst))
        return false;
    // if (Phi.getNumberOfValues (inst) != 2) return false; // want exactly 2 inputs
    // VM.sysWriteln ("Simplify " + inst);
    Operand resOp = Phi.getResult(inst);
    if (!(resOp instanceof HeapOperand)) {
        // scalar phi
        return false;
    }
    int xidx = -1;
    Instruction x = null;
    for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
        Instruction in = definingInstruction(Phi.getValue(inst, i));
        if (getOrigBlock(in) != getOrigBlock(inst) && dominator.dominates(getOrigBlock(in), getOrigBlock(inst))) {
            if (xidx != -1)
                return false;
            xidx = i;
            x = in;
        } else if (!dominator.dominates(getOrigBlock(inst), getOrigBlock(in))) {
            return false;
        }
    }
    if (x == null)
        return false;
    replaceUses(inst, (HeapOperand<?>) Phi.getValue(inst, xidx), Phi.getPred(inst, xidx), true);
    // Cast to generic HeapOperand
    @SuppressWarnings("unchecked") HeapOperand<Object> hop = (HeapOperand) resOp;
    if (hop.value.isExceptionHeapType())
        return false;
    /* check that inside the loop, the heap variable is only used/defed
       by simple, non-volatile loads or only by stores

       if so, replace uses of inst (a memory phi) with its dominating input
    */
    int type = checkLoop(inst, hop, xidx, block);
    if (type == CL_LOADS_ONLY || type == CL_STORES_ONLY || type == CL_NONE) {
        replaceUses(inst, (HeapOperand<?>) Phi.getValue(inst, xidx), Phi.getPred(inst, xidx), false);
    }
    return false;
}
Also used : HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) BasicBlockOperand(org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand) HeapOperand(org.jikesrvm.compilers.opt.ir.operand.HeapOperand) RegisterOperand(org.jikesrvm.compilers.opt.ir.operand.RegisterOperand) LocationOperand(org.jikesrvm.compilers.opt.ir.operand.LocationOperand) Operand(org.jikesrvm.compilers.opt.ir.operand.Operand) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 74 with Instruction

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

the class LICM method move.

void move(Instruction inst, BasicBlock to) {
    BasicBlock _origBlock = getOrigBlock(inst);
    Instruction cand = null;
    /* find a position within bestBlock */
    if (dominator.dominates(_origBlock.getNumber(), to.getNumber())) {
        // moved down, so insert in from
        Instruction last = null;
        Enumeration<Instruction> e = to.forwardInstrEnumerator();
        while (e.hasMoreElements()) {
            cand = e.nextElement();
            if (DEBUG)
                VM.sysWriteln(cand.toString());
            ;
            // skip labels, phis, and yieldpoints
            if (!Label.conforms(cand) && !cand.isYieldPoint() && !Phi.conforms(cand)) {
                break;
            }
            last = cand;
        }
        cand = last;
    } else {
        // moved up, so insert at end of block
        Enumeration<Instruction> e = to.reverseInstrEnumerator();
        while (e.hasMoreElements()) {
            cand = e.nextElement();
            if (DEBUG)
                VM.sysWriteln(cand.toString());
            // skip branches and newly placed insts
            if (!BBend.conforms(cand) && !cand.isBranch() && !relocated.contains(cand)) {
                break;
            }
        }
        if (DEBUG)
            VM.sysWriteln("Adding to relocated: " + inst);
        relocated.add(inst);
    }
    if (DEBUG && moved.add(inst.operator())) {
        VM.sysWriteln("m(" + (ir.isLIR() ? "l" : "h") + ") " + inst.operator());
    }
    if (VERBOSE) {
        VM.sysWrite(ir.isLIR() ? "%" : "#");
        VM.sysWriteln(" moving " + inst + " from " + _origBlock + " to " + to + "\n" + "behind  " + cand);
    }
    inst.remove();
    cand.insertAfter(inst);
}
Also used : ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Example 75 with Instruction

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

the class LICM method scheduleHeapDefsEarly.

/**
 * Schedules an instruction as early as possible,
 * but behind the definitions of op[i] and behind earlyPos.
 *
 * @param op the definitions that must have been occurred before the new
 *  position of the instruction
 * @param earlyPos the instruction that serves as a lower bound (exclusive)
 *  for the position
 * @param me the instruction to schedule
 * @return the instruction that serves as the new lower bound (exclusive)
 *  for further scheduling
 */
Instruction scheduleHeapDefsEarly(HeapOperand<?>[] op, Instruction earlyPos, Instruction me) {
    if (op == null)
        return earlyPos;
    for (HeapOperand<?> anOp : op) {
        Instruction def = definingInstruction(anOp);
        if (VM.VerifyAssertions)
            VM._assert(def != null);
        earlyPos = maxDominatorDepth(scheduleEarly(def), earlyPos);
    }
    return earlyPos;
}
Also used : Instruction(org.jikesrvm.compilers.opt.ir.Instruction)

Aggregations

Instruction (org.jikesrvm.compilers.opt.ir.Instruction)356 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)204 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)144 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)117 Register (org.jikesrvm.compilers.opt.ir.Register)106 IntConstantOperand (org.jikesrvm.compilers.opt.ir.operand.IntConstantOperand)72 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)61 ConditionOperand (org.jikesrvm.compilers.opt.ir.operand.ConditionOperand)61 MethodOperand (org.jikesrvm.compilers.opt.ir.operand.MethodOperand)54 LocationOperand (org.jikesrvm.compilers.opt.ir.operand.LocationOperand)53 Test (org.junit.Test)49 TrueGuardOperand (org.jikesrvm.compilers.opt.ir.operand.TrueGuardOperand)46 TypeReference (org.jikesrvm.classloader.TypeReference)38 BranchOperand (org.jikesrvm.compilers.opt.ir.operand.BranchOperand)38 NullConstantOperand (org.jikesrvm.compilers.opt.ir.operand.NullConstantOperand)35 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)33 HeapOperand (org.jikesrvm.compilers.opt.ir.operand.HeapOperand)33 TrapCodeOperand (org.jikesrvm.compilers.opt.ir.operand.TrapCodeOperand)31 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)28 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)27