Search in sources :

Example 1 with ExceptionHandlerBasicBlock

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);
    }
}
Also used : GenerationContext(org.jikesrvm.compilers.opt.bc2ir.GenerationContext) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) ExceptionHandlerBasicBlockBag(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)

Example 2 with ExceptionHandlerBasicBlock

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());
        }
    }
}
Also used : ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)

Example 3 with ExceptionHandlerBasicBlock

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();
    }
}
Also used : BitVector(org.jikesrvm.util.BitVector) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)

Example 4 with ExceptionHandlerBasicBlock

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;
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)

Example 5 with ExceptionHandlerBasicBlock

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);
}
Also used : BasicBlock(org.jikesrvm.compilers.opt.ir.BasicBlock) ExceptionHandlerBasicBlock(org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)

Aggregations

ExceptionHandlerBasicBlock (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlock)17 BasicBlock (org.jikesrvm.compilers.opt.ir.BasicBlock)16 ExceptionHandlerBasicBlockBag (org.jikesrvm.compilers.opt.ir.ExceptionHandlerBasicBlockBag)6 Instruction (org.jikesrvm.compilers.opt.ir.Instruction)5 HashSet (java.util.HashSet)2 TypeReference (org.jikesrvm.classloader.TypeReference)2 Operand (org.jikesrvm.compilers.opt.ir.operand.Operand)2 RegisterOperand (org.jikesrvm.compilers.opt.ir.operand.RegisterOperand)2 TypeOperand (org.jikesrvm.compilers.opt.ir.operand.TypeOperand)2 OutEdgeEnumeration (org.jikesrvm.compilers.opt.util.SpaceEffGraphNode.OutEdgeEnumeration)2 RVMMethod (org.jikesrvm.classloader.RVMMethod)1 GenerationContext (org.jikesrvm.compilers.opt.bc2ir.GenerationContext)1 OsrPoint (org.jikesrvm.compilers.opt.ir.OsrPoint)1 RegSpillListElement (org.jikesrvm.compilers.opt.ir.RegSpillListElement)1 Register (org.jikesrvm.compilers.opt.ir.Register)1 PhysicalRegisterSet (org.jikesrvm.compilers.opt.ir.ia32.PhysicalRegisterSet)1 AddressConstantOperand (org.jikesrvm.compilers.opt.ir.operand.AddressConstantOperand)1 BasicBlockOperand (org.jikesrvm.compilers.opt.ir.operand.BasicBlockOperand)1 BranchProfileOperand (org.jikesrvm.compilers.opt.ir.operand.BranchProfileOperand)1 ClassConstantOperand (org.jikesrvm.compilers.opt.ir.operand.ClassConstantOperand)1