summaryrefslogtreecommitdiff
path: root/lib/CodeGen/DwarfEHPrepare.cpp
diff options
context:
space:
mode:
authorBill Wendling <isanbard@gmail.com>2011-08-17 19:48:49 +0000
committerBill Wendling <isanbard@gmail.com>2011-08-17 19:48:49 +0000
commit35adbb3e4829d3a14784c2bb8ec768b6154c2107 (patch)
treef873496726b644b1f128cd3bd9c2207b480c3411 /lib/CodeGen/DwarfEHPrepare.cpp
parentc1dbf0cdb44a291647e42be9f3621886dedb5235 (diff)
downloadllvm-35adbb3e4829d3a14784c2bb8ec768b6154c2107.tar.gz
llvm-35adbb3e4829d3a14784c2bb8ec768b6154c2107.tar.bz2
llvm-35adbb3e4829d3a14784c2bb8ec768b6154c2107.tar.xz
Modify for the new EH scheme.
Things are much saner now. We no longer need to modify the laning pads, because of the invariants we impose upon them. The only thing DwarfEHPrepare needs to do is convert the 'resume' instruction into a call to '_Unwind_Resume'. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@137855 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/DwarfEHPrepare.cpp')
-rw-r--r--lib/CodeGen/DwarfEHPrepare.cpp58
1 files changed, 57 insertions, 1 deletions
diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp
index 03604b0a17..3aa72ee196 100644
--- a/lib/CodeGen/DwarfEHPrepare.cpp
+++ b/lib/CodeGen/DwarfEHPrepare.cpp
@@ -63,6 +63,8 @@ namespace {
typedef SmallPtrSet<BasicBlock*, 8> BBSet;
BBSet LandingPads;
+ bool InsertUnwindResumeCalls();
+
bool NormalizeLandingPads();
bool LowerUnwindsAndResumes();
bool MoveExceptionValueCalls();
@@ -658,13 +660,67 @@ Instruction *DwarfEHPrepare::CreateExceptionValueCall(BasicBlock *BB) {
return CallInst::Create(ExceptionValueIntrinsic, "eh.value.call", Start);
}
+/// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present
+/// into calls to the appropriate _Unwind_Resume function.
+bool DwarfEHPrepare::InsertUnwindResumeCalls() {
+ SmallVector<ResumeInst*, 16> Resumes;
+ for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
+ for (BasicBlock::iterator II = I->begin(), IE = I->end(); II != IE; ++II)
+ if (ResumeInst *RI = dyn_cast<ResumeInst>(II))
+ Resumes.push_back(RI);
+
+ if (Resumes.empty())
+ return false;
+
+ // Find the rewind function if we didn't already.
+ if (!RewindFunction) {
+ LLVMContext &Ctx = Resumes[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);
+ }
+
+ // Create the basic block where the _Unwind_Resume call will live.
+ LLVMContext &Ctx = F->getContext();
+ BasicBlock *UnwindBB = BasicBlock::Create(Ctx, "unwind_resume", F);
+ PHINode *PN = PHINode::Create(Type::getInt8PtrTy(Ctx), Resumes.size(),
+ "exn.obj", UnwindBB);
+
+ // Extract the exception object from the ResumeInst and add it to the PHI node
+ // that feeds the _Unwind_Resume call.
+ for (SmallVectorImpl<ResumeInst*>::iterator
+ I = Resumes.begin(), E = Resumes.end(); I != E; ++I) {
+ ResumeInst *RI = *I;
+ BranchInst::Create(UnwindBB, RI->getParent());
+ ExtractValueInst *ExnObj = ExtractValueInst::Create(RI->getOperand(0),
+ 0, "exn.obj", RI);
+ PN->addIncoming(ExnObj, RI->getParent());
+ RI->eraseFromParent();
+ }
+
+ // Call the function.
+ CallInst *CI = CallInst::Create(RewindFunction, PN, "", UnwindBB);
+ CI->setCallingConv(TLI->getLibcallCallingConv(RTLIB::UNWIND_RESUME));
+
+ // We never expect _Unwind_Resume to return.
+ new UnreachableInst(Ctx, UnwindBB);
+ return true;
+}
+
bool DwarfEHPrepare::runOnFunction(Function &Fn) {
bool Changed = false;
// Initialize internal state.
- DT = &getAnalysis<DominatorTree>();
+ DT = &getAnalysis<DominatorTree>(); // FIXME: We won't need this with the new EH.
F = &Fn;
+ if (InsertUnwindResumeCalls()) {
+ // FIXME: The reset of this function can go once the new EH is done.
+ LandingPads.clear();
+ return true;
+ }
+
// Ensure that only unwind edges end at landing pads (a landing pad is a
// basic block where an invoke unwind edge ends).
Changed |= NormalizeLandingPads();