use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock in project JikesRVM by JikesRVM.
the class Inliner method execute.
/**
* Execute an inlining decision inlDec for the CALL instruction
* callSite that is contained in ir.
*
* @param inlDec the inlining decision to execute
* @param ir the governing IR
* @param callSite the call site to inline
*/
public static void execute(InlineDecision inlDec, IR ir, Instruction callSite) {
// Find out where the call site is and isolate it in its own basic block.
BasicBlock bb = callSite.getBasicBlock().segregateInstruction(callSite, ir);
BasicBlock in = bb.prevBasicBlockInCodeOrder();
BasicBlock out = bb.nextBasicBlockInCodeOrder();
// We need to ensure that inlining the CALL instruction does not
// insert any new exceptional edges into the CFG that were not
// present before the inlining. Note that inlining the CALL may
// introduce new CALLS, for which we don't know the exception
// behavior. However, we know that any new PEIs introduced in the
// inlined code had better not add exceptional edges to the
// original CFG. So, create a new ExceptionHandlerBasicBlockBag
// which will enforce this behavior.
ExceptionHandlerBasicBlock[] catchBlocks = new ExceptionHandlerBasicBlock[bb.getNumberOfExceptionalOut()];
Enumeration<BasicBlock> e = bb.getExceptionalOut();
for (int i = 0; i < catchBlocks.length; i++) {
catchBlocks[i] = (ExceptionHandlerBasicBlock) e.nextElement();
}
ExceptionHandlerBasicBlockBag bag = new ExceptionHandlerBasicBlockBag(catchBlocks, null);
// Execute the inlining decision, updating ir.gc's state.
GenerationContext childgc = execute(inlDec, ir.getGc(), bag, callSite);
// Splice the callee into the caller's code order
ir.cfg.removeFromCFGAndCodeOrder(bb);
ir.cfg.breakCodeOrder(in, out);
ir.cfg.linkInCodeOrder(in, childgc.getCfg().firstInCodeOrder());
ir.cfg.linkInCodeOrder(childgc.getCfg().lastInCodeOrder(), out);
// Splice the callee into the caller's CFG
in.insertOut(childgc.getPrologue());
if (childgc.getEpilogue() != null) {
childgc.getEpilogue().insertOut(out);
}
}
use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock in project JikesRVM by JikesRVM.
the class DepGraph method computeHandlerLiveSet.
/**
* Determine the set of variables live on entry to any handler
* block that is reachable from currentBlock
*/
private void computeHandlerLiveSet() {
if (ir.getHandlerLivenessComputed() && currentBlock.hasExceptionHandlers()) {
Enumeration<BasicBlock> e = currentBlock.getExceptionalOut();
while (e.hasMoreElements()) {
ExceptionHandlerBasicBlock handlerBlock = (ExceptionHandlerBasicBlock) e.nextElement();
handlerLiveSet.add(handlerBlock.getLiveSet());
}
}
}
use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock in project JikesRVM by JikesRVM.
the class LoopUnrolling method naiveUnroller.
private void naiveUnroller(LSTNode t, IR ir) {
BitVector nloop = t.getLoop();
BasicBlock seqStart = null;
Enumeration<BasicBlock> bs;
if (t.getLoop().populationCount() > MAX_BLOCKS_FOR_NAIVE_UNROLLING) {
report("1 is too big");
return;
}
report("Naively unrolling");
CFGTransformations.killFallThroughs(ir, nloop);
// first, capture the blocks in the loop body.
int bodyBlocks = nloop.populationCount();
BasicBlock[] body = new BasicBlock[bodyBlocks];
{
int i = 0;
bs = ir.getBasicBlocks(nloop);
while (bs.hasMoreElements()) {
BasicBlock b = bs.nextElement();
if (VM.VerifyAssertions) {
VM._assert(!(b instanceof ExceptionHandlerBasicBlock));
}
body[i++] = b;
BasicBlock next = b.nextBasicBlockInCodeOrder();
if (next == null || !CFGTransformations.inLoop(next, nloop)) {
// end of loop in code order
seqStart = b;
}
}
}
BasicBlock seqEnd = seqStart.nextBasicBlockInCodeOrder();
if (seqEnd != null)
ir.cfg.breakCodeOrder(seqStart, seqEnd);
BasicBlock seqLast = seqStart;
BasicBlock firstHeaderCopy = null;
BasicBlock currentBlock = seqLast;
for (int i = 1; i <= unrollFactor; ++i) {
// copy body
for (BasicBlock bb : body) {
seqLast = copyAndLinkBlock(ir, seqLast, bb);
if (bb == t.header) {
if (firstHeaderCopy == null) {
firstHeaderCopy = seqLast;
}
}
}
// redirect internal branches
currentBlock = seqLast;
for (int j = 0; j < bodyBlocks; ++j) {
currentBlock.recomputeNormalOut(ir);
Enumeration<BasicBlock> be = currentBlock.getOut();
while (be.hasMoreElements()) {
BasicBlock out = be.nextElement();
if (out != t.header && CFGTransformations.inLoop(out, nloop)) {
BasicBlock outCopy = copiedBlocks.get(out);
currentBlock.redirectOuts(out, outCopy, ir);
}
}
currentBlock.recomputeNormalOut(ir);
currentBlock = currentBlock.prevBasicBlockInCodeOrder();
}
if (i != 1) {
// redirect the branches to the header in the (i-1)th copy
for (int j = 0; j < bodyBlocks; ++j) {
Enumeration<BasicBlock> be = currentBlock.getOut();
while (be.hasMoreElements()) {
BasicBlock out = be.nextElement();
if (out == t.header) {
BasicBlock headerCopy;
headerCopy = copiedBlocks.get(t.header);
currentBlock.redirectOuts(t.header, headerCopy, ir);
}
}
currentBlock.recomputeNormalOut(ir);
currentBlock = currentBlock.prevBasicBlockInCodeOrder();
}
}
}
if (seqEnd != null)
ir.cfg.linkInCodeOrder(seqLast, seqEnd);
for (int j = 0; j < bodyBlocks; ++j) {
Enumeration<BasicBlock> be = body[j].getOut();
while (be.hasMoreElements()) {
BasicBlock out = be.nextElement();
if (out == t.header) {
body[j].redirectOuts(t.header, firstHeaderCopy, ir);
}
}
body[j].recomputeNormalOut(ir);
}
// the following loop redirects backedges that start in the last
// copy to point to the first copy instead and not to the original
// header.
// | |
// Thus we get [ ] instead of [ ]<-.
// | | |
// [ ]<-. [ ] |
// | | | |
// [ ] | [ ] |
// | | | |
// [ ] | [ ] |
// |\_/ |\_/
//
// Instead of 2^(unroll_log) we only have 2^(unroll_log-1) bodies
// in the unrolled loop, but there is one copy of the loop's body
// that dominates the unrolled version. Peeling of this first
// version should have benefits for global code placement.
currentBlock = seqLast;
for (int j = 0; j < bodyBlocks; ++j) {
Enumeration<BasicBlock> be = currentBlock.getOut();
while (be.hasMoreElements()) {
BasicBlock out = be.nextElement();
if (out == t.header) {
currentBlock.redirectOuts(t.header, firstHeaderCopy, ir);
}
}
currentBlock.recomputeNormalOut(ir);
currentBlock = currentBlock.prevBasicBlockInCodeOrder();
}
}
use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock in project JikesRVM by JikesRVM.
the class OptExceptionTable method countExceptionTableSize.
/**
* @param ir the IR with the exception tables
* @return an upper bound on the size of the exception table for an IR.
*/
private static int countExceptionTableSize(IR ir) {
int tSize = 0;
for (BasicBlock bblock = ir.firstBasicBlockInCodeOrder(); bblock != null; bblock = bblock.nextBasicBlockInCodeOrder()) {
if (bblock.hasExceptionHandlers()) {
for (Enumeration<BasicBlock> e = bblock.getExceptionHandlers(); e.hasMoreElements(); ) {
ExceptionHandlerBasicBlock ebb = (ExceptionHandlerBasicBlock) e.nextElement();
tSize += ebb.getNumberOfExceptionTableEntries();
}
}
}
return tSize;
}
use of org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock in project JikesRVM by JikesRVM.
the class GenerationContextTest method assertThatEnclosingHandlersContainRethrow.
private void assertThatEnclosingHandlersContainRethrow(ExceptionHandlerBasicBlock rethrow, ExceptionHandlerBasicBlockBag ehbbb) {
boolean rethrowFound = false;
Enumeration<BasicBlock> exceptionHandlerBasicBlocks = ehbbb.enumerator();
while (exceptionHandlerBasicBlocks.hasMoreElements()) {
BasicBlock nextElement = exceptionHandlerBasicBlocks.nextElement();
if (nextElement == rethrow) {
rethrowFound = true;
}
}
assertTrue(rethrowFound);
}
Aggregations