Move more code back to 2.5 APIs.
[oota-llvm.git] / lib / Transforms / IPO / LowerSetJmp.cpp
index c040025115bdb5e0a9f5f09e2cd2faefade9e708..3a65ac7a8f596ab6a1c26b705f4b13c0412f89c0 100644 (file)
@@ -2,8 +2,8 @@
 //
 //                     The LLVM Compiler Infrastructure
 //
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
 //
 // pass invokable via the "opt" command at will.
 //===----------------------------------------------------------------------===//
 
+#define DEBUG_TYPE "lowersetjmp"
 #include "llvm/Transforms/IPO.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Instructions.h"
 #include "llvm/Intrinsics.h"
+#include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Pass.h"
 #include "llvm/Support/CFG.h"
+#include "llvm/Support/Compiler.h"
 #include "llvm/Support/InstVisitor.h"
 #include "llvm/Transforms/Utils/Local.h"
 #include "llvm/ADT/DepthFirstIterator.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/VectorExtras.h"
+#include "llvm/ADT/SmallVector.h"
+#include <map>
 using namespace llvm;
 
-namespace {
-  Statistic<> LongJmpsTransformed("lowersetjmp",
-                                  "Number of longjmps transformed");
-  Statistic<> SetJmpsTransformed("lowersetjmp",
-                                 "Number of setjmps transformed");
-  Statistic<> CallsTransformed("lowersetjmp",
-                               "Number of calls invokified");
-  Statistic<> InvokesTransformed("lowersetjmp",
-                                 "Number of invokes modified");
+STATISTIC(LongJmpsTransformed, "Number of longjmps transformed");
+STATISTIC(SetJmpsTransformed , "Number of setjmps transformed");
+STATISTIC(CallsTransformed   , "Number of calls invokified");
+STATISTIC(InvokesTransformed , "Number of invokes modified");
 
+namespace {
   //===--------------------------------------------------------------------===//
   // LowerSetJmp pass implementation.
-  class LowerSetJmp : public ModulePass,
+  class VISIBILITY_HIDDEN LowerSetJmp : public ModulePass,
                       public InstVisitor<LowerSetJmp> {
     // LLVM library functions...
-    Function* InitSJMap;        // __llvm_sjljeh_init_setjmpmap
-    Function* DestroySJMap;     // __llvm_sjljeh_destroy_setjmpmap
-    Function* AddSJToMap;       // __llvm_sjljeh_add_setjmp_to_map
-    Function* ThrowLongJmp;     // __llvm_sjljeh_throw_longjmp
-    Function* TryCatchLJ;       // __llvm_sjljeh_try_catching_longjmp_exception
-    Function* IsLJException;    // __llvm_sjljeh_is_longjmp_exception
-    Function* GetLJValue;       // __llvm_sjljeh_get_longjmp_value
+    Constant *InitSJMap;        // __llvm_sjljeh_init_setjmpmap
+    Constant *DestroySJMap;     // __llvm_sjljeh_destroy_setjmpmap
+    Constant *AddSJToMap;       // __llvm_sjljeh_add_setjmp_to_map
+    Constant *ThrowLongJmp;     // __llvm_sjljeh_throw_longjmp
+    Constant *TryCatchLJ;       // __llvm_sjljeh_try_catching_longjmp_exception
+    Constant *IsLJException;    // __llvm_sjljeh_is_longjmp_exception
+    Constant *GetLJValue;       // __llvm_sjljeh_get_longjmp_value
 
     typedef std::pair<SwitchInst*, CallInst*> SwitchValuePair;
 
@@ -111,6 +112,9 @@ namespace {
 
     bool IsTransformableFunction(const std::string& Name);
   public:
+    static char ID; // Pass identification, replacement for typeid
+    LowerSetJmp() : ModulePass(&ID) {}
+
     void visitCallInst(CallInst& CI);
     void visitInvokeInst(InvokeInst& II);
     void visitReturnInst(ReturnInst& RI);
@@ -119,10 +123,11 @@ namespace {
     bool runOnModule(Module& M);
     bool doInitialization(Module& M);
   };
-
-  RegisterOpt<LowerSetJmp> X("lowersetjmp", "Lower Set Jump");
 } // end anonymous namespace
 
+char LowerSetJmp::ID = 0;
+static RegisterPass<LowerSetJmp> X("lowersetjmp", "Lower Set Jump");
+
 // run - Run the transformation on the program. We grab the function
 // prototypes for longjmp and setjmp. If they are used in the program,
 // then we can go directly to the places they're at and transform them.
@@ -130,8 +135,8 @@ bool LowerSetJmp::runOnModule(Module& M) {
   bool Changed = false;
 
   // These are what the functions are called.
-  Function* SetJmp = M.getNamedFunction("llvm.setjmp");
-  Function* LongJmp = M.getNamedFunction("llvm.longjmp");
+  Function* SetJmp = M.getFunction("llvm.setjmp");
+  Function* LongJmp = M.getFunction("llvm.longjmp");
 
   // This program doesn't have longjmp and setjmp calls.
   if ((!LongJmp || LongJmp->use_empty()) &&
@@ -196,40 +201,41 @@ bool LowerSetJmp::runOnModule(Module& M) {
 // This function is always successful, unless it isn't.
 bool LowerSetJmp::doInitialization(Module& M)
 {
-  const Type *SBPTy = PointerType::get(Type::SByteTy);
-  const Type *SBPPTy = PointerType::get(SBPTy);
+  const Type *SBPTy = PointerType::getUnqual(Type::Int8Ty);
+  const Type *SBPPTy = PointerType::getUnqual(SBPTy);
 
   // N.B. See llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h for
   // a description of the following library functions.
 
   // void __llvm_sjljeh_init_setjmpmap(void**)
   InitSJMap = M.getOrInsertFunction("__llvm_sjljeh_init_setjmpmap",
-                                    Type::VoidTy, SBPPTy, NULL);
+                                    Type::VoidTy, SBPPTy, (Type *)0);
   // void __llvm_sjljeh_destroy_setjmpmap(void**)
   DestroySJMap = M.getOrInsertFunction("__llvm_sjljeh_destroy_setjmpmap",
-                                       Type::VoidTy, SBPPTy, NULL);
+                                       Type::VoidTy, SBPPTy, (Type *)0);
 
   // void __llvm_sjljeh_add_setjmp_to_map(void**, void*, unsigned)
   AddSJToMap = M.getOrInsertFunction("__llvm_sjljeh_add_setjmp_to_map",
                                      Type::VoidTy, SBPPTy, SBPTy,
-                                     Type::UIntTy, NULL);
+                                     Type::Int32Ty, (Type *)0);
 
   // void __llvm_sjljeh_throw_longjmp(int*, int)
   ThrowLongJmp = M.getOrInsertFunction("__llvm_sjljeh_throw_longjmp",
-                                       Type::VoidTy, SBPTy, Type::IntTy, NULL);
+                                       Type::VoidTy, SBPTy, Type::Int32Ty,
+                                       (Type *)0);
 
   // unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **)
   TryCatchLJ =
     M.getOrInsertFunction("__llvm_sjljeh_try_catching_longjmp_exception",
-                          Type::UIntTy, SBPPTy, NULL);
+                          Type::Int32Ty, SBPPTy, (Type *)0);
 
   // bool __llvm_sjljeh_is_longjmp_exception()
   IsLJException = M.getOrInsertFunction("__llvm_sjljeh_is_longjmp_exception",
-                                        Type::BoolTy, NULL);
+                                        Type::Int1Ty, (Type *)0);
 
   // int __llvm_sjljeh_get_longjmp_value()
   GetLJValue = M.getOrInsertFunction("__llvm_sjljeh_get_longjmp_value",
-                                     Type::IntTy, NULL);
+                                     Type::Int32Ty, (Type *)0);
   return true;
 }
 
