diff --git a/include/phasar/Utils/LLVMShorthands.h b/include/phasar/Utils/LLVMShorthands.h index 01d211a6f2..958fb9b635 100644 --- a/include/phasar/Utils/LLVMShorthands.h +++ b/include/phasar/Utils/LLVMShorthands.h @@ -22,6 +22,7 @@ #include "llvm/IR/Function.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/ModuleSlotTracker.h" #include "llvm/IR/Value.h" #include "phasar/Utils/Utilities.h" @@ -216,6 +217,23 @@ bool isVarAnnotationIntrinsic(const llvm::Function *F); * */ llvm::StringRef getVarAnnotationIntrinsicName(const llvm::CallInst *CallInst); + +class ModulesToSlotTracker { + friend class ProjectIRDB; + friend class LLVMBasedICFG; + friend class LLVMZeroValue; + +private: + static inline llvm::SmallDenseMap, 2> + MToST; + + static void updateMSTForModule(const llvm::Module *); + static void deleteMSTForModule(const llvm::Module *); + +public: + static llvm::ModuleSlotTracker &getSlotTrackerForModule(const llvm::Module *); +}; } // namespace psr #endif diff --git a/lib/DB/ProjectIRDB.cpp b/lib/DB/ProjectIRDB.cpp index e6ac395d95..d3b8b8ad66 100644 --- a/lib/DB/ProjectIRDB.cpp +++ b/lib/DB/ProjectIRDB.cpp @@ -55,6 +55,7 @@ ProjectIRDB::ProjectIRDB(IRDBOptions Options) : Options(Options) { MPM.addPass(ValueAnnotationPass()); // just to be sure that none of the passes messed up the module! MPM.addPass(llvm::VerifierPass()); + ModulesToSlotTracker::updateMSTForModule(LLVMZeroValueMod.get()); } ProjectIRDB::ProjectIRDB(const std::vector &IRFiles, @@ -105,6 +106,9 @@ ProjectIRDB::ProjectIRDB(const std::vector &Modules, } ProjectIRDB::~ProjectIRDB() { + for (auto &[File, Module] : Modules) { + ModulesToSlotTracker::deleteMSTForModule(Module.get()); + } // release resources if IRDB does not own if (!(Options & IRDBOptions::OWNS)) { for (auto &Context : Contexts) { @@ -134,6 +138,7 @@ void ProjectIRDB::preprocessModule(llvm::Module *M) { RetOrResInstructions.insert(RRInsts.begin(), RRInsts.end()); STOP_TIMER("LLVM Passes", PAMM_SEVERITY_LEVEL::Full); buildIDModuleMapping(M); + ModulesToSlotTracker::updateMSTForModule(M); } void ProjectIRDB::linkForWPA() { @@ -199,6 +204,7 @@ void ProjectIRDB::linkForWPA() { // to link at all. But we have to update the WPAMOD pointer! WPAModule = Modules.begin()->second.get(); } + ModulesToSlotTracker::updateMSTForModule(WPAModule); } void ProjectIRDB::preprocessAllModules() { diff --git a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp index 304ba8ad1e..7358dae2d9 100644 --- a/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp +++ b/lib/PhasarLLVM/ControlFlow/LLVMBasedICFG.cpp @@ -669,10 +669,12 @@ LLVMBasedICFG::getReturnSitesOfCallAt(const llvm::Instruction *N) const { if (const auto *Invoke = llvm::dyn_cast(N)) { const llvm::Instruction *NormalSucc = &Invoke->getNormalDest()->front(); auto *UnwindSucc = &Invoke->getUnwindDest()->front(); - if (!IgnoreDbgInstructions && llvm::isa(NormalSucc)) { + if (!IgnoreDbgInstructions && + llvm::isa(NormalSucc)) { NormalSucc = NormalSucc->getNextNonDebugInstruction(); } - if (!IgnoreDbgInstructions && llvm::isa(UnwindSucc)) { + if (!IgnoreDbgInstructions && + llvm::isa(UnwindSucc)) { UnwindSucc = UnwindSucc->getNextNonDebugInstruction(); } if (NormalSucc != nullptr) { @@ -947,6 +949,8 @@ LLVMBasedICFG::buildCRuntimeGlobalCtorsDtorsModel(llvm::Module &M) { IRB.CreateRetVoid(); } + ModulesToSlotTracker::updateMSTForModule(&M); + return GlobModel; } diff --git a/lib/Utils/LLVMShorthands.cpp b/lib/Utils/LLVMShorthands.cpp index d3b9a803cc..f2cf2f15f6 100644 --- a/lib/Utils/LLVMShorthands.cpp +++ b/lib/Utils/LLVMShorthands.cpp @@ -140,18 +140,10 @@ bool matchesSignature(const llvm::FunctionType *FType1, return false; } -static llvm::ModuleSlotTracker &getModuleSlotTrackerFor(const llvm::Value *V) { - static llvm::SmallDenseMap, 2> - ModuleToSlotTracker; +llvm::ModuleSlotTracker &getModuleSlotTrackerFor(const llvm::Value *V) { const auto *M = getModuleFromVal(V); - auto &ret = ModuleToSlotTracker[M]; - if (!ret) { - ret = std::make_unique(M); - } - - return *ret; + return ModulesToSlotTracker::getSlotTrackerForModule(M); } std::string llvmIRToString(const llvm::Value *V) { @@ -437,4 +429,21 @@ llvm::StringRef getVarAnnotationIntrinsicName(const llvm::CallInst *CallInst) { return data->getAsCString(); } +llvm::ModuleSlotTracker & +ModulesToSlotTracker::getSlotTrackerForModule(const llvm::Module *M) { + auto &ret = MToST[M]; + if (M == nullptr && ret == nullptr) { + ret = std::make_unique(M); + } + assert(ret != nullptr && "no ModuleSlotTracker instance for module cached"); + return *ret; +} + +void ModulesToSlotTracker::updateMSTForModule(const llvm::Module *M) { + MToST[M] = std::make_unique(M); +} +void ModulesToSlotTracker::deleteMSTForModule(const llvm::Module *M) { + MToST.erase(M); +} + } // namespace psr