Eliminate support for the llvm.unwind intrinisic, using the Unwind instruction instead
authorChris Lattner <sabre@nondot.org>
Mon, 8 Sep 2003 19:44:26 +0000 (19:44 +0000)
committerChris Lattner <sabre@nondot.org>
Mon, 8 Sep 2003 19:44:26 +0000 (19:44 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@8411 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/CBackend/CBackend.cpp
lib/Target/CBackend/Writer.cpp
lib/Target/X86/InstSelectSimple.cpp
lib/Target/X86/X86ISelSimple.cpp
lib/Transforms/IPO/PruneEH.cpp
lib/Transforms/Utils/InlineFunction.cpp
lib/Transforms/Utils/SimplifyCFG.cpp
lib/VMCore/Function.cpp
lib/VMCore/Verifier.cpp

index 073ce19189f035d761e0a87ca6ef45913abcf98d..0a9c8d1d017edd1bd4a2ffb1db39a8ccbf9845b0 100644 (file)
@@ -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
index 073ce19189f035d761e0a87ca6ef45913abcf98d..0a9c8d1d017edd1bd4a2ffb1db39a8ccbf9845b0 100644 (file)
@@ -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
index 6712d94f32460b9bbbf14daea15f5ad6d73ad72b..85708ff2fd41c610b2137251725de05cfbbc0510 100644 (file)
@@ -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); 
index 6712d94f32460b9bbbf14daea15f5ad6d73ad72b..85708ff2fd41c610b2137251725de05cfbbc0510 100644 (file)
@@ -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); 
index 41f7f73845c30fd07b20b3e9fbe336a87e4c3c3f..8be8761b8532fd41590745ac5ae02f803bbd258e 100644 (file)
@@ -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;
 
index 864b6ba3db366034aac138be678926f633e204a5..17628e22537da6bef164f8c5d5c93d22a7286013 100644 (file)
@@ -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.
index f47c8405186324113b16be6a27cc1fb5dbc20b25..1d5e4ec8afb683ce4f1c20dc65a52c2873fd6b86 100644 (file)
@@ -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) &&
index ccbe4c224481854c72401ad508685fd82daf568b..74098ffc45ae1266e274a7bd2e5619b2980801d1 100644 (file)
@@ -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;
index 138542c06fb4d52b3e6b475fabe917253cdb193d..2e43d88b85fc33298ee841a5132ccdfbb9454abd 100644 (file)
@@ -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;