use of org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand in project JikesRVM by JikesRVM.
the class EnterSSA method search2.
/**
* This routine is the guts of the SSA construction phase for heap array
* SSA. The renaming algorithm is analagous to the algorithm for
* scalars See <code> renameSymbolicRegisters </code> for more details.
*
* @param X the current basic block being traversed
* @param stacks a structure holding the current names for each heap
* variable
* used and defined by each instruction.
*/
private void search2(BasicBlock X, HashMap<Object, Stack<HeapOperand<Object>>> stacks) {
if (DEBUG)
System.out.println("SEARCH2 " + X);
SSADictionary dictionary = ir.HIRInfo.dictionary;
for (Enumeration<Instruction> ie = dictionary.getAllInstructions(X); ie.hasMoreElements(); ) {
Instruction A = ie.nextElement();
if (!dictionary.usesHeapVariable(A) && !dictionary.defsHeapVariable(A))
continue;
if (A.operator() != PHI) {
// replace the Heap variables USED by this instruction
HeapOperand<Object>[] uses = dictionary.getHeapUses(A);
if (uses != null) {
// Generic array problem
@SuppressWarnings("unchecked") HeapOperand<Object>[] newUses = new HeapOperand[uses.length];
for (int i = 0; i < uses.length; i++) {
Stack<HeapOperand<Object>> S = stacks.get(uses[i].getHeapType());
newUses[i] = S.peek().copy();
if (DEBUG) {
System.out.println("NORMAL USE PEEK " + newUses[i]);
}
}
dictionary.replaceUses(A, newUses);
}
}
// replace any Heap variable DEF
if (A.operator() != PHI) {
HeapOperand<Object>[] defs = dictionary.getHeapDefs(A);
if (defs != null) {
for (HeapOperand<Object> operand : dictionary.replaceDefs(A, X)) {
Stack<HeapOperand<Object>> S = stacks.get(operand.getHeapType());
S.push(operand);
if (DEBUG)
System.out.println("PUSH " + operand + " FOR " + operand.getHeapType());
}
}
} else {
HeapOperand<Object>[] r = dictionary.replaceDefs(A, X);
Stack<HeapOperand<Object>> S = stacks.get(r[0].getHeapType());
S.push(r[0]);
if (DEBUG)
System.out.println("PUSH " + r[0] + " FOR " + r[0].getHeapType());
}
}
for (Enumeration<BasicBlock> y = X.getOut(); y.hasMoreElements(); ) {
BasicBlock Y = y.nextElement();
if (Y.isExit())
continue;
int j = numPredProcessed[Y.getNumber()]++;
// replace each USE in each HEAP-PHI function for Y
for (Iterator<Instruction> hp = dictionary.getHeapPhiInstructions(Y); hp.hasNext(); ) {
Instruction s = hp.next();
// Down-cast to a generic type
@SuppressWarnings("unchecked") HeapOperand<Object> H1 = (HeapOperand) Phi.getResult(s);
Stack<HeapOperand<Object>> S = stacks.get(H1.getHeapType());
HeapOperand<Object> H2 = S.peek();
Phi.setValue(s, j, new HeapOperand<Object>(H2.getHeapVariable()));
Phi.setPred(s, j, new BasicBlockOperand(X));
}
}
for (Enumeration<TreeNode> c = ir.HIRInfo.dominatorTree.getChildren(X); c.hasMoreElements(); ) {
DominatorTreeNode v = (DominatorTreeNode) c.nextElement();
search2(v.getBlock(), stacks);
}
for (Enumeration<Instruction> a = dictionary.getAllInstructions(X); a.hasMoreElements(); ) {
Instruction A = a.nextElement();
if (!dictionary.usesHeapVariable(A) && !dictionary.defsHeapVariable(A))
continue;
// retrieve the Heap Variables defined by A
if (A.operator() != PHI) {
HeapOperand<Object>[] defs = dictionary.getHeapDefs(A);
if (defs != null) {
for (HeapOperand<Object> def : defs) {
Stack<HeapOperand<Object>> S = stacks.get(def.getHeapType());
S.pop();
if (DEBUG)
System.out.println("POP " + def.getHeapType());
}
}
} else {
// Down-cast to a generic type
@SuppressWarnings("unchecked") HeapOperand<Object> H = (HeapOperand) Phi.getResult(A);
Stack<HeapOperand<Object>> S = stacks.get(H.getHeapType());
S.pop();
if (DEBUG)
System.out.println("POP " + H.getHeapType());
}
}
// end of fourth loop
if (DEBUG)
System.out.println("END SEARCH2 " + X);
}
use of org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand 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.BasicBlockOperand in project JikesRVM by JikesRVM.
the class SSA method purgeBlockFromPHIs.
/**
* Fix up any PHI instructions in the given target block to reflect that
* the given source block is no longer a predecessor of target.
* The basic algorithm is to erase the PHI operands related to the edge
* from source to target by sliding the other PHI operands down as required.
*
* @param source the source block to remove from PHIs in target
* @param target the target block that may contain PHIs to update.
*/
static void purgeBlockFromPHIs(BasicBlock source, BasicBlock target) {
for (Enumeration<Instruction> e = target.forwardRealInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
// all done (assume PHIs are first!)
if (s.operator() != PHI)
return;
int numPairs = Phi.getNumberOfPreds(s);
int dst = 0;
for (int src = 0; src < numPairs; src++) {
BasicBlockOperand bbop = Phi.getPred(s, src);
if (bbop.block == source) {
Phi.setValue(s, src, null);
Phi.setPred(s, src, null);
} else {
if (src != dst) {
Phi.setValue(s, dst, Phi.getClearValue(s, src));
Phi.setPred(s, dst, Phi.getClearPred(s, src));
}
dst++;
}
}
for (int i = dst; i < numPairs; i++) {
Phi.setValue(s, i, null);
Phi.setPred(s, i, null);
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand in project JikesRVM by JikesRVM.
the class SSA method replaceBlockInPhis.
/**
* Update PHI instructions in the target block so that any PHIs that
* come from basic block B1, now come from basic block B2.
*
* @param target the target block that may contain PHIs to update.
* @param B1 the block to replace in the phi instructions
* @param B2 the replacement block for B1
*/
static void replaceBlockInPhis(BasicBlock target, BasicBlock B1, BasicBlock B2) {
for (Enumeration<Instruction> e = target.forwardRealInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
// all done (assume PHIs are first!)
if (s.operator() != PHI)
return;
int numPairs = Phi.getNumberOfPreds(s);
for (int src = 0; src < numPairs; src++) {
BasicBlockOperand bbop = Phi.getPred(s, src);
if (bbop.block == B1) {
Phi.setPred(s, src, new BasicBlockOperand(B2));
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand in project JikesRVM by JikesRVM.
the class EnterSSA method search.
/**
* This routine is the guts of the SSA construction phase for scalars. See
* renameSymbolicRegisters for more details.
*
* @param X basic block to search dominator tree from
* @param S stack of names for each register
*/
private void search(BasicBlock X, Stack<RegisterOperand>[] S) {
if (DEBUG)
System.out.println("SEARCH " + X);
HashMap<Register, Register> pushedRegs = new HashMap<Register, Register>();
for (Enumeration<Instruction> ie = X.forwardInstrEnumerator(); ie.hasMoreElements(); ) {
Instruction A = ie.nextElement();
if (A.operator() != PHI) {
// replace each use
for (int u = A.getNumberOfDefs(); u < A.getNumberOfOperands(); u++) {
Operand op = A.getOperand(u);
if (op instanceof RegisterOperand) {
RegisterOperand rop = (RegisterOperand) op;
Register r1 = rop.getRegister();
if (r1.isSSA())
continue;
if (r1.isPhysical())
continue;
RegisterOperand r2 = S[r1.getNumber()].peek();
if (DEBUG)
System.out.println("REPLACE NORMAL USE " + r1 + " with " + r2);
if (r2 != null) {
rop.setRegister(r2.getRegister());
DefUse.recordUse(rop);
}
}
}
}
// replace each def
for (int d = 0; d < A.getNumberOfDefs(); d++) {
Operand op = A.getOperand(d);
if (op instanceof RegisterOperand) {
RegisterOperand rop = (RegisterOperand) op;
Register r1 = rop.getRegister();
if (r1.isSSA())
continue;
if (r1.isPhysical())
continue;
Register r2 = ir.regpool.getReg(r1);
if (DEBUG)
System.out.println("PUSH " + r2 + " FOR " + r1 + " BECAUSE " + A);
S[r1.getNumber()].push(new RegisterOperand(r2, rop.getType()));
rop.setRegister(r2);
pushedRegs.put(r2, r1);
}
}
}
if (DEBUG)
System.out.println("SEARCH (second loop) " + X);
for (Enumeration<BasicBlock> y = X.getOut(); y.hasMoreElements(); ) {
BasicBlock Y = y.nextElement();
if (DEBUG)
System.out.println(" Successor: " + Y);
int j = numPredProcessed[Y.getNumber()]++;
if (Y.isExit())
continue;
Instruction s = Y.firstRealInstruction();
if (s == null)
continue;
// replace use USE in each PHI instruction
if (DEBUG)
System.out.println(" Predecessor: " + j);
while (s.operator() == PHI) {
Operand val = Phi.getValue(s, j);
if (val.isRegister()) {
Register r1 = ((RegisterOperand) Phi.getValue(s, j)).getRegister();
// ignore registers already marked SSA by a previous pass
if (!r1.isSSA()) {
RegisterOperand r2 = S[r1.getNumber()].peek();
if (r2 == null) {
// in this case, the register is never defined along
// this particular control flow path into the basic
// block.
Phi.setValue(s, j, new UnreachableOperand());
} else {
RegisterOperand rop = r2.copyRO();
Phi.setValue(s, j, rop);
DefUse.recordUse(rop);
}
Phi.setPred(s, j, new BasicBlockOperand(X));
}
}
s = s.nextInstructionInCodeOrder();
}
}
if (DEBUG)
System.out.println("SEARCH (third loop) " + X);
for (Enumeration<TreeNode> c = ir.HIRInfo.dominatorTree.getChildren(X); c.hasMoreElements(); ) {
DominatorTreeNode v = (DominatorTreeNode) c.nextElement();
search(v.getBlock(), S);
}
if (DEBUG)
System.out.println("SEARCH (fourth loop) " + X);
for (Enumeration<Instruction> a = X.forwardInstrEnumerator(); a.hasMoreElements(); ) {
Instruction A = a.nextElement();
// loop over each def
for (int d = 0; d < A.getNumberOfDefs(); d++) {
Operand newOp = A.getOperand(d);
if (newOp == null)
continue;
if (!newOp.isRegister())
continue;
Register newReg = newOp.asRegister().getRegister();
if (newReg.isSSA())
continue;
if (newReg.isPhysical())
continue;
Register r1 = pushedRegs.get(newReg);
S[r1.getNumber()].pop();
if (DEBUG)
System.out.println("POP " + r1);
}
}
// end of fourth loop
if (DEBUG)
System.out.println("FINISHED SEARCH " + X);
}
Aggregations