diff options
author | Chris Lattner <sabre@nondot.org> | 2004-02-08 07:30:29 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-02-08 07:30:29 +0000 |
commit | 476488e669790e2c4a47484c36f9a0681f71361c (patch) | |
tree | 3f8f993984ed6182a0421e8d7e6cf565040cc069 /llvm/lib | |
parent | d97d8faa179cad4d9ef970ab0f6233fc9a2eef8d (diff) | |
download | bcm5719-llvm-476488e669790e2c4a47484c36f9a0681f71361c.tar.gz bcm5719-llvm-476488e669790e2c4a47484c36f9a0681f71361c.zip |
Add a call to 'write' right before the call to abort() in the unwind path.
This causes the JIT, or LLC'd program to print out a nice message, explaining
WHY the program aborted.
llvm-svn: 11184
Diffstat (limited to 'llvm/lib')
-rw-r--r-- | llvm/lib/Transforms/Scalar/LowerInvoke.cpp | 30 |
1 files changed, 27 insertions, 3 deletions
diff --git a/llvm/lib/Transforms/Scalar/LowerInvoke.cpp b/llvm/lib/Transforms/Scalar/LowerInvoke.cpp index 3686fc01f6e..df1c0e4fa66 100644 --- a/llvm/lib/Transforms/Scalar/LowerInvoke.cpp +++ b/llvm/lib/Transforms/Scalar/LowerInvoke.cpp @@ -15,12 +15,12 @@ //===----------------------------------------------------------------------===// #include "llvm/Transforms/Scalar.h" +#include "llvm/Constants.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Module.h" #include "llvm/Pass.h" #include "llvm/iTerminators.h" #include "llvm/iOther.h" -#include "llvm/Module.h" -#include "llvm/Type.h" -#include "llvm/Constant.h" #include "Support/Statistic.h" using namespace llvm; @@ -28,6 +28,9 @@ namespace { Statistic<> NumLowered("lowerinvoke", "Number of invoke & unwinds replaced"); class LowerInvoke : public FunctionPass { + Value *AbortMessage; + unsigned AbortMessageLength; + Function *WriteFn; Function *AbortFn; public: bool doInitialization(Module &M); @@ -44,7 +47,21 @@ FunctionPass *llvm::createLowerInvokePass() { return new LowerInvoke(); } // doInitialization - Make sure that there is a prototype for abort in the // current module. bool LowerInvoke::doInitialization(Module &M) { + Constant *Msg = + ConstantArray::get("Exception handler needed, but not available.\n"); + AbortMessageLength = Msg->getNumOperands()-1; // don't include \0 + + GlobalVariable *MsgGV = + new GlobalVariable(Msg->getType(), true, GlobalValue::InternalLinkage, Msg, + "", &M); + std::vector<Constant*> GEPIdx(2, Constant::getNullValue(Type::LongTy)); + AbortMessage = + ConstantExpr::getGetElementPtr(ConstantPointerRef::get(MsgGV), GEPIdx); + AbortFn = M.getOrInsertFunction("abort", Type::VoidTy, 0); + WriteFn = M.getOrInsertFunction("write", Type::VoidTy, Type::IntTy, + PointerType::get(Type::SByteTy), Type::IntTy, + 0); return true; } @@ -70,6 +87,13 @@ bool LowerInvoke::runOnFunction(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); + // Insert a call to abort() new CallInst(AbortFn, std::vector<Value*>(), "", UI); |