diff options
author | Chris Lattner <sabre@nondot.org> | 2004-11-13 19:07:32 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-11-13 19:07:32 +0000 |
commit | 0c3b390a547188e3db01b963918af0a57548cd04 (patch) | |
tree | 55fe5df4396d4ddbf40688a37f98f2a5c0db32fe /lib/Transforms/Utils/LowerInvoke.cpp | |
parent | 9ecc0461841ad2fb44996a965f30ab3931efbf70 (diff) |
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.cpp | 53 |
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)); |