use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class LICM method checkLoop.
/*
* TODO document xidx parameter and turn this comment into proper JavaDoc.
* <p>
* Checks that inside the loop, the heap variable is only used/defed
* by simple, non-volatile loads/stores
*
* @param inst a phi instruction
* @param hop the result operand of the phi instruction
* @param xidx
* @param block the block that contains the phi instruction
*
* @return one of {@link #CL_LOADS_ONLY}, {@link #CL_STORES_ONLY},
* {@link #CL_LOADS_AND_STORES}, {@link #CL_COMPLEX}
*/
private int checkLoop(Instruction inst, HeapOperand<Object> hop, int xidx, BasicBlock block) {
HashSet<Instruction> seen = new HashSet<Instruction>();
Queue<Instruction> workList = new Queue<Instruction>();
int _state = CL_NONE;
int instUses = 0;
seen.add(inst);
for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
if (i == xidx)
continue;
Instruction y = definingInstruction(Phi.getValue(inst, i));
if (y == inst)
instUses++;
if (!(seen.contains(y))) {
seen.add(y);
workList.insert(y);
}
}
while (!(workList.isEmpty())) {
Instruction y = workList.remove();
if (Phi.conforms(y)) {
for (int i = Phi.getNumberOfValues(y) - 1; i >= 0; --i) {
Instruction z = definingInstruction(Phi.getValue(y, i));
if (z == inst)
instUses++;
if (!(seen.contains(z))) {
seen.add(z);
workList.insert(z);
}
}
} else if ((y.isPEI()) || !LocationCarrier.conforms(y) || y.operator().isAcquire() || y.operator().isRelease()) {
return CL_COMPLEX;
} else {
// check for access to volatile field
LocationOperand loc = LocationCarrier.getLocation(y);
if (loc == null || loc.mayBeVolatile()) {
// VM.sysWriteln (" no loc or volatile field");
return CL_COMPLEX;
}
if (y.isImplicitStore()) {
// conservatively estimate loop-invariance by header domination
if (!inVariantLocation(y, block))
return CL_COMPLEX;
_state |= CL_STORES_ONLY;
} else {
_state |= CL_LOADS_ONLY;
}
for (HeapOperand<?> op : ssad.getHeapUses(y)) {
if (op.value.isExceptionHeapType())
continue;
if (op.getHeapType() != hop.getHeapType())
return CL_COMPLEX;
y = definingInstruction(op);
if (y == inst)
instUses++;
if (!(seen.contains(y))) {
seen.add(y);
workList.insert(y);
}
}
}
}
if (_state == CL_STORES_ONLY && ssad.getNumberOfUses(hop.value) != instUses) {
return CL_COMPLEX;
}
return _state;
}
use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class LICM method replaceUses.
/*
* In the consumers of `inst', replace uses of `inst's result
* with uses of `replacement'
*/
private boolean replaceUses(Instruction inst, HeapOperand<?> replacement, BasicBlockOperand replacementBlock, boolean onlyPEIs) {
if (VM.VerifyAssertions)
VM._assert(Phi.conforms(inst));
boolean changed = false;
// Cast to generic HeapOperand
@SuppressWarnings("unchecked") HeapOperand<Object> hop = (HeapOperand) Phi.getResult(inst);
HeapVariable<Object> H = hop.value;
Iterator<HeapOperand<Object>> it = ssad.iterateHeapUses(H);
while (it.hasNext()) {
hop = it.next();
Instruction user = hop.instruction;
if (onlyPEIs && !user.isPEI())
continue;
if (Phi.conforms(user)) {
for (int i = 0; i < Phi.getNumberOfValues(user); i++) {
if (Phi.getValue(user, i) == hop) {
Phi.setValue(user, i, replacement.copy());
Phi.setPred(user, i, (BasicBlockOperand) replacementBlock.copy());
}
}
changed |= replacement.value != H;
} else {
HeapOperand<?>[] uses = ssad.getHeapUses(user);
for (int i = uses.length - 1; i >= 0; --i) {
if (uses[i].value == H) {
changed |= replacement.value != H;
uses[i] = replacement.copy();
uses[i].setInstruction(user);
}
}
}
if (DEBUG && changed) {
VM.sysWriteln(" changing dependency of " + user + "\n" + "from " + H + " to " + replacement);
}
}
if (!onlyPEIs) {
for (int i = Phi.getNumberOfValues(inst) - 1; i >= 0; --i) {
Phi.setValue(inst, i, replacement.copy());
}
}
return changed;
}
use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class LeaveSSA method unSSAGuardsFinalize.
/**
* Rename registers and delete Phis.
*
* @param ir the governing IR, currently in SSA form
*/
private void unSSAGuardsFinalize(IR ir) {
DefUse.computeDU(ir);
for (Register r = ir.regpool.getFirstSymbolicRegister(); r != null; r = r.getNext()) {
if (!r.isValidation())
continue;
Register nreg = guardFind(r);
Enumeration<RegisterOperand> uses = DefUse.uses(r);
while (uses.hasMoreElements()) {
RegisterOperand use = uses.nextElement();
use.setRegister(nreg);
}
Enumeration<RegisterOperand> defs = DefUse.defs(r);
while (defs.hasMoreElements()) {
RegisterOperand def = defs.nextElement();
def.setRegister(nreg);
}
}
Instruction inst = guardPhis;
while (inst != null) {
inst.remove();
inst = inst2guardPhi.get(inst);
}
}
use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class LeaveSSA method unSSAGuardsDetermineReg.
/**
* Determine target register for guard phi operands
*
* @param ir the governing IR, currently in SSA form
*/
private void unSSAGuardsDetermineReg(IR ir) {
Instruction inst = guardPhis;
while (inst != null) {
Register r = Phi.getResult(inst).asRegister().getRegister();
int values = Phi.getNumberOfValues(inst);
for (int i = 0; i < values; ++i) {
Operand op = Phi.getValue(inst, i);
if (op instanceof RegisterOperand) {
guardUnion(op.asRegister().getRegister(), r);
} else {
if (VM.VerifyAssertions) {
VM._assert(op instanceof TrueGuardOperand || op instanceof UnreachableOperand);
}
}
}
inst = inst2guardPhi.get(inst);
}
}
use of org.jikesrvm.compilers.opt.ir.Instruction in project JikesRVM by JikesRVM.
the class LeaveSSA method performRename.
// substitute variables renamed in control parents
private void performRename(BasicBlock bb, DominatorTree dom, VariableStacks s) {
if (DEBUG)
VM.sysWriteln("performRename: " + bb);
Enumeration<Instruction> e = bb.forwardRealInstrEnumerator();
while (e.hasMoreElements()) {
Instruction i = e.nextElement();
Enumeration<Operand> ee = i.getUses();
while (ee.hasMoreElements()) {
Operand o = ee.nextElement();
if (o instanceof RegisterOperand) {
Register r1 = ((RegisterOperand) o).getRegister();
if (r1.isValidation())
continue;
Operand r2 = s.peek(r1);
if (r2 != null) {
if (DEBUG) {
VM.sysWriteln("replace operand in " + i + "(" + r2 + " for " + o);
}
i.replaceOperand(o, r2.copy());
}
}
}
}
// record renamings required in children
e = bb.forwardRealInstrEnumerator();
while (e.hasMoreElements()) {
Instruction i = e.nextElement();
if (globalRenameTable.contains(i)) {
Register original = Move.getVal(i).asRegister().getRegister();
RegisterOperand rename = Move.getResult(i);
if (DEBUG)
VM.sysWriteln("record rename " + rename + " for " + original);
s.push(original, rename);
}
}
// insert copies in control children
Enumeration<TreeNode> children = dom.getChildren(bb);
while (children.hasMoreElements()) {
BasicBlock c = ((DominatorTreeNode) children.nextElement()).getBlock();
performRename(c, dom, s);
}
// pop renamings from this block off stack
e = bb.forwardRealInstrEnumerator();
while (e.hasMoreElements()) {
Instruction i = e.nextElement();
if (globalRenameTable.contains(i)) {
Register original = Move.getVal(i).asRegister().getRegister();
s.pop(original);
}
}
}
Aggregations