- Changed |= CleanupSelectors(CatchAllSels);
- return Changed;
-}
-
-/// NormalizeLandingPads - Normalize and discover landing pads, noting them
-/// in the LandingPads set. A landing pad is normal if the only CFG edges
-/// that end at it are unwind edges from invoke instructions. If we inlined
-/// through an invoke we could have a normal branch from the previous
-/// unwind block through to the landing pad for the original invoke.
-/// Abnormal landing pads are fixed up by redirecting all unwind edges to
-/// a new basic block which falls through to the original.
-bool DwarfEHPrepare::NormalizeLandingPads() {
- bool Changed = false;
-
- const MCAsmInfo *MAI = TM->getMCAsmInfo();
- bool usingSjLjEH = MAI->getExceptionHandlingType() == ExceptionHandling::SjLj;
-
- for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) {
- TerminatorInst *TI = I->getTerminator();
- if (!isa<InvokeInst>(TI))
- continue;
- BasicBlock *LPad = TI->getSuccessor(1);
- // Skip landing pads that have already been normalized.
- if (LandingPads.count(LPad))
- continue;
-
- // Check that only invoke unwind edges end at the landing pad.
- bool OnlyUnwoundTo = true;
- bool SwitchOK = usingSjLjEH;
- for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad);
- PI != PE; ++PI) {
- TerminatorInst *PT = (*PI)->getTerminator();
- // The SjLj dispatch block uses a switch instruction. This is effectively
- // an unwind edge, so we can disregard it here. There will only ever
- // be one dispatch, however, so if there are multiple switches, one
- // of them truly is a normal edge, not an unwind edge.
- if (SwitchOK && isa<SwitchInst>(PT)) {
- SwitchOK = false;
- continue;
- }
- if (!isa<InvokeInst>(PT) || LPad == PT->getSuccessor(0)) {
- OnlyUnwoundTo = false;
- break;
- }
- }
-
- if (OnlyUnwoundTo) {
- // Only unwind edges lead to the landing pad. Remember the landing pad.
- LandingPads.insert(LPad);
- continue;
- }
-
- // At least one normal edge ends at the landing pad. Redirect the unwind
- // edges to a new basic block which falls through into this one.
-
- // Create the new basic block.
- BasicBlock *NewBB = BasicBlock::Create(F->getContext(),
- LPad->getName() + "_unwind_edge");
-
- // Insert it into the function right before the original landing pad.
- LPad->getParent()->getBasicBlockList().insert(LPad, NewBB);
-
- // Redirect unwind edges from the original landing pad to NewBB.
- for (pred_iterator PI = pred_begin(LPad), PE = pred_end(LPad); PI != PE; ) {
- TerminatorInst *PT = (*PI++)->getTerminator();
- if (isa<InvokeInst>(PT) && PT->getSuccessor(1) == LPad)
- // Unwind to the new block.
- PT->setSuccessor(1, NewBB);
- }
-
- // If there are any PHI nodes in LPad, we need to update them so that they
- // merge incoming values from NewBB instead.
- for (BasicBlock::iterator II = LPad->begin(); isa<PHINode>(II); ++II) {
- PHINode *PN = cast<PHINode>(II);
- pred_iterator PB = pred_begin(NewBB), PE = pred_end(NewBB);
-
- // Check to see if all of the values coming in via unwind edges are the
- // same. If so, we don't need to create a new PHI node.
- Value *InVal = PN->getIncomingValueForBlock(*PB);
- for (pred_iterator PI = PB; PI != PE; ++PI) {
- if (PI != PB && InVal != PN->getIncomingValueForBlock(*PI)) {
- InVal = 0;
- break;
- }
- }
-
- if (InVal == 0) {
- // Different unwind edges have different values. Create a new PHI node
- // in NewBB.
- PHINode *NewPN = PHINode::Create(PN->getType(),
- PN->getNumIncomingValues(),
- PN->getName()+".unwind", NewBB);
- // Add an entry for each unwind edge, using the value from the old PHI.
- for (pred_iterator PI = PB; PI != PE; ++PI)
- NewPN->addIncoming(PN->getIncomingValueForBlock(*PI), *PI);
-
- // Now use this new PHI as the common incoming value for NewBB in PN.
- InVal = NewPN;
- }
-
- // Revector exactly one entry in the PHI node to come from NewBB
- // and delete all other entries that come from unwind edges. If
- // there are both normal and unwind edges from the same predecessor,
- // this leaves an entry for the normal edge.
- for (pred_iterator PI = PB; PI != PE; ++PI)
- PN->removeIncomingValue(*PI);
- PN->addIncoming(InVal, NewBB);
- }
-
- // Add a fallthrough from NewBB to the original landing pad.
- BranchInst::Create(LPad, NewBB);
-
- // Now update DominatorTree analysis information.
- DT->splitBlock(NewBB);
-
- // Remember the newly constructed landing pad. The original landing pad
- // LPad is no longer a landing pad now that all unwind edges have been
- // revectored to NewBB.
- LandingPads.insert(NewBB);
- ++NumLandingPadsSplit;
- Changed = true;
- }
-
- return Changed;
-}
-
-/// LowerUnwinds - Turn unwind instructions into calls to _Unwind_Resume,
-/// rethrowing any previously caught exception. This will crash horribly
-/// at runtime if there is no such exception: using unwind to throw a new
-/// exception is currently not supported.
-bool DwarfEHPrepare::LowerUnwindsAndResumes() {
- SmallVector<Instruction*, 16> ResumeInsts;
-
- for (Function::iterator fi = F->begin(), fe = F->end(); fi != fe; ++fi) {
- for (BasicBlock::iterator bi = fi->begin(), be = fi->end(); bi != be; ++bi){
- if (isa<UnwindInst>(bi))
- ResumeInsts.push_back(bi);
- else if (CallInst *call = dyn_cast<CallInst>(bi))
- if (Function *fn = dyn_cast<Function>(call->getCalledValue()))
- if (fn->getName() == "llvm.eh.resume")
- ResumeInsts.push_back(bi);
- }
- }
-
- if (ResumeInsts.empty()) return false;
-
- // Find the rewind function if we didn't already.
- if (!RewindFunction) {
- LLVMContext &Ctx = ResumeInsts[0]->getContext();
- FunctionType *FTy = FunctionType::get(Type::getVoidTy(Ctx),
- Type::getInt8PtrTy(Ctx), false);
- const char *RewindName = TLI->getLibcallName(RTLIB::UNWIND_RESUME);
- RewindFunction = F->getParent()->getOrInsertFunction(RewindName, FTy);
- }
-
- bool Changed = false;
-
- for (SmallVectorImpl<Instruction*>::iterator
- I = ResumeInsts.begin(), E = ResumeInsts.end(); I != E; ++I) {
- Instruction *RI = *I;
-
- // Replace the resuming instruction with a call to _Unwind_Resume (or the
- // appropriate target equivalent).
-
- llvm::Value *ExnValue;
- if (isa<UnwindInst>(RI))
- ExnValue = CreateExceptionValueCall(RI->getParent());
- else
- ExnValue = cast<CallInst>(RI)->getArgOperand(0);
-
- // Create the call...
- CallInst *CI = CallInst::Create(RewindFunction, ExnValue, "", RI);
- CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));
-
- // ...followed by an UnreachableInst, if it was an unwind.
- // Calls to llvm.eh.resume are typically already followed by this.
- if (isa<UnwindInst>(RI))
- new UnreachableInst(RI->getContext(), RI);
-
- if (isa<UnwindInst>(RI))
- ++NumUnwindsLowered;
- else
- ++NumResumesLowered;
-
- // Nuke the resume instruction.
- RI->eraseFromParent();
-
- Changed = true;
- }
-
- return Changed;
-}
-
-/// MoveExceptionValueCalls - Ensure that eh.exception is only ever called from
-/// landing pads by replacing calls outside of landing pads with direct use of
-/// a register holding the appropriate value; this requires adding calls inside
-/// all landing pads to initialize the register. Also, move eh.exception calls
-/// inside landing pads to the start of the landing pad (optional, but may make
-/// things simpler for later passes).
-bool DwarfEHPrepare::MoveExceptionValueCalls() {
- // If the eh.exception intrinsic is not declared in the module then there is
- // nothing to do. Speed up compilation by checking for this common case.
- if (!ExceptionValueIntrinsic &&
- !F->getParent()->getFunction(Intrinsic::getName(Intrinsic::eh_exception)))
- return false;
-
- bool Changed = false;
-
- // Move calls to eh.exception that are inside a landing pad to the start of
- // the landing pad.
- for (BBSet::const_iterator LI = LandingPads.begin(), LE = LandingPads.end();
- LI != LE; ++LI) {
- BasicBlock *LP = *LI;
- for (BasicBlock::iterator II = LP->getFirstNonPHIOrDbg(), IE = LP->end();
- II != IE;)
- if (EHExceptionInst *EI = dyn_cast<EHExceptionInst>(II++)) {
- // Found a call to eh.exception.
- if (!EI->use_empty()) {
- // If there is already a call to eh.exception at the start of the
- // landing pad, then get hold of it; otherwise create such a call.
- Value *CallAtStart = CreateExceptionValueCall(LP);
-
- // If the call was at the start of a landing pad then leave it alone.
- if (EI == CallAtStart)
- continue;
- EI->replaceAllUsesWith(CallAtStart);
- }
- EI->eraseFromParent();
- ++NumExceptionValuesMoved;
- Changed = true;
- }
- }
-
- // Look for calls to eh.exception that are not in a landing pad. If one is
- // found, then a register that holds the exception value will be created in
- // each landing pad, and the SSAUpdater will be used to compute the values
- // returned by eh.exception calls outside of landing pads.
- SSAUpdater SSA;
-
- // Remember where we found the eh.exception call, to avoid rescanning earlier
- // basic blocks which we already know contain no eh.exception calls.
- bool FoundCallOutsideLandingPad = false;
- Function::iterator BB = F->begin();
- for (Function::iterator BE = F->end(); BB != BE; ++BB) {
- // Skip over landing pads.
- if (LandingPads.count(BB))
- continue;
-
- for (BasicBlock::iterator II = BB->getFirstNonPHIOrDbg(), IE = BB->end();
- II != IE; ++II)
- if (isa<EHExceptionInst>(II)) {
- SSA.Initialize(II->getType(), II->getName());
- FoundCallOutsideLandingPad = true;
- break;
- }
-
- if (FoundCallOutsideLandingPad)
- break;
- }
-
- // If all calls to eh.exception are in landing pads then we are done.
- if (!FoundCallOutsideLandingPad)
- return Changed;
-
- // Add a call to eh.exception at the start of each landing pad, and tell the
- // SSAUpdater that this is the value produced by the landing pad.
- for (BBSet::iterator LI = LandingPads.begin(), LE = LandingPads.end();
- LI != LE; ++LI)
- SSA.AddAvailableValue(*LI, CreateExceptionValueCall(*LI));
-
- // Now turn all calls to eh.exception that are not in a landing pad into a use
- // of the appropriate register.
- for (Function::iterator BE = F->end(); BB != BE; ++BB) {
- // Skip over landing pads.
- if (LandingPads.count(BB))
- continue;
-
- for (BasicBlock::iterator II = BB->getFirstNonPHIOrDbg(), IE = BB->end();
- II != IE;)
- if (EHExceptionInst *EI = dyn_cast<EHExceptionInst>(II++)) {
- // Found a call to eh.exception, replace it with the value from any
- // upstream landing pad(s).
- EI->replaceAllUsesWith(SSA.GetValueAtEndOfBlock(BB));
- EI->eraseFromParent();
- ++NumExceptionValuesMoved;
- }
- }
-
- return true;
-}
-
-/// CreateExceptionValueCall - Insert a call to the eh.exception intrinsic at
-/// the start of the basic block (unless there already is one, in which case
-/// the existing call is returned).
-Instruction *DwarfEHPrepare::CreateExceptionValueCall(BasicBlock *BB) {
- Instruction *Start = BB->getFirstNonPHIOrDbg();
- // Is this a call to eh.exception?
- if (IntrinsicInst *CI = dyn_cast<IntrinsicInst>(Start))
- if (CI->getIntrinsicID() == Intrinsic::eh_exception)
- // Reuse the existing call.
- return Start;
-
- // Find the eh.exception intrinsic if we didn't already.
- if (!ExceptionValueIntrinsic)
- ExceptionValueIntrinsic = Intrinsic::getDeclaration(F->getParent(),
- Intrinsic::eh_exception);
-
- // Create the call.
- return CallInst::Create(ExceptionValueIntrinsic, "eh.value.call", Start);