From: =?UTF-8?q?Richard=20Trembeck=C3=BD?= Date: Wed, 4 May 2016 15:21:45 +0200 Subject: llvm: make KLEE compile against LLVM 3.8 Patch-mainline: no Signed-off-by: Jiri Slaby --- lib/Core/Executor.cpp | 5 +++++ lib/Core/StatsTracker.cpp | 4 ++++ lib/Module/IntrinsicCleaner.cpp | 10 +++++++++- lib/Module/LowerSwitch.cpp | 8 ++++++++ lib/Module/ModuleUtil.cpp | 39 +++++++++++++++++++++++++++++++++------ lib/Module/Optimize.cpp | 13 ++++++++++++- tools/klee/main.cpp | 7 ++++++- 7 files changed, 77 insertions(+), 9 deletions(-) diff --git a/lib/Core/Executor.cpp b/lib/Core/Executor.cpp index 3492cd7e9b3c..51531f8f46c8 100644 --- a/lib/Core/Executor.cpp +++ b/lib/Core/Executor.cpp @@ -2136,8 +2136,13 @@ void Executor::executeInstruction(ExecutionState &state, KInstruction *ki) { !fpWidthToSemantics(right->getWidth())) return terminateStateOnExecError(state, "Unsupported FRem operation"); llvm::APFloat Res(*fpWidthToSemantics(left->getWidth()), left->getAPValue()); +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + Res.mod( + APFloat(*fpWidthToSemantics(right->getWidth()), right->getAPValue())); +#else Res.mod(APFloat(*fpWidthToSemantics(right->getWidth()),right->getAPValue()), APFloat::rmNearestTiesToEven); +#endif bindLocal(ki, state, ConstantExpr::alloc(Res.bitcastToAPInt())); break; } diff --git a/lib/Core/StatsTracker.cpp b/lib/Core/StatsTracker.cpp index 6dc13df86440..e931dcef8b2e 100644 --- a/lib/Core/StatsTracker.cpp +++ b/lib/Core/StatsTracker.cpp @@ -629,7 +629,11 @@ static std::vector getSuccs(Instruction *i) { for (succ_iterator it = succ_begin(bb), ie = succ_end(bb); it != ie; ++it) res.push_back(&*(it->begin())); } else { +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + res.push_back(&*(++(i->getIterator()))); +#else res.push_back(&*(++BasicBlock::iterator(i))); +#endif } return res; diff --git a/lib/Module/IntrinsicCleaner.cpp b/lib/Module/IntrinsicCleaner.cpp index 54bda16013b6..2b93319f2615 100644 --- a/lib/Module/IntrinsicCleaner.cpp +++ b/lib/Module/IntrinsicCleaner.cpp @@ -52,6 +52,10 @@ bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b, Module &M) { for (BasicBlock::iterator i = b.begin(), ie = b.end(); (i != ie) && (block_split == false);) { IntrinsicInst *ii = dyn_cast(&*i); +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + // create a copy of iterator to pass to IRBuilder ctor later + BasicBlock::iterator i_ = i; +#endif // increment now since LowerIntrinsic deletion makes iterator invalid. ++i; if(ii) { @@ -104,8 +108,12 @@ bool IntrinsicCleanerPass::runOnBasicBlock(BasicBlock &b, Module &M) { case Intrinsic::uadd_with_overflow: case Intrinsic::usub_with_overflow: case Intrinsic::umul_with_overflow: { +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + // ctor needs the iterator, but we already increased our one + IRBuilder<> builder(ii->getParent(), i_); +#else IRBuilder<> builder(ii->getParent(), ii); - +#endif Value *op1 = ii->getArgOperand(0); Value *op2 = ii->getArgOperand(1); diff --git a/lib/Module/LowerSwitch.cpp b/lib/Module/LowerSwitch.cpp index 1a194245a09a..b61da111908b 100644 --- a/lib/Module/LowerSwitch.cpp +++ b/lib/Module/LowerSwitch.cpp @@ -64,7 +64,11 @@ 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(F->getContext(), "NodeBlock"); +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + Function::iterator FI = origBlock->getIterator(); +#else Function::iterator FI = origBlock; +#endif F->getBasicBlockList().insert(++FI, newBlock); ICmpInst *cmpInst = @@ -101,7 +105,11 @@ void LowerSwitchPass::processSwitchInst(SwitchInst *SI) { // if-then statements go to this and the PHI nodes are happy. BasicBlock* newDefault = BasicBlock::Create(F->getContext(), "newDefault"); +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + F->getBasicBlockList().insert(defaultBlock->getIterator(), newDefault); +#else F->getBasicBlockList().insert(defaultBlock, newDefault); +#endif BranchInst::Create(defaultBlock, newDefault); // If there is an entry in any PHI nodes for the default edge, make sure diff --git a/lib/Module/ModuleUtil.cpp b/lib/Module/ModuleUtil.cpp index b07d3d2fe348..e6d592b135b6 100644 --- a/lib/Module/ModuleUtil.cpp +++ b/lib/Module/ModuleUtil.cpp @@ -207,8 +207,19 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er StringRef memberName; #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) - ErrorOr memberNameErr = AI->getName(); - std::error_code ec = memberNameErr.getError(); + std::error_code ec; +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + ErrorOr childErr = *AI; + ec = childErr.getError(); + if (ec) { + errorMessage = ec.message(); + return false; + } +#else + object::Archive::child_iterator childErr = AI; +#endif + ErrorOr memberNameErr = childErr->getName(); + ec = memberNameErr.getError(); if (!ec) { memberName = memberNameErr.get(); #else @@ -226,7 +237,8 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er } #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) - ErrorOr > child = AI->getAsBinary(); + ErrorOr > child = + childErr->getAsBinary(); ec = child.getError(); #else OwningPtr child; @@ -235,7 +247,7 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er if (ec) { // If we can't open as a binary object file its hopefully a bitcode file #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) - ErrorOr buff = AI->getMemoryBufferRef(); + ErrorOr buff = childErr->getMemoryBufferRef(); ec = buff.getError(); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) ErrorOr > buffErr = AI->getMemoryBuffer(); @@ -343,7 +355,9 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Found " << GV->getName() << " in " << M->getModuleIdentifier() << "\n"); -#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + if (Linker::linkModules(*composite, std::unique_ptr(M))) +#elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 6) if (Linker::LinkModules(composite, M)) #else if (Linker::LinkModules(composite, M, Linker::DestroySource, &errorMessage)) @@ -360,8 +374,10 @@ static bool linkBCA(object::Archive* archive, Module* composite, std::string& er // Link succeed, now clean up modulesLoadedOnPass++; KLEE_DEBUG_WITH_TYPE("klee_linker", dbgs() << "Linking succeeded.\n"); - +// M was owned by linkModules function +#if LLVM_VERSION_CODE < LLVM_VERSION(3, 8) delete M; +#endif archiveModules[i] = 0; // We need to recompute the undefined symbols in the composite module @@ -427,7 +443,9 @@ Module *klee::linkWithLibrary(Module *module, std::string ErrorMessage; if (magic == sys::fs::file_magic::bitcode) { +#if LLVM_VERSION_CODE < LLVM_VERSION(3, 8) Module *Result = 0; +#endif #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) ErrorOr > ResultErr = @@ -445,6 +463,10 @@ Module *klee::linkWithLibrary(Module *module, ErrorMessage.c_str()); } +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + if (Linker::linkModules(*module, std::move(ResultErr.get()))) { + ErrorMessage = "linking error"; +#else #if LLVM_VERSION_CODE >= LLVM_VERSION(3, 7) Result = ResultErr->release(); #elif LLVM_VERSION_CODE >= LLVM_VERSION(3, 5) @@ -456,6 +478,7 @@ Module *klee::linkWithLibrary(Module *module, ErrorMessage = "linking error"; #else if (Linker::LinkModules(module, Result, Linker::DestroySource, &ErrorMessage)) { +#endif #endif klee_error("Link with library %s failed: %s", libraryName.c_str(), ErrorMessage.c_str()); @@ -639,7 +662,11 @@ Module *klee::loadModule(LLVMContext &ctx, const std::string &path, std::string auto module = *errorOrModule; #endif +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + if (auto ec = module->materializeAll()) { +#else if (auto ec = module->materializeAllPermanently()) { +#endif errorMsg = ec.message(); return nullptr; } diff --git a/lib/Module/Optimize.cpp b/lib/Module/Optimize.cpp index 64e4863f70b3..944f51ef336d 100644 --- a/lib/Module/Optimize.cpp +++ b/lib/Module/Optimize.cpp @@ -102,7 +102,12 @@ static void AddStandardCompilePasses(klee::LegacyLLVMPassManagerTy &PM) { addPass(PM, createCFGSimplificationPass()); // Clean up after IPCP & DAE addPass(PM, createPruneEHPass()); // Remove dead EH info - addPass(PM, createFunctionAttrsPass()); // Deduce function attrs +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + addPass(PM, createPostOrderFunctionAttrsPass()); + addPass(PM, createReversePostOrderFunctionAttrsPass()); +#else + addPass(PM, createFunctionAttrsPass()); // Deduce function attrs +#endif if (!DisableInline) addPass(PM, createFunctionInliningPass()); // Inline small functions @@ -217,8 +222,14 @@ void Optimize(Module *M, const std::string &EntryPoint) { addPass(Passes, createScalarReplAggregatesPass()); // Break up allocas // Run a few AA driven optimizations here and now, to cleanup the code. +#if LLVM_VERSION_CODE >= LLVM_VERSION(3, 8) + addPass(Passes, createPostOrderFunctionAttrsPass()); + addPass(Passes, createReversePostOrderFunctionAttrsPass()); + // addPass(Passes, createGlobalsAAWrapperPass()); +#else addPass(Passes, createFunctionAttrsPass()); // Add nocapture addPass(Passes, createGlobalsModRefPass()); // IP alias analysis +#endif addPass(Passes, createLICMPass()); // Hoist loop invariants addPass(Passes, createGVNPass()); // Remove redundancies diff --git a/tools/klee/main.cpp b/tools/klee/main.cpp index f8706f9f74e5..dbc166ed158a 100644 --- a/tools/klee/main.cpp +++ b/tools/klee/main.cpp @@ -291,7 +291,12 @@ KleeHandler::KleeHandler(int argc, char **argv) for (; i <= INT_MAX; ++i) { SmallString<128> d(directory); llvm::sys::path::append(d, "klee-out-"); - raw_svector_ostream ds(d); ds << i; ds.flush(); + raw_svector_ostream ds(d); + ds << i; +// SmallString is always up-to-date, no need to flush. See Support/raw_ostream.h +#if LLVM_VERSION_CODE < LLVM_VERSION(3, 8) + ds.flush(); +#endif // create directory and try to link klee-last if (mkdir(d.c_str(), 0775) == 0) { -- 2.15.0