Skip to content

Commit 5faa616

Browse files
committed
[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.
1 parent 7b330fa commit 5faa616

File tree

2 files changed

+8
-53
lines changed

2 files changed

+8
-53
lines changed

llvm/include/llvm/Transforms/IPO/Attributor.h

Lines changed: 3 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1231,10 +1231,8 @@ struct InformationCache {
12311231
InformationCache(const Module &M, AnalysisGetter &AG,
12321232
BumpPtrAllocator &Allocator, SetVector<Function *> *CGSCC,
12331233
bool UseExplorer = true)
1234-
: DL(M.getDataLayout()), Allocator(Allocator), AG(AG),
1234+
: CGSCC(CGSCC), DL(M.getDataLayout()), Allocator(Allocator), AG(AG),
12351235
TargetTriple(M.getTargetTriple()) {
1236-
if (CGSCC)
1237-
initializeModuleSlice(*CGSCC);
12381236
if (UseExplorer)
12391237
Explorer = new (Allocator) MustBeExecutedContextExplorer(
12401238
/* ExploreInterBlock */ true, /* ExploreCFGForward */ true,
@@ -1286,46 +1284,8 @@ struct InformationCache {
12861284
}
12871285
}
12881286

1289-
/// Initialize the ModuleSlice member based on \p SCC. ModuleSlices contains
1290-
/// (a subset of) all functions that we can look at during this SCC traversal.
1291-
/// This includes functions (transitively) called from the SCC and the
1292-
/// (transitive) callers of SCC functions. We also can look at a function if
1293-
/// there is a "reference edge", i.a., if the function somehow uses (!=calls)
1294-
/// a function in the SCC or a caller of a function in the SCC.
1295-
void initializeModuleSlice(SetVector<Function *> &SCC) {
1296-
ModuleSlice.insert(SCC.begin(), SCC.end());
1297-
1298-
SmallPtrSet<Function *, 16> Seen;
1299-
SmallVector<Function *, 16> Worklist(SCC.begin(), SCC.end());
1300-
while (!Worklist.empty()) {
1301-
Function *F = Worklist.pop_back_val();
1302-
ModuleSlice.insert(F);
1303-
1304-
for (Instruction &I : instructions(*F))
1305-
if (auto *CB = dyn_cast<CallBase>(&I))
1306-
if (auto *Callee =
1307-
dyn_cast_if_present<Function>(CB->getCalledOperand()))
1308-
if (Seen.insert(Callee).second)
1309-
Worklist.push_back(Callee);
1310-
}
1311-
1312-
Seen.clear();
1313-
Worklist.append(SCC.begin(), SCC.end());
1314-
while (!Worklist.empty()) {
1315-
Function *F = Worklist.pop_back_val();
1316-
ModuleSlice.insert(F);
1317-
1318-
// Traverse all transitive uses.
1319-
foreachUse(*F, [&](Use &U) {
1320-
if (auto *UsrI = dyn_cast<Instruction>(U.getUser()))
1321-
if (Seen.insert(UsrI->getFunction()).second)
1322-
Worklist.push_back(UsrI->getFunction());
1323-
});
1324-
}
1325-
}
1326-
1327-
/// The slice of the module we are allowed to look at.
1328-
SmallPtrSet<Function *, 8> ModuleSlice;
1287+
/// The CG-SCC the pass is run on, or nullptr if it is a module pass.
1288+
const SetVector<Function *> *const CGSCC = nullptr;
13291289

13301290
/// A vector type to hold instructions.
13311291
using InstructionVectorTy = SmallVector<Instruction *, 8>;
@@ -1391,11 +1351,6 @@ struct InformationCache {
13911351
return UniqueBES;
13921352
}
13931353

1394-
/// Check whether \p F is part of module slice.
1395-
bool isInModuleSlice(const Function &F) {
1396-
return ModuleSlice.empty() || ModuleSlice.count(const_cast<Function *>(&F));
1397-
}
1398-
13991354
/// Return true if the stack (llvm::Alloca) can be accessed by other threads.
14001355
bool stackIsAccessibleByOtherThreads() { return !targetIsGPU(); }
14011356

llvm/lib/Transforms/IPO/OpenMPOpt.cpp

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -421,7 +421,7 @@ struct OMPInformationCache : public InformationCache {
421421
// TODO: We directly convert uses into proper calls and unknown uses.
422422
for (Use &U : RFI.Declaration->uses()) {
423423
if (Instruction *UserI = dyn_cast<Instruction>(U.getUser())) {
424-
if (ModuleSlice.empty() || ModuleSlice.count(UserI->getFunction())) {
424+
if (!CGSCC || CGSCC->empty() || CGSCC->contains(UserI->getFunction())) {
425425
RFI.getOrCreateUseVector(UserI->getFunction()).push_back(&U);
426426
++NumUses;
427427
}
@@ -830,16 +830,15 @@ struct OpenMPOpt {
830830
return Ctx.getDiagHandlerPtr()->isAnyRemarkEnabled(DEBUG_TYPE);
831831
}
832832

833-
/// Run all OpenMP optimizations on the underlying SCC/ModuleSlice.
833+
/// Run all OpenMP optimizations on the underlying SCC.
834834
bool run(bool IsModulePass) {
835835
if (SCC.empty())
836836
return false;
837837

838838
bool Changed = false;
839839

840840
LLVM_DEBUG(dbgs() << TAG << "Run on SCC with " << SCC.size()
841-
<< " functions in a slice with "
842-
<< OMPInfoCache.ModuleSlice.size() << " functions\n");
841+
<< " functions\n");
843842

844843
if (IsModulePass) {
845844
Changed |= runAttributor(IsModulePass);
@@ -1932,7 +1931,8 @@ struct OpenMPOpt {
19321931
};
19331932

19341933
Kernel OpenMPOpt::getUniqueKernelFor(Function &F) {
1935-
if (!OMPInfoCache.ModuleSlice.empty() && !OMPInfoCache.ModuleSlice.count(&F))
1934+
if (OMPInfoCache.CGSCC && !OMPInfoCache.CGSCC->empty() &&
1935+
!OMPInfoCache.CGSCC->contains(&F))
19361936
return nullptr;
19371937

19381938
// Use a scope to keep the lifetime of the CachedKernel short.

0 commit comments

Comments
 (0)