about summary refs log tree commit diff homepage
diff options
context:
space:
mode:
-rw-r--r--include/klee/Interpreter.h4
-rw-r--r--lib/Core/Executor.cpp13
-rw-r--r--lib/Core/Executor.h4
-rw-r--r--lib/Core/ExternalDispatcher.cpp20
-rw-r--r--lib/Core/ExternalDispatcher.h3
-rw-r--r--lib/Module/Checks.cpp19
-rw-r--r--lib/Module/IntrinsicCleaner.cpp11
-rw-r--r--lib/Module/KModule.cpp26
-rw-r--r--lib/Module/LowerSwitch.cpp4
-rw-r--r--lib/Module/ModuleUtil.cpp5
-rw-r--r--tools/klee/main.cpp31
11 files changed, 78 insertions, 62 deletions
diff --git a/include/klee/Interpreter.h b/include/klee/Interpreter.h
index ece84b2c..4c428994 100644
--- a/include/klee/Interpreter.h
+++ b/include/klee/Interpreter.h
@@ -18,6 +18,7 @@ struct KTest;
 
 namespace llvm {
 class Function;
+class LLVMContext;
 class Module;
 class raw_ostream;
 class raw_fd_ostream;
@@ -93,7 +94,8 @@ protected:
 public:
   virtual ~Interpreter() {}
 
-  static Interpreter *create(const InterpreterOptions &_interpreterOpts,
+  static Interpreter *create(llvm::LLVMContext &ctx,
+                             const InterpreterOptions &_interpreterOpts,
                              InterpreterHandler *ih);
 
   /// Register the module to be executed.  
diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp
index 58603e7c..19a5e3f8 100644
--- a/lib/Core/Executor.cpp
+++ b/lib/Core/Executor.cpp
@@ -343,9 +343,10 @@ const char *Executor::TerminateReasonNames[] = {
   [ Unhandled ] = "xxx",
 };
 
-Executor::Executor(const InterpreterOptions &opts, InterpreterHandler *ih)
+Executor::Executor(LLVMContext &ctx, const InterpreterOptions &opts,
+    InterpreterHandler *ih)
     : Interpreter(opts), kmodule(0), interpreterHandler(ih), searcher(0),
-      externalDispatcher(new ExternalDispatcher()), statsTracker(0),
+      externalDispatcher(new ExternalDispatcher(ctx)), statsTracker(0),
       pathWriter(0), symPathWriter(0), specialFunctionHandler(0),
       processTree(0), replayKTest(0), replayPath(0), usingSeeds(0),
       atMemoryLimit(false), inhibitForking(false), haltExecution(false),
@@ -1552,7 +1553,7 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) {
 
       if (!isVoidReturn) {
         LLVM_TYPE_Q Type *t = caller->getType();
-        if (t != Type::getVoidTy(getGlobalContext())) {
+        if (t != Type::getVoidTy(i->getContext())) {
           // may need to do coercion due to bitcasts
           Expr::Width from = result->getWidth();
           Expr::Width to = getWidthForLLVMType(t);
@@ -3087,7 +3088,7 @@ void Executor::callExternalFunction(ExecutionState &state,
   }
 
   LLVM_TYPE_Q Type *resultType = target->inst->getType();
-  if (resultType != Type::getVoidTy(getGlobalContext())) {
+  if (resultType != Type::getVoidTy(function->getContext())) {
     ref<Expr> e = ConstantExpr::fromMemory((void*) args, 
                                            getWidthForLLVMType(resultType));
     bindLocal(target, state, e);
@@ -3756,7 +3757,7 @@ Expr::Width Executor::getWidthForLLVMType(LLVM_TYPE_Q llvm::Type *type) const {
 
 ///
 
-Interpreter *Interpreter::create(const InterpreterOptions &opts,
+Interpreter *Interpreter::create(LLVMContext &ctx, const InterpreterOptions &opts,
                                  InterpreterHandler *ih) {
-  return new Executor(opts, ih);
+  return new Executor(ctx, opts, ih);
 }
diff --git a/lib/Core/Executor.h b/lib/Core/Executor.h
index 93d1443e..4970b8a0 100644
--- a/lib/Core/Executor.h
+++ b/lib/Core/Executor.h
@@ -41,6 +41,7 @@ namespace llvm {
   class Function;
   class GlobalValue;
   class Instruction;
+  class LLVMContext;
 #if LLVM_VERSION_CODE <= LLVM_VERSION(3, 1)
   class TargetData;
 #else
@@ -434,7 +435,8 @@ private:
   void doDumpStates();
 
 public:
-  Executor(const InterpreterOptions &opts, InterpreterHandler *ie);
+  Executor(llvm::LLVMContext &ctx, const InterpreterOptions &opts,
+      InterpreterHandler *ie);
   virtual ~Executor();
 
   const InterpreterHandler& getHandler() {
diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp
index ecc9912e..01c5f935 100644
--- a/lib/Core/ExternalDispatcher.cpp
+++ b/lib/Core/ExternalDispatcher.cpp
@@ -85,8 +85,8 @@ void *ExternalDispatcher::resolveSymbol(const std::string &name) {
   return addr;
 }
 
-ExternalDispatcher::ExternalDispatcher() {
-  dispatchModule = new Module("ExternalDispatcher", getGlobalContext());
+ExternalDispatcher::ExternalDispatcher(LLVMContext &ctx) {
+  dispatchModule = new Module("ExternalDispatcher", ctx);
 
   std::string error;
   executionEngine = ExecutionEngine::createJIT(dispatchModule, &error);
@@ -195,6 +195,7 @@ Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *in
   if (!resolveSymbol(target->getName()))
     return 0;
 
+  LLVMContext &ctx = target->getContext();
   CallSite cs;
   if (inst->getOpcode()==Instruction::Call) {
     cs = CallSite(cast<CallInst>(inst));
@@ -206,20 +207,20 @@ Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *in
 
   std::vector<LLVM_TYPE_Q Type*> nullary;
   
-  Function *dispatcher = Function::Create(FunctionType::get(Type::getVoidTy(getGlobalContext()), 
+  Function *dispatcher = Function::Create(FunctionType::get(Type::getVoidTy(ctx),
 							    nullary, false),
 					  GlobalVariable::ExternalLinkage, 
 					  "",
 					  dispatchModule);
 
 
-  BasicBlock *dBB = BasicBlock::Create(getGlobalContext(), "entry", dispatcher);
+  BasicBlock *dBB = BasicBlock::Create(ctx, "entry", dispatcher);
 
   // Get a Value* for &gTheArgsP, as an i64**.
   Instruction *argI64sp = 
-    new IntToPtrInst(ConstantInt::get(Type::getInt64Ty(getGlobalContext()), 
+    new IntToPtrInst(ConstantInt::get(Type::getInt64Ty(ctx),
                                       (uintptr_t) (void*) &gTheArgsP),
-                     PointerType::getUnqual(PointerType::getUnqual(Type::getInt64Ty(getGlobalContext()))),
+                     PointerType::getUnqual(PointerType::getUnqual(Type::getInt64Ty(ctx))),
                      "argsp", dBB);
   Instruction *argI64s = new LoadInst(argI64sp, "args", dBB); 
   
@@ -238,8 +239,7 @@ Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *in
                                (*ai)->getType());
     Instruction *argI64p = 
       GetElementPtrInst::Create(argI64s, 
-                                ConstantInt::get(Type::getInt32Ty(getGlobalContext()), 
-                                                 idx), 
+                                ConstantInt::get(Type::getInt32Ty(ctx), idx),
                                 "", dBB);
 
     Instruction *argp = new BitCastInst(argI64p, PointerType::getUnqual(argTy),
@@ -260,14 +260,14 @@ Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *in
 #else
   Instruction *result = CallInst::Create(dispatchTarget, args, args+i, "", dBB);
 #endif
-  if (result->getType() != Type::getVoidTy(getGlobalContext())) {
+  if (result->getType() != Type::getVoidTy(ctx)) {
     Instruction *resp = 
       new BitCastInst(argI64s, PointerType::getUnqual(result->getType()), 
                       "", dBB);
     new StoreInst(result, resp, dBB);
   }
 
-  ReturnInst::Create(getGlobalContext(), dBB);
+  ReturnInst::Create(ctx, dBB);
 
   delete[] args;
 
diff --git a/lib/Core/ExternalDispatcher.h b/lib/Core/ExternalDispatcher.h
index d8d9dc58..94363bab 100644
--- a/lib/Core/ExternalDispatcher.h
+++ b/lib/Core/ExternalDispatcher.h
@@ -17,6 +17,7 @@
 namespace llvm {
   class ExecutionEngine;
   class Instruction;
+  class LLVMContext;
   class Function;
   class FunctionType;
   class Module;
@@ -35,7 +36,7 @@ namespace klee {
     bool runProtectedCall(llvm::Function *f, uint64_t *args);
     
   public:
-    ExternalDispatcher();
+    ExternalDispatcher(llvm::LLVMContext &ctx);
     ~ExternalDispatcher();
 
     /* Call the given function using the parameter passing convention of
diff --git a/lib/Module/Checks.cpp b/lib/Module/Checks.cpp
index 7d9b7284..44b35e6e 100644
--- a/lib/Module/Checks.cpp
+++ b/lib/Module/Checks.cpp
@@ -53,6 +53,7 @@ char DivCheckPass::ID;
 
 bool DivCheckPass::runOnModule(Module &M) { 
   Function *divZeroCheckFunction = 0;
+  LLVMContext &ctx = M.getContext();
 
   bool moduleChanged = false;
   
@@ -67,7 +68,7 @@ bool DivCheckPass::runOnModule(Module &M) {
             
             CastInst *denominator =
               CastInst::CreateIntegerCast(i->getOperand(1),
-                                          Type::getInt64Ty(getGlobalContext()),
+                                          Type::getInt64Ty(ctx),
                                           false,  /* sign doesn't matter */
                                           "int_cast_to_i64",
                                           i);
@@ -75,8 +76,8 @@ bool DivCheckPass::runOnModule(Module &M) {
             // Lazily bind the function to avoid always importing it.
             if (!divZeroCheckFunction) {
               Constant *fc = M.getOrInsertFunction("klee_div_zero_check", 
-                                                   Type::getVoidTy(getGlobalContext()), 
-                                                   Type::getInt64Ty(getGlobalContext()), 
+                                                   Type::getVoidTy(ctx),
+                                                   Type::getInt64Ty(ctx),
                                                    NULL);
               divZeroCheckFunction = cast<Function>(fc);
             }
@@ -100,6 +101,7 @@ char OvershiftCheckPass::ID;
 
 bool OvershiftCheckPass::runOnModule(Module &M) {
   Function *overshiftCheckFunction = 0;
+  LLVMContext &ctx = M.getContext();
 
   bool moduleChanged = false;
 
@@ -118,12 +120,13 @@ bool OvershiftCheckPass::runOnModule(Module &M) {
             // Determine bit width of first operand
             uint64_t bitWidth=i->getOperand(0)->getType()->getScalarSizeInBits();
 
-            ConstantInt *bitWidthC = ConstantInt::get(Type::getInt64Ty(getGlobalContext()),bitWidth,false);
+            ConstantInt *bitWidthC = ConstantInt::get(Type::getInt64Ty(ctx),
+		bitWidth, false);
             args.push_back(bitWidthC);
 
             CastInst *shift =
               CastInst::CreateIntegerCast(i->getOperand(1),
-                                          Type::getInt64Ty(getGlobalContext()),
+                                          Type::getInt64Ty(ctx),
                                           false,  /* sign doesn't matter */
                                           "int_cast_to_i64",
                                           i);
@@ -133,9 +136,9 @@ bool OvershiftCheckPass::runOnModule(Module &M) {
             // Lazily bind the function to avoid always importing it.
             if (!overshiftCheckFunction) {
               Constant *fc = M.getOrInsertFunction("klee_overshift_check",
-                                                   Type::getVoidTy(getGlobalContext()),
-                                                   Type::getInt64Ty(getGlobalContext()),
-                                                   Type::getInt64Ty(getGlobalContext()),
+                                                   Type::getVoidTy(ctx),
+                                                   Type::getInt64Ty(ctx),
+                                                   Type::getInt64Ty(ctx),
                                                    NULL);
               overshiftCheckFunction = cast<Function>(fc);
             }
diff --git a/lib/Module/IntrinsicCleaner.cpp b/lib/Module/IntrinsicCleaner.cpp
index 54582e69..3f7644af 100644
--- a/lib/Module/IntrinsicCleaner.cpp
+++ b/lib/Module/IntrinsicCleaner.cpp
@@ -70,6 +70,7 @@ bool IntrinsicCleanerPass::runOnModule(Module &M) {
 bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b, Module &M) {
   bool dirty = false;
   bool block_split=false;
+  LLVMContext &ctx = M.getContext();
   
 #if LLVM_VERSION_CODE <= LLVM_VERSION(3, 1)
   unsigned WordSize = TargetData.getPointerSizeInBits() / 8;
@@ -97,18 +98,18 @@ bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b, Module &M) {
         Value *src = ii->getArgOperand(1);
 
         if (WordSize == 4) {
-          Type *i8pp = PointerType::getUnqual(PointerType::getUnqual(Type::getInt8Ty(getGlobalContext())));
+          Type *i8pp = PointerType::getUnqual(PointerType::getUnqual(Type::getInt8Ty(ctx)));
           Value *castedDst = CastInst::CreatePointerCast(dst, i8pp, "vacopy.cast.dst", ii);
           Value *castedSrc = CastInst::CreatePointerCast(src, i8pp, "vacopy.cast.src", ii);
           Value *load = new LoadInst(castedSrc, "vacopy.read", ii);
           new StoreInst(load, castedDst, false, ii);
         } else {
           assert(WordSize == 8 && "Invalid word size!");
-          Type *i64p = PointerType::getUnqual(Type::getInt64Ty(getGlobalContext()));
+          Type *i64p = PointerType::getUnqual(Type::getInt64Ty(ctx));
           Value *pDst = CastInst::CreatePointerCast(dst, i64p, "vacopy.cast.dst", ii);
           Value *pSrc = CastInst::CreatePointerCast(src, i64p, "vacopy.cast.src", ii);
           Value *val = new LoadInst(pSrc, std::string(), ii); new StoreInst(val, pDst, ii);
-          Value *off = ConstantInt::get(Type::getInt64Ty(getGlobalContext()), 1);
+          Value *off = ConstantInt::get(Type::getInt64Ty(ctx), 1);
           pDst = GetElementPtrInst::Create(pDst, off, std::string(), ii);
           pSrc = GetElementPtrInst::Create(pSrc, off, std::string(), ii);
           val = new LoadInst(pSrc, std::string(), ii); new StoreInst(val, pDst, ii);
@@ -223,12 +224,12 @@ bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b, Module &M) {
         // a call of the abort() function.
         Function *F = cast<Function>(
           M.getOrInsertFunction(
-            "abort", Type::getVoidTy(getGlobalContext()), NULL));
+            "abort", Type::getVoidTy(ctx), NULL));
         F->setDoesNotReturn();
         F->setDoesNotThrow();
 
         CallInst::Create(F, Twine(), ii);
-        new UnreachableInst(getGlobalContext(), ii);
+        new UnreachableInst(ctx, ii);
 
         ii->eraseFromParent();
 
diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp
index 57346a31..3259873e 100644
--- a/lib/Module/KModule.cpp
+++ b/lib/Module/KModule.cpp
@@ -144,12 +144,12 @@ static Function *getStubFunctionForCtorList(Module *m,
   
   std::vector<LLVM_TYPE_Q Type*> nullary;
 
-  Function *fn = Function::Create(FunctionType::get(Type::getVoidTy(getGlobalContext()), 
+  Function *fn = Function::Create(FunctionType::get(Type::getVoidTy(m->getContext()),
 						    nullary, false),
 				  GlobalVariable::InternalLinkage, 
 				  name,
                               m);
-  BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "entry", fn);
+  BasicBlock *bb = BasicBlock::Create(m->getContext(), "entry", fn);
   
   // From lli:
   // Should be an array of '{ int, void ()* }' structs.  The first value is
@@ -174,7 +174,7 @@ static Function *getStubFunctionForCtorList(Module *m,
     }
   }
   
-  ReturnInst::Create(getGlobalContext(), bb);
+  ReturnInst::Create(m->getContext(), bb);
 
   return fn;
 }
@@ -241,11 +241,13 @@ void KModule::addInternalFunction(const char* functionName){
 
 void KModule::prepare(const Interpreter::ModuleOptions &opts,
                       InterpreterHandler *ih) {
+  LLVMContext &ctx = module->getContext();
+
   if (!MergeAtExit.empty()) {
     Function *mergeFn = module->getFunction("klee_merge");
     if (!mergeFn) {
       LLVM_TYPE_Q llvm::FunctionType *Ty = 
-        FunctionType::get(Type::getVoidTy(getGlobalContext()), 
+        FunctionType::get(Type::getVoidTy(ctx),
                           std::vector<LLVM_TYPE_Q Type*>(), false);
       mergeFn = Function::Create(Ty, GlobalVariable::ExternalLinkage,
 				 "klee_merge",
@@ -264,16 +266,16 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts,
                    name.c_str());
       }
 
-      BasicBlock *exit = BasicBlock::Create(getGlobalContext(), "exit", f);
+      BasicBlock *exit = BasicBlock::Create(ctx, "exit", f);
       PHINode *result = 0;
-      if (f->getReturnType() != Type::getVoidTy(getGlobalContext()))
+      if (f->getReturnType() != Type::getVoidTy(ctx))
 #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 0)
         result = PHINode::Create(f->getReturnType(), 0, "retval", exit);
 #else
 		result = PHINode::Create(f->getReturnType(), "retval", exit);
 #endif
       CallInst::Create(mergeFn, "", exit);
-      ReturnInst::Create(getGlobalContext(), result, exit);
+      ReturnInst::Create(ctx, result, exit);
 
       llvm::errs() << "KLEE: adding klee_merge at exit of: " << name << "\n";
       for (llvm::Function::iterator bbit = f->begin(), bbie = f->end(); 
@@ -317,19 +319,19 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts,
   // by name. We only add them if such a function doesn't exist to
   // avoid creating stale uses.
 
-  LLVM_TYPE_Q llvm::Type *i8Ty = Type::getInt8Ty(getGlobalContext());
+  LLVM_TYPE_Q llvm::Type *i8Ty = Type::getInt8Ty(ctx);
   forceImport(module, "memcpy", PointerType::getUnqual(i8Ty),
               PointerType::getUnqual(i8Ty),
               PointerType::getUnqual(i8Ty),
-              targetData->getIntPtrType(getGlobalContext()), (Type*) 0);
+              targetData->getIntPtrType(ctx), (Type*) 0);
   forceImport(module, "memmove", PointerType::getUnqual(i8Ty),
               PointerType::getUnqual(i8Ty),
               PointerType::getUnqual(i8Ty),
-              targetData->getIntPtrType(getGlobalContext()), (Type*) 0);
+              targetData->getIntPtrType(ctx), (Type*) 0);
   forceImport(module, "memset", PointerType::getUnqual(i8Ty),
               PointerType::getUnqual(i8Ty),
-              Type::getInt32Ty(getGlobalContext()),
-              targetData->getIntPtrType(getGlobalContext()), (Type*) 0);
+              Type::getInt32Ty(ctx),
+              targetData->getIntPtrType(ctx), (Type*) 0);
 #endif
   // FIXME: Missing force import for various math functions.
 
diff --git a/lib/Module/LowerSwitch.cpp b/lib/Module/LowerSwitch.cpp
index a98b84ad..7f28748a 100644
--- a/lib/Module/LowerSwitch.cpp
+++ b/lib/Module/LowerSwitch.cpp
@@ -66,7 +66,7 @@ void LowerSwitchPass::switchConvert(CaseItr begin, CaseItr end,
   
   // iterate through all the cases, creating a new BasicBlock for each
   for (CaseItr it = begin; it < end; ++it) {
-    BasicBlock *newBlock = BasicBlock::Create(getGlobalContext(), "NodeBlock");
+    BasicBlock *newBlock = BasicBlock::Create(F->getContext(), "NodeBlock");
     Function::iterator FI = origBlock;
     F->getBasicBlockList().insert(++FI, newBlock);
     
@@ -102,7 +102,7 @@ void LowerSwitchPass::processSwitchInst(SwitchInst *SI) {
 
   // Create a new, empty default block so that the new hierarchy of
   // if-then statements go to this and the PHI nodes are happy.
-  BasicBlock* newDefault = BasicBlock::Create(getGlobalContext(), "newDefault");
+  BasicBlock* newDefault = BasicBlock::Create(F->getContext(), "newDefault");
 
   F->getBasicBlockList().insert(defaultBlock, newDefault);
   BranchInst::Create(defaultBlock, newDefault);
diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp
index 2cd41c89..94a37e08 100644
--- a/lib/Module/ModuleUtil.cpp
+++ b/lib/Module/ModuleUtil.cpp
@@ -248,7 +248,8 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er
       if (buff)
       {
         // FIXME: Maybe load bitcode file lazily? Then if we need to link, materialise the module
-        Result = ParseBitcodeFile(buff.get(), getGlobalContext(), &errorMessage);
+        Result = ParseBitcodeFile(buff.get(), composite->getContext(),
+	    &errorMessage);
 
         if(!Result)
         {
@@ -378,7 +379,7 @@ Module *klee::linkWithLibrary(Module *module,
 
   sys::fs::file_magic magic = sys::fs::identify_magic(Buffer->getBuffer());
 
-  LLVMContext &Context = getGlobalContext();
+  LLVMContext &Context = module->getContext();
   std::string ErrorMessage;
 
   if (magic == sys::fs::file_magic::bitcode) {
diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp
index e95522a0..505d259c 100644
--- a/tools/klee/main.cpp
+++ b/tools/klee/main.cpp
@@ -689,11 +689,12 @@ static int initEnv(Module *mainModule) {
 
   /* Insert void klee_init_env(int* argc, char*** argv) */
   std::vector<const Type*> params;
-  params.push_back(Type::getInt32Ty(getGlobalContext()));
-  params.push_back(Type::getInt32Ty(getGlobalContext()));
+  LLVMContext &ctx = mainModule->getContext();
+  params.push_back(Type::getInt32Ty(ctx));
+  params.push_back(Type::getInt32Ty(ctx));
   Function* initEnvFn =
     cast<Function>(mainModule->getOrInsertFunction("klee_init_env",
-                                                   Type::getVoidTy(getGlobalContext()),
+                                                   Type::getVoidTy(ctx),
                                                    argcPtr->getType(),
                                                    argvPtr->getType(),
                                                    NULL));
@@ -1032,6 +1033,7 @@ static void replaceOrRenameFunction(llvm::Module *module,
   }
 }
 static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir) {
+  LLVMContext &ctx = mainModule->getContext();
   // Ensure that klee-uclibc exists
   SmallString<128> uclibcBCA(libDir);
   llvm::sys::path::append(uclibcBCA, KLEE_UCLIBC_BCA_NAME);
@@ -1044,13 +1046,13 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir)
   Function *f;
   // force import of __uClibc_main
   mainModule->getOrInsertFunction("__uClibc_main",
-                                  FunctionType::get(Type::getVoidTy(getGlobalContext()),
+                                  FunctionType::get(Type::getVoidTy(ctx),
                                                std::vector<LLVM_TYPE_Q Type*>(),
                                                     true));
 
   // force various imports
   if (WithPOSIXRuntime) {
-    LLVM_TYPE_Q llvm::Type *i8Ty = Type::getInt8Ty(getGlobalContext());
+    LLVM_TYPE_Q llvm::Type *i8Ty = Type::getInt8Ty(ctx);
     mainModule->getOrInsertFunction("realpath",
                                     PointerType::getUnqual(i8Ty),
                                     PointerType::getUnqual(i8Ty),
@@ -1060,12 +1062,12 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir)
                                     PointerType::getUnqual(i8Ty),
                                     NULL);
     mainModule->getOrInsertFunction("__fgetc_unlocked",
-                                    Type::getInt32Ty(getGlobalContext()),
+                                    Type::getInt32Ty(ctx),
                                     PointerType::getUnqual(i8Ty),
                                     NULL);
     mainModule->getOrInsertFunction("__fputc_unlocked",
-                                    Type::getInt32Ty(getGlobalContext()),
-                                    Type::getInt32Ty(getGlobalContext()),
+                                    Type::getInt32Ty(ctx),
+                                    Type::getInt32Ty(ctx),
                                     PointerType::getUnqual(i8Ty),
                                     NULL);
   }
@@ -1130,11 +1132,11 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir)
   std::vector<LLVM_TYPE_Q Type*> fArgs;
   fArgs.push_back(ft->getParamType(1)); // argc
   fArgs.push_back(ft->getParamType(2)); // argv
-  Function *stub = Function::Create(FunctionType::get(Type::getInt32Ty(getGlobalContext()), fArgs, false),
+  Function *stub = Function::Create(FunctionType::get(Type::getInt32Ty(ctx), fArgs, false),
                                     GlobalVariable::ExternalLinkage,
                                     EntryPoint,
                                     mainModule);
-  BasicBlock *bb = BasicBlock::Create(getGlobalContext(), "entry", stub);
+  BasicBlock *bb = BasicBlock::Create(ctx, "entry", stub);
 
   std::vector<llvm::Value*> args;
   args.push_back(llvm::ConstantExpr::getBitCast(userMainFn,
@@ -1151,7 +1153,7 @@ static llvm::Module *linkWithUclibc(llvm::Module *mainModule, StringRef libDir)
   CallInst::Create(uclibcMainFn, args.begin(), args.end(), "", bb);
 #endif
 
-  new UnreachableInst(getGlobalContext(), bb);
+  new UnreachableInst(ctx, bb);
 
   klee_message("NOTE: Using klee-uclibc : %s", uclibcBCA.c_str());
   return mainModule;
@@ -1236,6 +1238,7 @@ int main(int argc, char **argv, char **envp) {
 
   // Load the bytecode...
   std::string ErrorMsg;
+  LLVMContext ctx;
   Module *mainModule = 0;
 #if LLVM_VERSION_CODE < LLVM_VERSION(3, 5)
   OwningPtr<MemoryBuffer> BufferPtr;
@@ -1245,7 +1248,7 @@ int main(int argc, char **argv, char **envp) {
                ec.message().c_str());
   }
 
-  mainModule = getLazyBitcodeModule(BufferPtr.get(), getGlobalContext(), &ErrorMsg);
+  mainModule = getLazyBitcodeModule(BufferPtr.get(), ctx, &ErrorMsg);
 
   if (mainModule) {
     if (mainModule->MaterializeAllPermanently(&ErrorMsg)) {
@@ -1262,7 +1265,7 @@ int main(int argc, char **argv, char **envp) {
     klee_error("error loading program '%s': %s", InputFile.c_str(),
                Buffer.getError().message().c_str());
 
-  auto mainModuleOrError = getLazyBitcodeModule(Buffer->get(), getGlobalContext());
+  auto mainModuleOrError = getLazyBitcodeModule(Buffer->get(), ctx);
 
   if (!mainModuleOrError) {
     klee_error("error loading program '%s': %s", InputFile.c_str(),
@@ -1387,7 +1390,7 @@ int main(int argc, char **argv, char **envp) {
   IOpts.MakeConcreteSymbolic = MakeConcreteSymbolic;
   KleeHandler *handler = new KleeHandler(pArgc, pArgv);
   Interpreter *interpreter =
-    theInterpreter = Interpreter::create(IOpts, handler);
+    theInterpreter = Interpreter::create(ctx, IOpts, handler);
   handler->setInterpreter(interpreter);
 
   for (int i=0; i<argc; i++) {