summaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/LowerInvoke.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-11-13 19:07:32 +0000
committerChris Lattner <sabre@nondot.org>2004-11-13 19:07:32 +0000
commit0c3b390a547188e3db01b963918af0a57548cd04 (patch)
tree55fe5df4396d4ddbf40688a37f98f2a5c0db32fe /lib/Transforms/Utils/LowerInvoke.cpp
parent9ecc0461841ad2fb44996a965f30ab3931efbf70 (diff)
downloadllvm-0c3b390a547188e3db01b963918af0a57548cd04.tar.gz
llvm-0c3b390a547188e3db01b963918af0a57548cd04.tar.bz2
llvm-0c3b390a547188e3db01b963918af0a57548cd04.tar.xz
Lazily create the abort message, so only translation units that use unwind
will actually get it. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@17700 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/LowerInvoke.cpp')
-rw-r--r--lib/Transforms/Utils/LowerInvoke.cpp53
1 files changed, 31 insertions, 22 deletions
diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp
index 33ed896a1e..97c2327c8c 100644
--- a/lib/Transforms/Utils/LowerInvoke.cpp
+++ b/lib/Transforms/Utils/LowerInvoke.cpp
@@ -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));