use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class EnterSSA method patchPEIgeneratedValues.
/**
* Work around some problems with PEI-generated values and
* handlers. Namely, if a PEI has a return value, rename the
* result register before and after the PEI in order to reflect the fact
* that the PEI may not actually assign the result register.
*/
private void patchPEIgeneratedValues() {
// this only applies if there are exception handlers
if (!ir.hasReachableExceptionHandlers())
return;
HashSet<Pair<BasicBlock, RegisterOperand>> needed = new HashSet<Pair<BasicBlock, RegisterOperand>>(4);
Enumeration<BasicBlock> blocks = ir.getBasicBlocks();
while (blocks.hasMoreElements()) {
BasicBlock block = blocks.nextElement();
if (block.getExceptionalOut().hasMoreElements()) {
Instruction pei = block.lastRealInstruction();
if (pei != null && pei.isPEI() && ResultCarrier.conforms(pei)) {
boolean copyNeeded = false;
RegisterOperand v = ResultCarrier.getResult(pei);
// void calls and the like... :(
if (v != null) {
Register orig = v.getRegister();
{
Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
while (out.hasMoreElements()) {
BasicBlock exp = out.nextElement();
LiveSet explive = live.getLiveInfo(exp).getIn();
if (explive.contains(orig)) {
copyNeeded = true;
break;
}
}
}
if (copyNeeded) {
Enumeration<BasicBlock> out = block.getApplicableExceptionalOut(pei);
while (out.hasMoreElements()) {
BasicBlock exp = out.nextElement();
needed.add(new Pair<BasicBlock, RegisterOperand>(exp, v));
}
}
}
}
}
}
// having determine where copies should be inserted, now insert them.
if (!needed.isEmpty()) {
for (Pair<BasicBlock, RegisterOperand> copy : needed) {
BasicBlock inBlock = copy.first;
RegisterOperand registerOp = copy.second;
TypeReference type = registerOp.getType();
Register register = registerOp.getRegister();
Register temp = ir.regpool.getReg(register);
inBlock.prependInstruction(SSA.makeMoveInstruction(ir, register, temp, type));
Enumeration<BasicBlock> outBlocks = inBlock.getIn();
while (outBlocks.hasMoreElements()) {
BasicBlock outBlock = outBlocks.nextElement();
Instruction x = SSA.makeMoveInstruction(ir, temp, register, type);
SSA.addAtEnd(ir, outBlock, x, true);
}
}
// Recompute liveness information. You might be tempted to incrementally
// update it, but it's tricky, so resist.....do the obvious, but easy thing!
prepare();
}
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock 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.BasicBlock in project JikesRVM by JikesRVM.
the class EnterSSA method computeNonLocals.
/**
* Pass through the IR and calculate which registers are not
* local to a basic block. Store the result in the <code> nonLocalRegisters
* </code> field.
*/
@SuppressWarnings("unused")
private void computeNonLocals() {
nonLocalRegisters = new HashSet<Register>(20);
Enumeration<BasicBlock> blocks = ir.getBasicBlocks();
while (blocks.hasMoreElements()) {
HashSet<Register> killed = new HashSet<Register>(5);
BasicBlock block = blocks.nextElement();
Enumeration<Instruction> instrs = block.forwardRealInstrEnumerator();
while (instrs.hasMoreElements()) {
Instruction instr = instrs.nextElement();
Enumeration<Operand> uses = instr.getUses();
while (uses.hasMoreElements()) {
Operand op = uses.nextElement();
if (op instanceof RegisterOperand) {
if (!killed.contains(op.asRegister().getRegister())) {
nonLocalRegisters.add(op.asRegister().getRegister());
}
}
}
Enumeration<Operand> defs = instr.getDefs();
while (defs.hasMoreElements()) {
Operand op = defs.nextElement();
if (op instanceof RegisterOperand) {
killed.add(op.asRegister().getRegister());
}
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class EnterSSA method registerCalls.
/**
* Register every CALL instruction in this method with the
* implicit heap array SSA look aside structure.
* Namely, mark that this instruction defs and uses <em> every </em>
* type of heap variable in the IR's SSA dictionary.
*
* @param ir the governing IR
*/
private void registerCalls(IR ir) {
SSADictionary dictionary = ir.HIRInfo.dictionary;
for (Enumeration<BasicBlock> bbe = ir.getBasicBlocks(); bbe.hasMoreElements(); ) {
BasicBlock b = bbe.nextElement();
for (Enumeration<Instruction> e = b.forwardInstrEnumerator(); e.hasMoreElements(); ) {
Instruction s = e.nextElement();
boolean isSynch = (s.operator() == READ_CEILING) || (s.operator() == WRITE_FLOOR) || (s.operator() == FENCE);
if (isSynch || Call.conforms(s) || MonitorOp.conforms(s) || Prepare.conforms(s) || Attempt.conforms(s) || CacheOp.conforms(s) || s.isDynamicLinkingPoint()) {
dictionary.registerUnknown(s, b);
}
}
}
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock 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;
}
Aggregations