summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2003-09-08 19:44:26 +0000
committerChris Lattner <sabre@nondot.org>2003-09-08 19:44:26 +0000
commitee5457cbe88b7f691f774de8515d9a94226d1b00 (patch)
treeac7e19c81aba3447b8446f1b4d29c5f5e6db01b8 /lib
parentda73beac201091653d9e2b900d2207c31ed97a0e (diff)
downloadllvm-ee5457cbe88b7f691f774de8515d9a94226d1b00.tar.gz
llvm-ee5457cbe88b7f691f774de8515d9a94226d1b00.tar.bz2
llvm-ee5457cbe88b7f691f774de8515d9a94226d1b00.tar.xz
Eliminate support for the llvm.unwind intrinisic, using the Unwind instruction instead
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8411 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r--lib/Target/CBackend/CBackend.cpp13
-rw-r--r--lib/Target/CBackend/Writer.cpp13
-rw-r--r--lib/Target/X86/InstSelectSimple.cpp1
-rw-r--r--lib/Target/X86/X86ISelSimple.cpp1
-rw-r--r--lib/Transforms/IPO/PruneEH.cpp11
-rw-r--r--lib/Transforms/Utils/InlineFunction.cpp41
-rw-r--r--lib/Transforms/Utils/SimplifyCFG.cpp49
-rw-r--r--lib/VMCore/Function.cpp3
-rw-r--r--lib/VMCore/Verifier.cpp2
9 files changed, 44 insertions, 90 deletions
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 073ce19189..0a9c8d1d01 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -1153,19 +1153,6 @@ void CWriter::visitCallInst(CallInst &I) {
Out << ")";
return;
- case LLVMIntrinsic::unwind:
- // The unwind intrinsic calls a control flow transfer out of the current
- // function, unwinding the stack until a caller who used the invoke
- // instruction is found. In this context, we code generated the invoke
- // instruction to add an entry to the top of the jmpbuf_list. Thus,
- // here we just have to longjmp to the specified handler.
- Out << "if (__llvm_jmpbuf_list == 0) { /* llvm.unwind */\n"
- << " printf(\"throw found with no handler!\\n\"); abort();\n"
- << " }\n"
- << " longjmp(__llvm_jmpbuf_list->buf, 1)";
- return;
-
-
case LLVMIntrinsic::setjmp:
case LLVMIntrinsic::sigsetjmp:
// This instrinsic should never exist in the program, but until we get
diff --git a/lib/Target/CBackend/Writer.cpp b/lib/Target/CBackend/Writer.cpp
index 073ce19189..0a9c8d1d01 100644
--- a/lib/Target/CBackend/Writer.cpp
+++ b/lib/Target/CBackend/Writer.cpp
@@ -1153,19 +1153,6 @@ void CWriter::visitCallInst(CallInst &I) {
Out << ")";
return;
- case LLVMIntrinsic::unwind:
- // The unwind intrinsic calls a control flow transfer out of the current
- // function, unwinding the stack until a caller who used the invoke
- // instruction is found. In this context, we code generated the invoke
- // instruction to add an entry to the top of the jmpbuf_list. Thus,
- // here we just have to longjmp to the specified handler.
- Out << "if (__llvm_jmpbuf_list == 0) { /* llvm.unwind */\n"
- << " printf(\"throw found with no handler!\\n\"); abort();\n"
- << " }\n"
- << " longjmp(__llvm_jmpbuf_list->buf, 1)";
- return;
-
-
case LLVMIntrinsic::setjmp:
case LLVMIntrinsic::sigsetjmp:
// This instrinsic should never exist in the program, but until we get
diff --git a/lib/Target/X86/InstSelectSimple.cpp b/lib/Target/X86/InstSelectSimple.cpp
index 6712d94f32..85708ff2fd 100644
--- a/lib/Target/X86/InstSelectSimple.cpp
+++ b/lib/Target/X86/InstSelectSimple.cpp
@@ -1044,7 +1044,6 @@ void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) {
addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1);
return;
- case LLVMIntrinsic::unwind: // llvm.unwind is not supported yet!
case LLVMIntrinsic::longjmp:
case LLVMIntrinsic::siglongjmp:
BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true);
diff --git a/lib/Target/X86/X86ISelSimple.cpp b/lib/Target/X86/X86ISelSimple.cpp
index 6712d94f32..85708ff2fd 100644
--- a/lib/Target/X86/X86ISelSimple.cpp
+++ b/lib/Target/X86/X86ISelSimple.cpp
@@ -1044,7 +1044,6 @@ void ISel::visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &CI) {
addDirectMem(BuildMI(BB, X86::MOVrm32, 5), TmpReg2).addReg(TmpReg1);
return;
- case LLVMIntrinsic::unwind: // llvm.unwind is not supported yet!
case LLVMIntrinsic::longjmp:
case LLVMIntrinsic::siglongjmp:
BuildMI(BB, X86::CALLpcrel32, 1).addExternalSymbol("abort", true);
diff --git a/lib/Transforms/IPO/PruneEH.cpp b/lib/Transforms/IPO/PruneEH.cpp
index 41f7f73845..8be8761b85 100644
--- a/lib/Transforms/IPO/PruneEH.cpp
+++ b/lib/Transforms/IPO/PruneEH.cpp
@@ -38,7 +38,7 @@ bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
// First, check to see if any callees might throw or if there are any external
// functions in this SCC: if so, we cannot prune any functions in this SCC.
- // If this SCC includes the llvm.unwind intrinsic, we KNOW it throws, so
+ // If this SCC includes the unwind instruction, we KNOW it throws, so
// obviously the SCC might throw.
//
bool SCCMightThrow = false;
@@ -48,10 +48,11 @@ bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
std::find(SCC.begin(), SCC.end(), SCC[i]) == SCC.end()) {
SCCMightThrow = true; break;
} else if (Function *F = SCC[i]->getFunction())
- if (F->isExternal() || // Is external function
- F->getIntrinsicID() == LLVMIntrinsic::unwind) {// Is unwind function!
- SCCMightThrow = true; break;
- }
+ if (!F->isExternal())
+ for (Function::iterator I = F->begin(), E = F->end(); I != E; ++I)
+ if (isa<UnwindInst>(I->getTerminator())) { // Uses unwind!
+ SCCMightThrow = true; break;
+ }
bool MadeChange = false;
diff --git a/lib/Transforms/Utils/InlineFunction.cpp b/lib/Transforms/Utils/InlineFunction.cpp
index 864b6ba3db..17628e2253 100644
--- a/lib/Transforms/Utils/InlineFunction.cpp
+++ b/lib/Transforms/Utils/InlineFunction.cpp
@@ -177,38 +177,13 @@ bool InlineFunction(CallSite CS) {
// If we just inlined a call due to an invoke instruction, scan the inlined
// function checking for function calls that should now be made into invoke
- // instructions, and for llvm.exc.rethrow()'s which should be turned into
- // branches.
+ // instructions, and for unwind's which should be turned into branches.
if (InvokeDest)
- for (Function::iterator BB = LastBlock, E = Caller->end(); BB != E; ++BB)
+ for (Function::iterator BB = LastBlock, E = Caller->end(); BB != E; ++BB) {
for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ) {
// We only need to check for function calls: inlined invoke instructions
// require no special handling...
if (CallInst *CI = dyn_cast<CallInst>(I)) {
- if (Function *F = CI->getCalledFunction())
- if (unsigned ID = F->getIntrinsicID())
- if (ID == LLVMIntrinsic::unwind) {
- // llvm.unwind requires special handling when it gets inlined
- // into an invoke site. Once this happens, we know that the
- // unwind would cause a control transfer to the invoke exception
- // destination, so we can transform it into a direct branch to
- // the exception destination.
- BranchInst *BI = new BranchInst(InvokeDest, CI);
-
- // Note that since any instructions after the rethrow/branch are
- // dead, we must delete them now (otherwise the terminator we
- // just inserted wouldn't be at the end of the basic block!)
- BasicBlock *CurBB = BB;
- while (&CurBB->back() != BI) {
- Instruction *I = &CurBB->back();
- if (!I->use_empty())
- I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
- CurBB->getInstList().pop_back();
- }
-
- break; // Done with this basic block!
- }
-
// Convert this function call into an invoke instruction...
// First, split the basic block...
@@ -231,6 +206,18 @@ bool InlineFunction(CallSite CS) {
}
}
+ if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
+ // An UnwindInst requires special handling when it gets inlined into an
+ // invoke site. Once this happens, we know that the unwind would cause
+ // a control transfer to the invoke exception destination, so we can
+ // transform it into a direct branch to the exception destination.
+ BranchInst *BI = new BranchInst(InvokeDest, UI);
+
+ // Delete the unwind instruction!
+ UI->getParent()->getInstList().pop_back();
+ }
+ }
+
// Now that the function is correct, make it a little bit nicer. In
// particular, move the basic blocks inserted from the end of the function
// into the space made by splitting the source basic block.
diff --git a/lib/Transforms/Utils/SimplifyCFG.cpp b/lib/Transforms/Utils/SimplifyCFG.cpp
index f47c840518..1d5e4ec8af 100644
--- a/lib/Transforms/Utils/SimplifyCFG.cpp
+++ b/lib/Transforms/Utils/SimplifyCFG.cpp
@@ -101,32 +101,31 @@ bool SimplifyCFG(BasicBlock *BB) {
// 'llvm.unwind'. If so, replace any invoke instructions which use this as an
// exception destination with call instructions.
//
- if (CallInst *CI = dyn_cast<CallInst>(&BB->front()))
- if (Function *F = CI->getCalledFunction())
- if (F->getIntrinsicID() == LLVMIntrinsic::unwind) {
- std::vector<BasicBlock*> Preds(pred_begin(BB), pred_end(BB));
- while (!Preds.empty()) {
- BasicBlock *Pred = Preds.back();
- if (InvokeInst *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
- if (II->getExceptionalDest() == BB) {
- // Insert a new branch instruction before the invoke, because this
- // is now a fall through...
- BranchInst *BI = new BranchInst(II->getNormalDest(), II);
- Pred->getInstList().remove(II); // Take out of symbol table
-
- // Insert the call now...
- std::vector<Value*> Args(II->op_begin()+3, II->op_end());
- CallInst *CI = new CallInst(II->getCalledValue(), Args,
- II->getName(), BI);
- // If the invoke produced a value, the Call now does instead
- II->replaceAllUsesWith(CI);
- delete II;
- Changed = true;
- }
-
- Preds.pop_back();
- }
+ if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator()))
+ if (BB->begin() == BasicBlock::iterator(UI)) { // Empty block?
+ std::vector<BasicBlock*> Preds(pred_begin(BB), pred_end(BB));
+ while (!Preds.empty()) {
+ BasicBlock *Pred = Preds.back();
+ if (InvokeInst *II = dyn_cast<InvokeInst>(Pred->getTerminator()))
+ if (II->getExceptionalDest() == BB) {
+ // Insert a new branch instruction before the invoke, because this
+ // is now a fall through...
+ BranchInst *BI = new BranchInst(II->getNormalDest(), II);
+ Pred->getInstList().remove(II); // Take out of symbol table
+
+ // Insert the call now...
+ std::vector<Value*> Args(II->op_begin()+3, II->op_end());
+ CallInst *CI = new CallInst(II->getCalledValue(), Args,
+ II->getName(), BI);
+ // If the invoke produced a value, the Call now does instead
+ II->replaceAllUsesWith(CI);
+ delete II;
+ Changed = true;
+ }
+
+ Preds.pop_back();
}
+ }
// Remove basic blocks that have no predecessors... which are unreachable.
if (pred_begin(BB) == pred_end(BB) &&
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp
index ccbe4c2244..74098ffc45 100644
--- a/lib/VMCore/Function.cpp
+++ b/lib/VMCore/Function.cpp
@@ -203,9 +203,6 @@ unsigned Function::getIntrinsicID() const {
if (getName() == "llvm.sigsetjmp") return LLVMIntrinsic::sigsetjmp;
if (getName() == "llvm.siglongjmp") return LLVMIntrinsic::siglongjmp;
break;
- case 'u':
- if (getName() == "llvm.unwind") return LLVMIntrinsic::unwind;
- break;
case 'v':
if (getName() == "llvm.va_copy") return LLVMIntrinsic::va_copy;
if (getName() == "llvm.va_end") return LLVMIntrinsic::va_end;
diff --git a/lib/VMCore/Verifier.cpp b/lib/VMCore/Verifier.cpp
index 138542c06f..2e43d88b85 100644
--- a/lib/VMCore/Verifier.cpp
+++ b/lib/VMCore/Verifier.cpp
@@ -522,8 +522,6 @@ void Verifier::visitIntrinsicFunctionCall(LLVMIntrinsic::ID ID, CallInst &CI) {
case LLVMIntrinsic::va_end: NumArgs = 1; break;
case LLVMIntrinsic::va_copy: NumArgs = 2; break;
- case LLVMIntrinsic::unwind: NumArgs = 0; break;
-
case LLVMIntrinsic::setjmp: NumArgs = 1; break;
case LLVMIntrinsic::longjmp: NumArgs = 2; break;
case LLVMIntrinsic::sigsetjmp: NumArgs = 2; break;