use of org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode 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.controlflow.DominatorTreeNode in project JikesRVM by JikesRVM.
the class LeaveSSA method translateFromSSA.
/**
* Main driver to translate an IR out of SSA form.
*
* @param ir the IR in SSA form
*/
public void translateFromSSA(IR ir) {
// 0. Deal with guards (validation registers)
unSSAGuards(ir);
// 1. re-compute dominator tree in case of control flow changes
LTDominators.perform(ir, true, true);
DominatorTree dom = new DominatorTree(ir, true);
// 1.5 Perform Sreedhar's naive translation from TSSA to CSSA
// if (ir.options.UNROLL_LOG == 0) normalizeSSA(ir);
// 2. compute liveness
LiveAnalysis live = new // don't create GC maps
LiveAnalysis(// don't create GC maps
false, // skip (final) local propagation step
true, // don't store information at handlers
false, // don't skip guards
false);
live.perform(ir);
// 3. initialization
VariableStacks s = new VariableStacks();
// 4. convert phi nodes into copies
BasicBlock b = ((DominatorTreeNode) dom.getRoot()).getBlock();
insertCopies(b, dom, live);
// 5. If necessary, recompute dominators to account for new control flow.
if (splitSomeBlock) {
LTDominators.perform(ir, true, true);
dom = new DominatorTree(ir, true);
}
// 6. compensate for copies required by simultaneous liveness
performRename(b, dom, s);
// 7. phis are now redundant
removeAllPhis(ir);
}
use of org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode 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);
}
}
}
use of org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode in project JikesRVM by JikesRVM.
the class LeaveSSA method insertCopies.
/**
* Insert copy instructions into a basic block to safely translate out
* of SSA form.
*
* @param bb the basic block
* @param dom a valid dominator tree for the IR
* @param live valid liveness information for the IR
*/
private void insertCopies(BasicBlock bb, DominatorTree dom, LiveAnalysis live) {
// add copies required in this block to remove phis.
// (record renaming required by simultaneous liveness in global tables)
scheduleCopies(bb, live);
// insert copies in control children
Enumeration<TreeNode> children = dom.getChildren(bb);
while (children.hasMoreElements()) {
BasicBlock c = ((DominatorTreeNode) children.nextElement()).getBlock();
insertCopies(c, dom, live);
}
}
use of org.jikesrvm.compilers.opt.controlflow.DominatorTreeNode 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