@@ -252,15 +258,18 @@ bool LowerSetJmp::IsTransformableFunction(const std::string& Name) {
 // throwing the exception for us.
 void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
 {
-  const Type* SBPTy = PointerType::get(Type::SByteTy);
+  const Type* SBPTy = PointerType::getUnqual(Type::Int8Ty);
 
   // Create the call to "__llvm_sjljeh_throw_longjmp". This takes the
   // same parameters as "longjmp", except that the buffer is cast to a
   // char*. It returns "void", so it doesn't need to replace any of
   // Inst's uses and doesn't get a name.
-  CastInst* CI = new CastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst);
-  new CallInst(ThrowLongJmp, make_vector<Value*>(CI, Inst->getOperand(2), 0),
-               "", Inst);
+  CastInst* CI = 
+    new BitCastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst);
+  SmallVector<Value *, 2> Args;
+  Args.push_back(CI);
+  Args.push_back(Inst->getOperand(2));
+  CallInst::Create(ThrowLongJmp, Args.begin(), Args.end(), "", Inst);
 
   SwitchValuePair& SVP = SwitchValMap[Inst->getParent()->getParent()];
 
@@ -268,7 +277,7 @@ void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
   // we should branch to the basic block that determines if this longjmp
   // is applicable here. Otherwise, issue an unwind.
   if (SVP.first)
