use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class CFGTransformations method loopPredecessors.
private static BasicBlock[] loopPredecessors(LSTNode n) {
BasicBlock header = n.header;
BitVector loop = n.getLoop();
int i = 0;
Enumeration<BasicBlock> be = header.getIn();
while (be.hasMoreElements()) if (!inLoop(be.nextElement(), loop))
i++;
BasicBlock[] res = new BasicBlock[i];
i = 0;
be = header.getIn();
while (be.hasMoreElements()) {
BasicBlock in = be.nextElement();
if (!inLoop(in, loop))
res[i++] = in;
}
return res;
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class CFGTransformations method turnLoopIntoUntil.
/**
* Transforms a given loop.
*
* <p> Look for the set S of in-loop predecessors of the loop header h.
* Make a copy h' of the loop header and redirect all edges going from
* nodes in S to h. Make them point to h' instead.
*
* <p> As an effect of this transformation, the old header is now not anymore
* part of the loop, but guards it.
*
* @param n anode
* @param ir the governing IR
* @return whether anything was changed
*/
private static boolean turnLoopIntoUntil(LSTNode n, IR ir) {
BasicBlock header = n.header;
BasicBlock newLoopTest = null;
int i = 0;
int exiters = 0;
Enumeration<BasicBlock> e = ir.getBasicBlocks(n.getLoop());
while (e.hasMoreElements()) {
BasicBlock b = e.nextElement();
if (!exitsLoop(b, n.getLoop())) {
// header doesn't exit: nothing to do
if (b == n.header)
return false;
} else {
exiters++;
}
i++;
}
// all blocks exit: can't improve
if (i == exiters)
return false;
// rewriting loops where the header has more than one in-loop
// successor will lead to irreducible control flow.
BasicBlock[] succ = inLoopSuccessors(n);
if (succ.length > 1) {
if (DEBUG)
VM.sysWriteln("unwhiling would lead to irreducible CFG");
return false;
}
BasicBlock[] pred = inLoopPredecessors(n);
float frequency = 0f;
if (pred.length > 0) {
frequency += edgeFrequency(pred[0], header);
// replicate the header as successor of pred[0]
BasicBlock p = header.prevBasicBlockInCodeOrder();
p.killFallThrough();
newLoopTest = pred[0].replicateThisOut(ir, header, p);
}
for (i = 1; i < pred.length; ++i) {
// check for aditional back edges
frequency += edgeFrequency(pred[i], header);
pred[i].redirectOuts(header, newLoopTest, ir);
}
newLoopTest.setExecutionFrequency(frequency);
header.setExecutionFrequency(header.getExecutionFrequency() - frequency);
return true;
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class CFGTransformations method splitCriticalEdges.
/**
* Critical edge removal: if (a,b) is an edge in the cfg where `a' has more
* than one out-going edge and `b' has more than one in-coming edge,
* insert a new empty block `c' on the edge between `a' and `b'.
*
* <p> We do this to provide landing pads for loop-invariant code motion.
* So we split only edges, where `a' has a lower loop nesting depth than `b'.
*
* @param ir the IR to process
*/
public static void splitCriticalEdges(IR ir) {
Enumeration<BasicBlock> e = ir.getBasicBlocks();
while (e.hasMoreElements()) {
BasicBlock b = e.nextElement();
int numberOfIns = b.getNumberOfIn();
// are no candidates for `b'.
if (b.isExceptionHandlerBasicBlock() || numberOfIns <= 1) {
continue;
}
// copy the predecessors, since we will alter the incoming edges.
BasicBlock[] ins = new BasicBlock[numberOfIns];
Enumeration<BasicBlock> ie = b.getIn();
for (int i = 0; i < numberOfIns; ++i) {
ins[i] = ie.nextElement();
}
// skip blocks, that do not fulfill our requirements for `a'
for (int i = 0; i < numberOfIns; ++i) {
BasicBlock a = ins[i];
if (a.getNumberOfOut() <= 1) {
continue;
}
// insert pads only for moving code up to the start of the method
// if (a.getExecutionFrequency() >= b.getExecutionFrequency()) continue;
// create a new block as landing pad
BasicBlock landingPad;
Instruction firstInB = b.firstInstruction();
int bcIndex = firstInB != null ? firstInB.getBytecodeIndex() : -1;
landingPad = b.createSubBlock(bcIndex, ir);
landingPad.setLandingPad();
landingPad.setExecutionFrequency(edgeFrequency(a, b));
// make the landing pad jump to `b'
Instruction g;
g = Goto.create(GOTO, b.makeJumpTarget());
landingPad.appendInstruction(g);
landingPad.recomputeNormalOut(ir);
// redirect a's outputs from b to the landing pad
a.redirectOuts(b, landingPad, ir);
a.killFallThrough();
BasicBlock aNext = a.nextBasicBlockInCodeOrder();
if (aNext != null) {
ir.cfg.breakCodeOrder(a, aNext);
ir.cfg.linkInCodeOrder(landingPad, aNext);
}
ir.cfg.linkInCodeOrder(a, landingPad);
}
}
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class CFGTransformations method killFallThroughs.
static void killFallThroughs(IR ir, BitVector nloop) {
Enumeration<BasicBlock> bs = ir.getBasicBlocks(nloop);
while (bs.hasMoreElements()) {
BasicBlock block = bs.nextElement();
Enumeration<BasicBlock> bi = block.getIn();
while (bi.hasMoreElements()) {
BasicBlock in = bi.nextElement();
if (inLoop(in, nloop))
continue;
in.killFallThrough();
}
block.killFallThrough();
}
}
use of org.jikesrvm.compilers.opt.ir.BasicBlock in project JikesRVM by JikesRVM.
the class DominatorSystem method initializeWorkList.
/**
* Initialize the work list for the dataflow equation system.
* <p> The initial work list is every equation containing the start
* node.
*/
@Override
protected void initializeWorkList() {
if (Dominators.COMPUTE_POST_DOMINATORS) {
// WARNING: an "end node" may be part of a cycle
for (Enumeration<BasicBlock> e = ir.getBasicBlocks(); e.hasMoreElements(); ) {
BasicBlock bb = e.nextElement();
addCellAppearancesToWorkList(getCell(bb));
}
} else {
DominatorCell first = (DominatorCell) getCell(ir.cfg.entry());
addCellAppearancesToWorkList(first);
}
}
Aggregations