Beispiel #1
0
/// HandleInlinedInvoke - If we inlined an invoke site, we need to convert calls
/// in the body of the inlined function into invokes.
///
/// II is the invoke instruction being inlined.  FirstNewBlock is the first
/// block of the inlined code (the last block is the end of the function),
/// and InlineCodeInfo is information about the code that got inlined.
static void HandleInlinedInvoke(InvokeInst *II, BasicBlock *FirstNewBlock,
                                ClonedCodeInfo &InlinedCodeInfo) {
    BasicBlock *InvokeDest = II->getUnwindDest();

    Function *Caller = FirstNewBlock->getParent();

    // The inlined code is currently at the end of the function, scan from the
    // start of the inlined code to its end, checking for stuff we need to
    // rewrite.
    InvokeInliningInfo Invoke(II);

    // Get all of the inlined landing pad instructions.
    SmallPtrSet<LandingPadInst*, 16> InlinedLPads;
    for (Function::iterator I = FirstNewBlock, E = Caller->end(); I != E; ++I)
        if (InvokeInst *II = dyn_cast<InvokeInst>(I->getTerminator()))
            InlinedLPads.insert(II->getLandingPadInst());

    // Append the clauses from the outer landing pad instruction into the inlined
    // landing pad instructions.
    LandingPadInst *OuterLPad = Invoke.getLandingPadInst();
    for (SmallPtrSet<LandingPadInst*, 16>::iterator I = InlinedLPads.begin(),
            E = InlinedLPads.end(); I != E; ++I) {
        LandingPadInst *InlinedLPad = *I;
        unsigned OuterNum = OuterLPad->getNumClauses();
        InlinedLPad->reserveClauses(OuterNum);
        for (unsigned OuterIdx = 0; OuterIdx != OuterNum; ++OuterIdx)
            InlinedLPad->addClause(OuterLPad->getClause(OuterIdx));
        if (OuterLPad->isCleanup())
            InlinedLPad->setCleanup(true);
    }

    for (Function::iterator BB = FirstNewBlock, E = Caller->end(); BB != E; ++BB) {
        if (InlinedCodeInfo.ContainsCalls)
            HandleCallsInBlockInlinedThroughInvoke(BB, Invoke);

        // Forward any resumes that are remaining here.
        if (ResumeInst *RI = dyn_cast<ResumeInst>(BB->getTerminator()))
            Invoke.forwardResume(RI, InlinedLPads);
    }

    // Now that everything is happy, we have one final detail.  The PHI nodes in
    // the exception destination block still have entries due to the original
    // invoke instruction. Eliminate these entries (which might even delete the
    // PHI node) now.
    InvokeDest->removePredecessor(II->getParent());
}