-    new BranchInst(SVP.first->getParent(), Inst);
+    BranchInst::Create(SVP.first->getParent(), Inst);
   else
     new UnwindInst(Inst);
 
@@ -301,9 +310,9 @@ AllocaInst* LowerSetJmp::GetSetJmpMap(Function* Func)
   assert(Inst && "Couldn't find even ONE instruction in entry block!");
 
   // Fill in the alloca and call to initialize the SJ map.
-  const Type *SBPTy = PointerType::get(Type::SByteTy);
+  const Type *SBPTy = PointerType::getUnqual(Type::Int8Ty);
   AllocaInst* Map = new AllocaInst(SBPTy, 0, "SJMap", Inst);
-  new CallInst(InitSJMap, make_vector<Value*>(Map, 0), "", Inst);
+  CallInst::Create(InitSJMap, Map, "", Inst);
   return SJMap[Func] = Map;
 }
 
@@ -316,7 +325,7 @@ BasicBlock* LowerSetJmp::GetRethrowBB(Function* Func)
 
   // The basic block we're going to jump to if we need to rethrow the
   // exception.
-  BasicBlock* Rethrow = new BasicBlock("RethrowExcept", Func);
+  BasicBlock* Rethrow = BasicBlock::Create("RethrowExcept", Func);
 
   // Fill in the "Rethrow" BB with a call to rethrow the exception. This
   // is the last instruction in the BB since at this point the runtime
