From b4904503de3195fb611a0aca2e58f4b770ccff51 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 28 Jul 2011 20:48:05 +0000 Subject: Initial code to convert ResumeInsts into calls to _Unwind_Resume. This should be the only code necessary for DWARF EH prepare. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136387 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/DwarfEHPrepare.cpp | 58 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/DwarfEHPrepare.cpp') diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 03604b0..3aa72ee 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -63,6 +63,8 @@ namespace { typedef SmallPtrSet 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 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(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::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(); + DT = &getAnalysis(); // 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(); -- cgit v1.1 From 10c6d12a9fd4dab411091f64db4db69670b88850 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Sat, 30 Jul 2011 05:42:50 +0000 Subject: Revert r136253, r136263, r136269, r136313, r136325, r136326, r136329, r136338, r136339, r136341, r136369, r136387, r136392, r136396, r136429, r136430, r136444, r136445, r136446, r136253 pending review. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@136556 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/DwarfEHPrepare.cpp | 58 +----------------------------------------- 1 file changed, 1 insertion(+), 57 deletions(-) (limited to 'lib/CodeGen/DwarfEHPrepare.cpp') diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 3aa72ee..03604b0 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -63,8 +63,6 @@ namespace { typedef SmallPtrSet BBSet; BBSet LandingPads; - bool InsertUnwindResumeCalls(); - bool NormalizeLandingPads(); bool LowerUnwindsAndResumes(); bool MoveExceptionValueCalls(); @@ -660,67 +658,13 @@ 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 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(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::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(); // FIXME: We won't need this with the new EH. + DT = &getAnalysis(); 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(); -- cgit v1.1 From 35adbb3e4829d3a14784c2bb8ec768b6154c2107 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Wed, 17 Aug 2011 19:48:49 +0000 Subject: 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 --- lib/CodeGen/DwarfEHPrepare.cpp | 58 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) (limited to 'lib/CodeGen/DwarfEHPrepare.cpp') diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 03604b0..3aa72ee 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -63,6 +63,8 @@ namespace { typedef SmallPtrSet 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 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(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::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(); + DT = &getAnalysis(); // 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(); -- cgit v1.1 From 09908c4b4a0b25eab4cb496d95d9dcc93f2214f2 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 25 Aug 2011 23:48:11 +0000 Subject: Look at only the terminators of the basic block. Also, if we're using the new EH scheme, return 'true' so that it doesn't try to run the old EH scheme's fixup on the new code. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138605 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/DwarfEHPrepare.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) (limited to 'lib/CodeGen/DwarfEHPrepare.cpp') diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index 3aa72ee..d2b129a 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -663,14 +663,18 @@ Instruction *DwarfEHPrepare::CreateExceptionValueCall(BasicBlock *BB) { /// InsertUnwindResumeCalls - Convert the ResumeInsts that are still present /// into calls to the appropriate _Unwind_Resume function. bool DwarfEHPrepare::InsertUnwindResumeCalls() { + bool UsesNewEH = false; SmallVector 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(II)) - Resumes.push_back(RI); + for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I) { + TerminatorInst *TI = I->getTerminator(); + if (ResumeInst *RI = dyn_cast(TI)) + Resumes.push_back(RI); + else if (InvokeInst *II = dyn_cast(TI)) + UsesNewEH = II->getUnwindDest()->isLandingPad(); + } if (Resumes.empty()) - return false; + return UsesNewEH; // Find the rewind function if we didn't already. if (!RewindFunction) { -- cgit v1.1 From e8ef4cc053257c8cc330d4995aa775785e7f3f04 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Fri, 26 Aug 2011 21:36:12 +0000 Subject: Update the dominator tree with the correct dominator for the new 'unwind' block. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@138664 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/DwarfEHPrepare.cpp | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'lib/CodeGen/DwarfEHPrepare.cpp') diff --git a/lib/CodeGen/DwarfEHPrepare.cpp b/lib/CodeGen/DwarfEHPrepare.cpp index d2b129a..ed9e409 100644 --- a/lib/CodeGen/DwarfEHPrepare.cpp +++ b/lib/CodeGen/DwarfEHPrepare.cpp @@ -693,6 +693,7 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { // Extract the exception object from the ResumeInst and add it to the PHI node // that feeds the _Unwind_Resume call. + BasicBlock *UnwindBBDom = Resumes[0]->getParent(); for (SmallVectorImpl::iterator I = Resumes.begin(), E = Resumes.end(); I != E; ++I) { ResumeInst *RI = *I; @@ -700,6 +701,7 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { ExtractValueInst *ExnObj = ExtractValueInst::Create(RI->getOperand(0), 0, "exn.obj", RI); PN->addIncoming(ExnObj, RI->getParent()); + UnwindBBDom = DT->findNearestCommonDominator(RI->getParent(), UnwindBBDom); RI->eraseFromParent(); } @@ -709,6 +711,9 @@ bool DwarfEHPrepare::InsertUnwindResumeCalls() { // We never expect _Unwind_Resume to return. new UnreachableInst(Ctx, UnwindBB); + + // Now update DominatorTree analysis information. + DT->addNewBlock(UnwindBB, UnwindBBDom); return true; } -- cgit v1.1