use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class IndexPropagationSystem method processAStore.
/**
* Update the set of dataflow equations to account for the actions
* of AStore instruction s
*
* <p> The store is of the form A[k] = val. let A_1 be the array SSA
* variable before the store, and A_2 the array SSA variable after
* the store. Then we add the dataflow equation
* L(A_2) = update(L(A_1), VALNUM(k))
*
* <p> Intuitively, this equation represents the fact that A[k] is available
* after the store
*
* @param s the Astore instruction
*/
void processAStore(Instruction s) {
HeapOperand<?>[] A1 = ssa.getHeapUses(s);
HeapOperand<?>[] A2 = ssa.getHeapDefs(s);
if ((A1.length != 1) || (A2.length != 1)) {
throw new OptimizingCompilerException("IndexPropagation.processAStore: astore instruction defs or uses multiple heap variables?");
}
Operand array = AStore.getArray(s);
Operand index = AStore.getIndex(s);
addUpdateArrayDefEquation(A2[0].getHeapVariable(), A1[0].getHeapVariable(), array, index);
}
use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class SSADictionary method makePhiInstruction.
/**
* Create a phi-function instruction for a heap variable
*
* @param H a symbolic variable for a Heap variable
* @param bb the basic block holding the new phi function
* instruction
* @return the instruction <code> H = phi H,H,..,H </code>
*/
private static Instruction makePhiInstruction(HeapVariable<Object> H, BasicBlock bb) {
int n = bb.getNumberOfIn();
Enumeration<BasicBlock> in = bb.getIn();
HeapOperand<Object> lhs = new HeapOperand<Object>(H);
Instruction s = Phi.create(PHI, lhs, n);
lhs.setInstruction(s);
for (int i = 0; i < n; i++) {
HeapOperand<Object> op = new HeapOperand<Object>(H);
op.setInstruction(s);
Phi.setValue(s, i, op);
BasicBlock pred = in.nextElement();
Phi.setPred(s, i, new BasicBlockOperand(pred));
}
return s;
}
use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand in project JikesRVM by JikesRVM.
the class SSADictionary method registerUse.
/**
* Register that an instruction uses a heap variable for a given
* field.
*
* @param s the instruction in question
* @param fr the field heap variable the instruction uses
*/
private void registerUse(Instruction s, FieldReference fr) {
if (VM.VerifyAssertions)
VM._assert(s.operator() != PHI);
RVMField f = fr.peekResolvedField();
HeapOperand<Object> H;
if (f == null) {
// can't resolve field at compile time.
// This isn't quite correct, but is somewhat close.
// See defect 3481.
H = new HeapOperand<Object>(findOrCreateHeapVariable(fr));
} else {
// not included in the set
if (heapTypes != null) {
if (!heapTypes.contains(f)) {
return;
}
}
H = new HeapOperand<Object>(findOrCreateHeapVariable(f));
}
HeapOperand<Object>[] Hprime = new HeapOperand[1];
Hprime[0] = H;
Hprime[0].setInstruction(s);
uses.put(s, Hprime);
}
use of org.jikesrvm.compilers.opt.ir.operand.HeapOperand 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.operand.HeapOperand 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;
}
Aggregations