aboutsummaryrefslogtreecommitdiff
path: root/lib/Transforms/Utils/LowerInvoke.cpp
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2004-02-08 22:14:44 +0000
committerChris Lattner <sabre@nondot.org>2004-02-08 22:14:44 +0000
commit501825e08a927a406cc328d09b3ff1bde44aefc0 (patch)
tree7cd61bb352431f13896757e6a3565b9bd0ce8966 /lib/Transforms/Utils/LowerInvoke.cpp
parenta306d3720a7a77141b2d4761a16be5ae7412a82d (diff)
Improve compatibility with programs that already have a prototype for 'write',
even if it is wierd in some way. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@11207 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/Utils/LowerInvoke.cpp')
-rw-r--r--lib/Transforms/Utils/LowerInvoke.cpp55
1 files changed, 43 insertions, 12 deletions
diff --git a/lib/Transforms/Utils/LowerInvoke.cpp b/lib/Transforms/Utils/LowerInvoke.cpp
index 83294653ef..1f278dbfb6 100644
--- a/lib/Transforms/Utils/LowerInvoke.cpp
+++ b/lib/Transforms/Utils/LowerInvoke.cpp
@@ -60,6 +60,7 @@ namespace {
bool doInitialization(Module &M);
bool runOnFunction(Function &F);
private:
+ void writeAbortMessage(Instruction *IB);
bool insertCheapEHSupport(Function &F);
bool insertExpensiveEHSupport(Function &F);
};
@@ -148,12 +149,49 @@ bool LowerInvoke::doInitialization(Module &M) {
}
// We need the 'write' and 'abort' functions for both models.
- WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy,
- VoidPtrTy, Type::IntTy, 0);
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 used 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) {
+ // These are the arguments we WANT...
+ std::vector<Value*> Args;
+ Args.push_back(ConstantInt::get(Type::IntTy, 2));
+ Args.push_back(AbortMessage);
+ Args.push_back(ConstantInt::get(Type::IntTy, AbortMessageLength));
+
+ // If the actual declaration of write disagrees, insert casts as
+ // appropriate.
+ const FunctionType *FT = WriteFn->getFunctionType();
+ unsigned NumArgs = FT->getNumParams();
+ for (unsigned i = 0; i != 3; ++i)
+ if (i < NumArgs && FT->getParamType(i) != Args[i]->getType())
+ Args[i] = ConstantExpr::getCast(cast<Constant>(Args[i]),
+ FT->getParamType(i));
+
+ new CallInst(WriteFn, Args, "", IB);
+ }
+}
+
bool LowerInvoke::insertCheapEHSupport(Function &F) {
bool Changed = false;
for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
@@ -177,11 +215,7 @@ bool LowerInvoke::insertCheapEHSupport(Function &F) {
++NumLowered; Changed = true;
} else if (UnwindInst *UI = dyn_cast<UnwindInst>(BB->getTerminator())) {
// Insert a new call to write(2, AbortMessage, AbortMessageLength);
- std::vector<Value*> Args;
- Args.push_back(ConstantInt::get(Type::IntTy, 2));
- Args.push_back(AbortMessage);
- Args.push_back(ConstantInt::get(Type::IntTy, AbortMessageLength));
- new CallInst(WriteFn, Args, "", UI);
+ writeAbortMessage(UI);
// Insert a call to abort()
new CallInst(AbortFn, std::vector<Value*>(), "", UI);
@@ -331,11 +365,8 @@ bool LowerInvoke::insertExpensiveEHSupport(Function &F) {
RI = TermBlock->getTerminator();
// Insert a new call to write(2, AbortMessage, AbortMessageLength);
- Idx[0] = ConstantInt::get(Type::IntTy, 2);
- Idx[1] = AbortMessage;
- Idx.push_back(ConstantInt::get(Type::IntTy, AbortMessageLength));
- new CallInst(WriteFn, Idx, "", RI);
-
+ writeAbortMessage(RI);
+
// Insert a call to abort()
new CallInst(AbortFn, std::vector<Value*>(), "", RI);
}