From 934244831211dde570d05c1c1dda55c264df68dc Mon Sep 17 00:00:00 2001 From: Manasij Mukherjee Date: Wed, 28 Apr 2021 11:03:24 -0700 Subject: [PATCH] Misc fixes to make Souper work better with SPEC 2017 (#813) --- build_deps.sh | 2 +- include/souper/Inst/Inst.h | 2 +- lib/Infer/EnumerativeSynthesis.cpp | 4 ++-- lib/Inst/Inst.cpp | 12 ++++++++---- lib/Pass/Pass.cpp | 21 ++++++++++++++++++++- 5 files changed, 32 insertions(+), 9 deletions(-) diff --git a/build_deps.sh b/build_deps.sh index efec652ec..bbbaed4ed 100755 --- a/build_deps.sh +++ b/build_deps.sh @@ -75,7 +75,7 @@ mkdir -p $llvm_srcdir mkdir -p $llvm_builddir -cmake_flags="-DCMAKE_INSTALL_PREFIX=$llvm_installdir -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_FORCE_ENABLE_STATS=ON -DCMAKE_BUILD_TYPE=$llvm_build_type -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_PROJECTS=\'llvm;clang;compiler-rt\'" +cmake_flags="-DCMAKE_INSTALL_PREFIX=$llvm_installdir -DLLVM_ENABLE_ASSERTIONS=ON -DLLVM_FORCE_ENABLE_STATS=ON -DCMAKE_BUILD_TYPE=$llvm_build_type -DLLVM_ENABLE_Z3_SOLVER=OFF -DLLVM_ENABLE_PROJECTS=\'llvm;clang;openmp;compiler-rt\'" if [ -n "`which ninja`" ] ; then (cd $llvm_builddir && cmake ${llvm_srcdir}/llvm -G Ninja $cmake_flags -DCMAKE_CXX_FLAGS="-DDISABLE_WRONG_OPTIMIZATIONS_DEFAULT_VALUE=true -DDISABLE_PEEPHOLES_DEFAULT_VALUE=false" "$@") diff --git a/include/souper/Inst/Inst.h b/include/souper/Inst/Inst.h index b854c570d..7c268677c 100644 --- a/include/souper/Inst/Inst.h +++ b/include/souper/Inst/Inst.h @@ -315,7 +315,7 @@ Inst *getInstCopy(Inst *I, InstContext &IC, std::map &InstCache, std::map &BlockCache, std::map *ConstMap, - bool CloneVars); + bool CloneVars, bool CloneBlocks = true); Inst *instJoin(Inst *I, Inst *Reserved, Inst *NewInst, std::map &InstCache, InstContext &IC); diff --git a/lib/Infer/EnumerativeSynthesis.cpp b/lib/Infer/EnumerativeSynthesis.cpp index 4ee94d45f..4d9d9f67b 100644 --- a/lib/Infer/EnumerativeSynthesis.cpp +++ b/lib/Infer/EnumerativeSynthesis.cpp @@ -725,7 +725,7 @@ std::error_code synthesizeWithKLEE(SynthesisContext &SC, std::vector &RH if (!ResultConstMap.empty()) { std::map InstCache; std::map BlockCache; - RHS = getInstCopy(I, SC.IC, InstCache, BlockCache, &ResultConstMap, false); + RHS = getInstCopy(I, SC.IC, InstCache, BlockCache, &ResultConstMap, false, false); } else { continue; } @@ -761,7 +761,7 @@ std::error_code synthesizeWithKLEE(SynthesisContext &SC, std::vector &RH } std::map InstCache; std::map BlockCache; - auto newRHS = getInstCopy(I, SC.IC, InstCache, BlockCache, &ZeroConstMap, false); + auto newRHS = getInstCopy(I, SC.IC, InstCache, BlockCache, &ZeroConstMap, false, false); if (isTransformationValid(SC.LHS, newRHS, SC.PCs, SC.BPCs, SC.IC)) RHS = newRHS; } diff --git a/lib/Inst/Inst.cpp b/lib/Inst/Inst.cpp index 5ee10945d..7d4316edd 100644 --- a/lib/Inst/Inst.cpp +++ b/lib/Inst/Inst.cpp @@ -1172,7 +1172,7 @@ Inst *souper::getInstCopy(Inst *I, InstContext &IC, std::map &InstCache, std::map &BlockCache, std::map *ConstMap, - bool CloneVars) { + bool CloneVars, bool CloneBlocks) { if (InstCache.count(I)) return InstCache.at(I); @@ -1209,9 +1209,13 @@ Inst *souper::getInstCopy(Inst *I, InstContext &IC, } } else if (I->K == Inst::Phi) { if (!BlockCache.count(I->B)) { - auto BlockCopy = IC.createBlock(I->B->Preds); - BlockCache[I->B] = BlockCopy; - Copy = IC.getPhi(BlockCopy, Ops, I->DemandedBits); + if (CloneBlocks) { + auto BlockCopy = IC.createBlock(I->B->Preds); + BlockCache[I->B] = BlockCopy; + Copy = IC.getPhi(BlockCopy, Ops, I->DemandedBits); + } else { + Copy = IC.getPhi(I->B, Ops, I->DemandedBits); + } } else { Copy = IC.getPhi(BlockCache.at(I->B), Ops, I->DemandedBits); } diff --git a/lib/Pass/Pass.cpp b/lib/Pass/Pass.cpp index 997f5299e..121a0bbfa 100644 --- a/lib/Pass/Pass.cpp +++ b/lib/Pass/Pass.cpp @@ -18,8 +18,10 @@ #include "llvm/Analysis/DemandedBits.h" #include "llvm/Analysis/LazyValueInfo.h" #include "llvm/Analysis/LoopInfo.h" +#include "llvm/Analysis/PostDominators.h" #include "llvm/Analysis/ScalarEvolution.h" #include "llvm/Analysis/TargetLibraryInfo.h" +#include "llvm/CodeGen/UnreachableBlockElim.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" @@ -33,6 +35,7 @@ #include "llvm/IR/Verifier.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Support/CommandLine.h" +#include "llvm/Transforms/Scalar/ADCE.h" #include "llvm/Transforms/Scalar/DCE.h" #include "llvm/Transforms/IPO/PassManagerBuilder.h" #include "llvm/Transforms/Utils/BasicBlockUtils.h" @@ -233,6 +236,17 @@ struct SouperPass : public ModulePass { if (!TLI) report_fatal_error("getTLI() failed"); + // Run UnreachableBlockElim and ADCE locally + // TODO: In the long run, switch this tool to the new pass manager. + FunctionPassManager FM; + FunctionAnalysisManager FAM; + FAM.registerPass([&] { return PassInstrumentationAnalysis(); }); + FAM.registerPass([&] { return DominatorTreeAnalysis(); }); + FAM.registerPass([&] { return PostDominatorTreeAnalysis(); }); + FM.addPass(UnreachableBlockElimPass()); + FM.addPass(ADCEPass()); + FM.run(*F, FAM); + FunctionCandidateSet CS = ExtractCandidatesFromPass(F, LI, DB, LVI, SE, TLI, IC, EBC); if (DebugLevel > 3) @@ -277,7 +291,12 @@ struct SouperPass : public ModulePass { EC == std::errc::value_too_large) { continue; } else { - report_fatal_error("Unable to query solver: " + EC.message() + "\n"); + llvm::errs() << "[FIXME: Crash commented out]\nUnable to query solver: " + EC.message() + "\n"; + continue; + // TODO: This is a temporary workaround to suppress a protocol error which is encountered + // once in SPEC 2017. This workaround does not have a negative effect other than maybe + // missing one potential transformation. + //report_fatal_error("Unable to query solver: " + EC.message() + "\n"); } } if (RHSs.empty())