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;
}
}
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;
}
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;
}
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);
}
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;
}
Aggregations