@@ -332,34 +341,28 @@ LowerSetJmp::SwitchValuePair LowerSetJmp::GetSJSwitch(Function* Func,
 {
   if (SwitchValMap[Func].first) return SwitchValMap[Func];
 
-  BasicBlock* LongJmpPre = new BasicBlock("LongJmpBlkPre", Func);
-  BasicBlock::InstListType& LongJmpPreIL = LongJmpPre->getInstList();
+  BasicBlock* LongJmpPre = BasicBlock::Create("LongJmpBlkPre", Func);
 
   // Keep track of the preliminary basic block for some of the other
   // transformations.
   PrelimBBMap[Func] = LongJmpPre;
 
   // Grab the exception.
-  CallInst* Cond = new
-    CallInst(IsLJException, std::vector<Value*>(), "IsLJExcept");
-  LongJmpPreIL.push_back(Cond);
+  CallInst* Cond = CallInst::Create(IsLJException, "IsLJExcept", LongJmpPre);
 
   // The "decision basic block" gets the number associated with the
   // setjmp call returning to switch on and the value returned by
   // longjmp.
-  BasicBlock* DecisionBB = new BasicBlock("LJDecisionBB", Func);
-  BasicBlock::InstListType& DecisionBBIL = DecisionBB->getInstList();
+  BasicBlock* DecisionBB = BasicBlock::Create("LJDecisionBB", Func);
 
-  new BranchInst(DecisionBB, Rethrow, Cond, LongJmpPre);
+  BranchInst::Create(DecisionBB, Rethrow, Cond, LongJmpPre);
 
   // Fill in the "decision" basic block.
-  CallInst* LJVal = new CallInst(GetLJValue, std::vector<Value*>(), "LJVal");
-  DecisionBBIL.push_back(LJVal);
-  CallInst* SJNum = new
-    CallInst(TryCatchLJ, make_vector<Value*>(GetSetJmpMap(Func), 0), "SJNum");
-  DecisionBBIL.push_back(SJNum);
+  CallInst* LJVal = CallInst::Create(GetLJValue, "LJVal", DecisionBB);
+  CallInst* SJNum = CallInst::Create(TryCatchLJ, GetSetJmpMap(Func), "SJNum",
+                                     DecisionBB);
 
-  SwitchInst* SI = new SwitchInst(SJNum, Rethrow, 0, DecisionBB);
+  SwitchInst* SI = SwitchInst::Create(SJNum, Rethrow, 0, DecisionBB);
   return SwitchValMap[Func] = SwitchValuePair(SI, LJVal);
 }
 
@@ -373,13 +376,13 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
   Function* Func = ABlock->getParent();
 
   // Add this setjmp to the setjmp map.
-  const Type* SBPTy = PointerType::get(Type::SByteTy);
-  CastInst* BufPtr = new CastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst);
-  new CallInst(AddSJToMap,
-               make_vector<Value*>(GetSetJmpMap(Func), BufPtr,
-                                   ConstantUInt::get(Type::UIntTy,
-                                                     SetJmpIDMap[Func]++), 0),
-               "", Inst);
+  const Type* SBPTy = PointerType::getUnqual(Type::Int8Ty);
+  CastInst* BufPtr = 
+    new BitCastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst);
+  std::vector<Value*> Args = 
+    make_vector<Value*>(GetSetJmpMap(Func), BufPtr,
+                        ConstantInt::get(Type::Int32Ty,SetJmpIDMap[Func]++), 0);
+  CallInst::Create(AddSJToMap, Args.begin(), Args.end(), "", Inst);
 
   // We are guaranteed that there are no values live across basic blocks
   // (because we are "not in SSA form" yet), but there can still be values live
@@ -421,14 +424,14 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
 
   // This PHI node will be in the new block created from the
   // splitBasicBlock call.
-  PHINode* PHI = new PHINode(Type::IntTy, "SetJmpReturn", Inst);
+  PHINode* PHI = PHINode::Create(Type::Int32Ty, "SetJmpReturn", Inst);
 
   // Coming from a call to setjmp, the return is 0.
-  PHI->addIncoming(ConstantInt::getNullValue(Type::IntTy), ABlock);
+  PHI->addIncoming(Inst->getContext().getNullValue(Type::Int32Ty), ABlock);
 
   // Add the case for this setjmp's number...
   SwitchValuePair SVP = GetSJSwitch(Func, GetRethrowBB(Func));
-  SVP.first->addCase(ConstantUInt::get(Type::UIntTy, SetJmpIDMap[Func] - 1),
+  SVP.first->addCase(ConstantInt::get(Type::Int32Ty, SetJmpIDMap[Func] - 1),
                      SetJmpContBlock);
 
   // Value coming from the handling of the exception.
@@ -437,7 +440,7 @@ void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
   // Replace all uses of this instruction with the PHI node created by
   // the eradication of setjmp.
   Inst->replaceAllUsesWith(PHI);
-  Inst->getParent()->getInstList().erase(Inst);
+  Inst->eraseFromParent();
 
   ++SetJmpsTransformed;
 }
