From 5faa616fe4bdfd3f18ba168ee85b164783a0bb3c Mon Sep 17 00:00:00 2001 From: Johannes Doerfert Date: Thu, 29 Jun 2023 22:07:14 -0700 Subject: [PATCH] [Attributor][NFCI] Remove the (already "unused") ModuleSlice At some point we alloed the CGSCC traversal to look at the entire module slice (see definition below). However, we don't allow that anymore, mostly for compile time and complexity reasons. Consequently, there is no need to build the ModuleSlice as we can replacve it with the SCC wherever it was still used. --- llvm/include/llvm/Transforms/IPO/Attributor.h | 51 ++------------------------- llvm/lib/Transforms/IPO/OpenMPOpt.cpp | 10 +++--- 2 files changed, 8 insertions(+), 53 deletions(-) diff --git a/llvm/include/llvm/Transforms/IPO/Attributor.h b/llvm/include/llvm/Transforms/IPO/Attributor.h index 538b2a1..9f9a0fe 100644 --- a/llvm/include/llvm/Transforms/IPO/Attributor.h +++ b/llvm/include/llvm/Transforms/IPO/Attributor.h @@ -1231,10 +1231,8 @@ struct InformationCache { InformationCache(const Module &M, AnalysisGetter &AG, BumpPtrAllocator &Allocator, SetVector *CGSCC, bool UseExplorer = true) - : DL(M.getDataLayout()), Allocator(Allocator), AG(AG), + : CGSCC(CGSCC), DL(M.getDataLayout()), Allocator(Allocator), AG(AG), TargetTriple(M.getTargetTriple()) { - if (CGSCC) - initializeModuleSlice(*CGSCC); if (UseExplorer) Explorer = new (Allocator) MustBeExecutedContextExplorer( /* ExploreInterBlock */ true, /* ExploreCFGForward */ true, @@ -1286,46 +1284,8 @@ struct InformationCache { } } - /// Initialize the ModuleSlice member based on \p SCC. ModuleSlices contains - /// (a subset of) all functions that we can look at during this SCC traversal. - /// This includes functions (transitively) called from the SCC and the - /// (transitive) callers of SCC functions. We also can look at a function if - /// there is a "reference edge", i.a., if the function somehow uses (!=calls) - /// a function in the SCC or a caller of a function in the SCC. - void initializeModuleSlice(SetVector &SCC) { - ModuleSlice.insert(SCC.begin(), SCC.end()); - - SmallPtrSet Seen; - SmallVector Worklist(SCC.begin(), SCC.end()); - while (!Worklist.empty()) { - Function *F = Worklist.pop_back_val(); - ModuleSlice.insert(F); - - for (Instruction &I : instructions(*F)) - if (auto *CB = dyn_cast(&I)) - if (auto *Callee = - dyn_cast_if_present(CB->getCalledOperand())) - if (Seen.insert(Callee).second) - Worklist.push_back(Callee); - } - - Seen.clear(); - Worklist.append(SCC.begin(), SCC.end()); - while (!Worklist.empty()) { - Function *F = Worklist.pop_back_val(); - ModuleSlice.insert(F); - - // Traverse all transitive uses. - foreachUse(*F, [&](Use &U) { - if (auto *UsrI = dyn_cast(U.getUser())) - if (Seen.insert(UsrI->getFunction()).second) - Worklist.push_back(UsrI->getFunction()); - }); - } - } - - /// The slice of the module we are allowed to look at. - SmallPtrSet ModuleSlice; + /// The CG-SCC the pass is run on, or nullptr if it is a module pass. + const SetVector *const CGSCC = nullptr; /// A vector type to hold instructions. using InstructionVectorTy = SmallVector; @@ -1391,11 +1351,6 @@ struct InformationCache { return UniqueBES; } - /// Check whether \p F is part of module slice. - bool isInModuleSlice(const Function &F) { - return ModuleSlice.empty() || ModuleSlice.count(const_cast(&F)); - } - /// Return true if the stack (llvm::Alloca) can be accessed by other threads. bool stackIsAccessibleByOtherThreads() { return !targetIsGPU(); } diff --git a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp index 70adee5..e1b4b1f 100644 --- a/llvm/lib/Transforms/IPO/OpenMPOpt.cpp +++ b/llvm/lib/Transforms/IPO/OpenMPOpt.cpp @@ -421,7 +421,7 @@ struct OMPInformationCache : public InformationCache { // TODO: We directly convert uses into proper calls and unknown uses. for (Use &U : RFI.Declaration->uses()) { if (Instruction *UserI = dyn_cast(U.getUser())) { - if (ModuleSlice.empty() || ModuleSlice.count(UserI->getFunction())) { + if (!CGSCC || CGSCC->empty() || CGSCC->contains(UserI->getFunction())) { RFI.getOrCreateUseVector(UserI->getFunction()).push_back(&U); ++NumUses; } @@ -830,7 +830,7 @@ struct OpenMPOpt { return Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(DEBUG_TYPE); } - /// Run all OpenMP optimizations on the underlying SCC/ModuleSlice. + /// Run all OpenMP optimizations on the underlying SCC. bool run(bool IsModulePass) { if (SCC.empty()) return false; @@ -838,8 +838,7 @@ struct OpenMPOpt { bool Changed = false; LLVM_DEBUG(dbgs() << TAG << "Run on SCC with " << SCC.size() - << " functions in a slice with " - << OMPInfoCache.ModuleSlice.size() << " functions\n"); + << " functions\n"); if (IsModulePass) { Changed |= runAttributor(IsModulePass); @@ -1932,7 +1931,8 @@ public: }; Kernel OpenMPOpt::getUniqueKernelFor(Function &F) { - if (!OMPInfoCache.ModuleSlice.empty() && !OMPInfoCache.ModuleSlice.count(&F)) + if (OMPInfoCache.CGSCC && !OMPInfoCache.CGSCC->empty() && + !OMPInfoCache.CGSCC->contains(&F)) return nullptr; // Use a scope to keep the lifetime of the CachedKernel short. -- 2.7.4