From: =?UTF-8?q?Richard=20Trembeck=C3=BD?= Date: Thu, 28 Apr 2016 18:27:24 +0200 Subject: Make KLEE compile against LLVM 3.7 Patch-mainline: no Signed-off-by: Jiri Slaby --- include/klee/CommandLine.h | 3 +- include/klee/Internal/Support/FloatEvaluation.h | 7 +++++ lib/Core/ExternalDispatcher.cpp | 15 ++++++---- lib/Core/StatsTracker.cpp | 3 +- lib/Module/InstructionInfoTable.cpp | 8 ++++- lib/Module/IntrinsicCleaner.cpp | 14 +++++++++ lib/Module/KModule.cpp | 13 ++++++++- lib/Module/ModuleUtil.cpp | 24 +++++++++++++-- lib/Module/Optimize.cpp | 39 +++++++++++++++++-------- lib/Module/RaiseAsm.cpp | 6 ++-- tools/klee/main.cpp | 9 +++++- 11 files changed, 113 insertions(+), 28 deletions(-) diff --git a/include/klee/CommandLine.h b/include/klee/CommandLine.h index 95aa51e041e2..cc186db711fc 100644 --- a/include/klee/CommandLine.h +++ b/include/klee/CommandLine.h @@ -70,8 +70,7 @@ extern llvm::cl::opt MetaSMTBackend; //A bit of ugliness so we can use cl::list<> like cl::bits<>, see queryLoggingOptions template -static bool optionIsSet(llvm::cl::list list, T option) -{ +static bool optionIsSet(llvm::cl::list &list, T option) { return std::find(list.begin(), list.end(), option) != list.end(); } diff --git a/include/klee/Internal/Support/FloatEvaluation.h b/include/klee/Internal/Support/FloatEvaluation.h index 6d9092f2ea37..436e0dc8152f 100644 --- a/include/klee/Internal/Support/FloatEvaluation.h +++ b/include/klee/Internal/Support/FloatEvaluation.h @@ -132,8 +132,15 @@ inline uint64_t mod(uint64_t l, uint64_t r, unsigned inWidth) { // determine if l represents NaN inline bool isNaN(uint64_t l, unsigned inWidth) { switch( inWidth ) { +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + case FLT_BITS: + return std::isnan(UInt64AsFloat(l)); + case DBL_BITS: + return std::isnan(UInt64AsDouble(l)); +#else case FLT_BITS: return llvm::IsNAN( UInt64AsFloat(l) ); case DBL_BITS: return llvm::IsNAN( UInt64AsDouble(l) ); +#endif default: llvm::report_fatal_error("unsupported floating point width"); } } diff --git a/lib/Core/ExternalDispatcher.cpp b/lib/Core/ExternalDispatcher.cpp index 09dd715a53ae..fa29f6e3047c 100644 --- a/lib/Core/ExternalDispatcher.cpp +++ b/lib/Core/ExternalDispatcher.cpp @@ -253,11 +253,16 @@ Function *ExternalDispatcher::createDispatcher(Function *target, Instruction *in // functions. LLVM_TYPE_Q Type *argTy = (i < FTy->getNumParams() ? FTy->getParamType(i) : (*ai)->getType()); - Instruction *argI64p = - GetElementPtrInst::Create(argI64s, - ConstantInt::get(Type::getInt32Ty(getGlobalContext()), - idx), - "", dBB); + Instruction *argI64p = +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + GetElementPtrInst::Create( + nullptr, argI64s, +#else + GetElementPtrInst::Create( + argI64s, +#endif + ConstantInt::get(Type::getInt32Ty(getGlobalContext()), idx), "", + dBB); Instruction *argp = new BitCastInst(argI64p, PointerType::getUnqual(argTy), "", dBB); diff --git a/lib/Core/StatsTracker.cpp b/lib/Core/StatsTracker.cpp index ded85f950fe4..ae12708c130c 100644 --- a/lib/Core/StatsTracker.cpp +++ b/lib/Core/StatsTracker.cpp @@ -167,8 +167,9 @@ static bool instructionIsCoverable(Instruction *i) { } else { Instruction *prev = --it; if (isa(prev) || isa(prev)) { + CallSite cs(prev); Function *target = - getDirectCallTarget(prev, /*moduleIsFullyLinked=*/true); + getDirectCallTarget(cs, /*moduleIsFullyLinked=*/true); if (target && target->doesNotReturn()) return false; } diff --git a/lib/Module/InstructionInfoTable.cpp b/lib/Module/InstructionInfoTable.cpp index 7e9a9e268b40..53c64878391f 100644 --- a/lib/Module/InstructionInfoTable.cpp +++ b/lib/Module/InstructionInfoTable.cpp @@ -87,7 +87,7 @@ static void buildInstructionToLineMap(Module *m, } } -static std::string getDSPIPath(DILocation Loc) { +static std::string getDSPIPath(const DILocation &Loc) { std::string dir = Loc.getDirectory(); std::string file = Loc.getFilename(); if (dir.empty() || file[0] == '/') { @@ -103,9 +103,15 @@ bool InstructionInfoTable::getInstructionDebugInfo(const llvm::Instruction *I, const std::string *&File, unsigned &Line) { if (MDNode *N = I->getMetadata("dbg")) { +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + DILocation *Loc = cast(N); + File = internString(getDSPIPath(*Loc)); + Line = Loc->getLine(); +#else DILocation Loc(N); File = internString(getDSPIPath(Loc)); Line = Loc.getLineNumber(); +#endif return true; } diff --git a/lib/Module/IntrinsicCleaner.cpp b/lib/Module/IntrinsicCleaner.cpp index 54582e6954cf..66e9392a618d 100644 --- a/lib/Module/IntrinsicCleaner.cpp +++ b/lib/Module/IntrinsicCleaner.cpp @@ -109,11 +109,25 @@ bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b, Module &M) { 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); +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + pDst = + GetElementPtrInst::Create(nullptr, pDst, off, std::string(), ii); + pSrc = + GetElementPtrInst::Create(nullptr, pSrc, off, std::string(), ii); +#else pDst = GetElementPtrInst::Create(pDst, off, std::string(), ii); pSrc = GetElementPtrInst::Create(pSrc, off, std::string(), ii); +#endif val = new LoadInst(pSrc, std::string(), ii); new StoreInst(val, pDst, ii); +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + pDst = + GetElementPtrInst::Create(nullptr, pDst, off, std::string(), ii); + pSrc = + GetElementPtrInst::Create(nullptr, pSrc, off, std::string(), ii); +#else pDst = GetElementPtrInst::Create(pDst, off, std::string(), ii); pSrc = GetElementPtrInst::Create(pSrc, off, std::string(), ii); +#endif val = new LoadInst(pSrc, std::string(), ii); new StoreInst(val, pDst, ii); } ii->removeFromParent(); diff --git a/lib/Module/KModule.cpp b/lib/Module/KModule.cpp index 598c439f9da0..cc328b1bb974 100644 --- a/lib/Module/KModule.cpp +++ b/lib/Module/KModule.cpp @@ -46,8 +46,11 @@ #else #include "llvm/IR/CallSite.h" #endif - +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) +#include "llvm/IR/LegacyPassManager.h" +#else #include "llvm/PassManager.h" +#endif #include "llvm/Support/CommandLine.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_os_ostream.h" @@ -301,7 +304,11 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts, // invariant transformations that we will end up doing later so that // optimize is seeing what is as close as possible to the final // module. +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + legacy::PassManager pm; +#else PassManager pm; +#endif pm.add(new RaiseAsmPass()); if (opts.CheckDivZero) pm.add(new DivCheckPass()); if (opts.CheckOvershift) pm.add(new OvershiftCheckPass()); @@ -369,7 +376,11 @@ void KModule::prepare(const Interpreter::ModuleOptions &opts, // linked in something with intrinsics but any external calls are // going to be unresolved. We really need to handle the intrinsics // directly I think? +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + legacy::PassManager pm3; +#else PassManager pm3; +#endif pm3.add(createCFGSimplificationPass()); switch(SwitchType) { case eSwitchTypeInternal: break; diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp index 537c9aba4b6f..2aa9b8e6b0ab 100644 --- a/lib/Module/ModuleUtil.cpp +++ b/lib/Module/ModuleUtil.cpp @@ -272,14 +272,22 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er // FIXME: Maybe load bitcode file lazily? Then if we need to link, materialise // the module #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + ErrorOr > Result_error = +#else ErrorOr Result_error = +#endif parseBitcodeFile(buff.get(), getGlobalContext()); ec = Result_error.getError(); if (ec) errorMessage = ec.message(); else - Result = Result_error.get(); +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + Result = Result_error->release(); #else + Result = Result_error.get(); +#endif +#else // LLVM 3.3, 3.4 Result = ParseBitcodeFile(buff.get(), getGlobalContext(), &errorMessage); #endif @@ -416,8 +424,15 @@ Module *klee::linkWithLibrary(Module *module, if (magic == sys::fs::file_magic::bitcode) { +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + ErrorOr > Result = parseBitcodeFile(buff, Context); + + if ((ec = Buffer.getError()) || Linker::LinkModules(module, Result->get())) + klee_error("Link with library %s failed: %s", libraryName.c_str(), + ec.message().c_str()); +#else // LLVM 3.5, 3.6 ErrorOr Result = parseBitcodeFile(buff, Context); -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) +#if LLVM_VERSION_CODE == LLVM_VERSION(3, 6) if ((ec = Buffer.getError()) || Linker::LinkModules(module, Result.get())) #else // LLVM 3.5 if ((ec = Buffer.getError()) || @@ -426,8 +441,11 @@ Module *klee::linkWithLibrary(Module *module, #endif klee_error("Link with library %s failed: %s", libraryName.c_str(), ec.message().c_str()); - +// unique_ptr owns the Module, we don't have to delete it +#if LLVM_VERSION_CODE < LLVM_VERSION(3, 7) delete Result.get(); +#endif +#endif } else if (magic == sys::fs::file_magic::archive) { #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) diff --git a/lib/Module/Optimize.cpp b/lib/Module/Optimize.cpp index 8cd592069523..3eca0db6c174 100644 --- a/lib/Module/Optimize.cpp +++ b/lib/Module/Optimize.cpp @@ -16,7 +16,11 @@ //===----------------------------------------------------------------------===// #include "klee/Config/Version.h" +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) +#include "llvm/IR/LegacyPassManager.h" +#else #include "llvm/PassManager.h" +#endif #include "llvm/Analysis/Passes.h" #include "llvm/Analysis/LoopPass.h" #include "llvm/Support/CommandLine.h" @@ -80,7 +84,11 @@ static cl::alias A1("S", cl::desc("Alias for --strip-debug"), // A utility function that adds a pass to the pass manager but will also add // a verifier pass after if we're supposed to verify. +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) +static inline void addPass(legacy::PassManager &PM, Pass *P) { +#else static inline void addPass(PassManager &PM, Pass *P) { +#endif // Add the pass to the pass manager... PM.add(P); @@ -91,8 +99,11 @@ static inline void addPass(PassManager &PM, Pass *P) { namespace llvm { - +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) +static void AddStandardCompilePasses(legacy::PassManager &PM) { +#else static void AddStandardCompilePasses(PassManager &PM) { +#endif PM.add(createVerifierPass()); // Verify that input is correct #if LLVM_VERSION_CODE < LLVM_VERSION(3, 0) @@ -166,27 +177,31 @@ static void AddStandardCompilePasses(PassManager &PM) { void Optimize(Module *M, const std::string &EntryPoint) { // Instantiate the pass manager to organize the passes. +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + legacy::PassManager Passes; +#else PassManager Passes; +#endif // If we're verifying, start off with a verification pass. if (VerifyEach) Passes.add(createVerifierPass()); -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) +#if LLVM_VERSION_CODE <= LLVM_VERSION(3, 1) + // Add an appropriate TargetData instance for this module... + addPass(Passes, new TargetData(M)); +#elif LLVM_VERSION_CODE <= LLVM_VERSION(3, 4) // Add an appropriate DataLayout instance for this module... - DataLayoutPass *dlpass = new DataLayoutPass(); - dlpass->doInitialization(*M); - addPass(Passes, dlpass); -#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) + addPass(Passes, new DataLayout(M)); +#elif LLVM_VERSION_CODE == LLVM_VERSION(3, 5) // Add an appropriate DataLayout instance for this module... addPass(Passes, new DataLayoutPass(M)); -#elif LLVM_VERSION_CODE > LLVM_VERSION(3, 1) +#elif LLVM_VERSION_CODE == LLVM_VERSION(3, 6) // Add an appropriate DataLayout instance for this module... - addPass(Passes, new DataLayout(M)); -#else - // Add an appropriate TargetData instance for this module... - addPass(Passes, new TargetData(M)); -#endif + DataLayoutPass *dlpass = new DataLayoutPass(); + dlpass->doInitialization(*M); + addPass(Passes, dlpass); +#endif // LLVM 3.7+ doesn't have DataLayoutPass anymore. // DWD - Run the opt standard pass list as well. AddStandardCompilePasses(Passes); diff --git a/lib/Module/RaiseAsm.cpp b/lib/Module/RaiseAsm.cpp index bde9fba93c3a..a2972ce7ee9b 100644 --- a/lib/Module/RaiseAsm.cpp +++ b/lib/Module/RaiseAsm.cpp @@ -103,8 +103,10 @@ bool RaiseAsmPass::runOnModule(Module &M) { klee_warning("Warning: unable to select native target: %s", Err.c_str()); TLI = 0; } else { - -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + TM = NativeTarget->createTargetMachine(HostTriple, "", "", TargetOptions()); + TLI = TM->getSubtargetImpl(*(M.begin()))->getTargetLowering(); +#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) TM = NativeTarget->createTargetMachine(HostTriple, "", "", TargetOptions()); TLI = TM->getSubtargetImpl()->getTargetLowering(); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 1) diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index 3747d69db0ed..9265abe04820 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -59,6 +59,10 @@ #include "llvm/Support/system_error.h" #endif +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) +#include "llvm/Support/Path.h" +#endif + #include #include #include @@ -1292,8 +1296,11 @@ int main(int argc, char **argv, char **envp) { // from the std::unique_ptr Buffer->release(); } - +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) + mainModule = mainModuleOrError->release(); +#else mainModule = *mainModuleOrError; +#endif if (auto ec = mainModule->materializeAllPermanently()) { klee_error("error loading program '%s': %s", InputFile.c_str(), ec.message().c_str()); -- 2.11.1