@@ -467,16 +470,18 @@ void LowerSetJmp::visitCallInst(CallInst& CI)
   // Construct the new "invoke" instruction.
   TerminatorInst* Term = OldBB->getTerminator();
   std::vector<Value*> Params(CI.op_begin() + 1, CI.op_end());
-  InvokeInst* II = new
-    InvokeInst(CI.getCalledValue(), NewBB, PrelimBBMap[Func],
-               Params, CI.getName(), Term);
+  InvokeInst* II =
+    InvokeInst::Create(CI.getCalledValue(), NewBB, PrelimBBMap[Func],
+                       Params.begin(), Params.end(), CI.getName(), Term);
+  II->setCallingConv(CI.getCallingConv());
+  II->setAttributes(CI.getAttributes());
 
   // Replace the old call inst with the invoke inst and remove the call.
   CI.replaceAllUsesWith(II);
-  CI.getParent()->getInstList().erase(&CI);
+  CI.eraseFromParent();
 
   // The old terminator is useless now that we have the invoke inst.
-  Term->getParent()->getInstList().erase(Term);
+  Term->eraseFromParent();
   ++CallsTransformed;
 }
 
@@ -495,20 +500,17 @@ void LowerSetJmp::visitInvokeInst(InvokeInst& II)
   // If not reachable from a setjmp call, don't transform.
   if (!DFSBlocks.count(BB)) return;
 
-  BasicBlock* NormalBB = II.getNormalDest();
   BasicBlock* ExceptBB = II.getUnwindDest();
 
   Function* Func = BB->getParent();
-  BasicBlock* NewExceptBB = new BasicBlock("InvokeExcept", Func);
-  BasicBlock::InstListType& InstList = NewExceptBB->getInstList();
+  BasicBlock* NewExceptBB = BasicBlock::Create("InvokeExcept", Func);
 
   // If this is a longjmp exception, then branch to the preliminary BB of
   // the longjmp exception handling. Otherwise, go to the old exception.
-  CallInst* IsLJExcept = new
-    CallInst(IsLJException, std::vector<Value*>(), "IsLJExcept");
-  InstList.push_back(IsLJExcept);
+  CallInst* IsLJExcept = CallInst::Create(IsLJException, "IsLJExcept",
+                                          NewExceptBB);
 
-  new BranchInst(PrelimBBMap[Func], ExceptBB, IsLJExcept, NewExceptBB);
+  BranchInst::Create(PrelimBBMap[Func], ExceptBB, IsLJExcept, NewExceptBB);
 
   II.setUnwindDest(NewExceptBB);
   ++InvokesTransformed;
@@ -518,16 +520,14 @@ void LowerSetJmp::visitInvokeInst(InvokeInst& II)
 // function.
 void LowerSetJmp::visitReturnInst(ReturnInst &RI) {
   Function* Func = RI.getParent()->getParent();
-  new CallInst(DestroySJMap, make_vector<Value*>(GetSetJmpMap(Func), 0),
-               "", &RI);
+  CallInst::Create(DestroySJMap, GetSetJmpMap(Func), "", &RI);
 }
 
 // visitUnwindInst - We want to destroy the setjmp map upon exit from the
 // function.
 void LowerSetJmp::visitUnwindInst(UnwindInst &UI) {
   Function* Func = UI.getParent()->getParent();
-  new CallInst(DestroySJMap, make_vector<Value*>(GetSetJmpMap(Func), 0),
-               "", &UI);
+  CallInst::Create(DestroySJMap, GetSetJmpMap(Func), "", &UI);
 }
 
 ModulePass *llvm::createLowerSetJmpPass() {