Lazily create the abort message, so only translation units that use unwind
authorChris Lattner <sabre@nondot.org>
Sat, 13 Nov 2004 19:07:32 +0000 (19:07 +0000)
committerChris Lattner <sabre@nondot.org>
Sat, 13 Nov 2004 19:07:32 +0000 (19:07 +0000)
will actually get it.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17700 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Utils/LowerInvoke.cpp

index 33ed896a1e7e43eb7aa18a9b7a99a63f05610efb..97c2327c8ca6fa4a5a96ed8baf435a125caa650b 100644 (file)
@@ -66,6 +66,7 @@ namespace {
     bool doInitialization(Module &M);
     bool runOnFunction(Function &F);
   private:
+    void createAbortMessage();
     void writeAbortMessage(Instruction *IB);
     bool insertCheapEHSupport(Function &F);
     bool insertExpensiveEHSupport(Function &F);
@@ -119,7 +120,34 @@ bool LowerInvoke::doInitialization(Module &M) {
     LongJmpFn = M.getOrInsertFunction("llvm.longjmp", Type::VoidTy,
                                       PointerType::get(JmpBufTy),
                                       Type::IntTy, 0);
+  }
+
+  // We need the 'write' and 'abort' functions for both models.
+  AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, 0);
 
+  // Unfortunately, 'write' can end up being prototyped in several different
+  // ways.  If the user defines a three (or more) operand function named 'write'
+  // we will use their prototype.  We _do not_ want to insert another instance
+  // of a write prototype, because we don't know that the funcresolve pass will
+  // run after us.  If there is a definition of a write function, but it's not
+  // suitable for our uses, we just don't emit write calls.  If there is no
+  // write prototype at all, we just add one.
+  if (Function *WF = M.getNamedFunction("write")) {
+    if (WF->getFunctionType()->getNumParams() > 3 ||
+        WF->getFunctionType()->isVarArg())
+      WriteFn = WF;
+    else
+      WriteFn = 0;
+  } else {
+    WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy,
+                                    VoidPtrTy, Type::IntTy, 0);
+  }
+  return true;
+}
+
+void LowerInvoke::createAbortMessage() {
+  Module &M = *WriteFn->getParent();
+  if (ExpensiveEHSupport) {
     // The abort message for expensive EH support tells the user that the
     // program 'unwound' without an 'invoke' instruction.
     Constant *Msg =
@@ -145,32 +173,13 @@ bool LowerInvoke::doInitialization(Module &M) {
     std::vector<Constant*> GEPIdx(2, Constant::getNullValue(Type::LongTy));
     AbortMessage = ConstantExpr::getGetElementPtr(MsgGV, GEPIdx);
   }
-
-  // We need the 'write' and 'abort' functions for both models.
-  AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, 0);
-
-  // Unfortunately, 'write' can end up being prototyped in several different
-  // ways.  If the user defines a three (or more) operand function named 'write'
-  // we will use their prototype.  We _do not_ want to insert another instance
-  // of a write prototype, because we don't know that the funcresolve pass will
-  // run after us.  If there is a definition of a write function, but it's not
-  // suitable for our uses, we just don't emit write calls.  If there is no
-  // write prototype at all, we just add one.
-  if (Function *WF = M.getNamedFunction("write")) {
-    if (WF->getFunctionType()->getNumParams() > 3 ||
-        WF->getFunctionType()->isVarArg())
-      WriteFn = WF;
-    else
-      WriteFn = 0;
-  } else {
-    WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy,
-                                    VoidPtrTy, Type::IntTy, 0);
-  }
-  return true;
 }
 
+
 void LowerInvoke::writeAbortMessage(Instruction *IB) {
   if (WriteFn) {
+    if (AbortMessage == 0) createAbortMessage();
+
     // These are the arguments we WANT...
     std::vector<Value*> Args;
     Args.push_back(ConstantInt::get(Type::IntTy, 2));