Skip to content

Commit 985b9b7

Browse files
committed
[PM] Avoid duplicates in the Used/Preserved/Required sets
The pass analysis uses "sets" implemented using a SmallVector type to keep track of Used, Preserved, Required and RequiredTransitive passes. When having nested analyses we could end up with duplicates in those sets, as there was no checks to see if a pass already existed in the "set" before pushing to the vectors. This idea with this patch is to avoid such duplicates by avoiding pushing elements that already is contained when adding elements to those sets. To align with the above PMDataManager::collectRequiredAndUsedAnalyses is changed to skip adding both the Required and RequiredTransitive passes to its result vectors (since RequiredTransitive always is a subset of Required we ended up with duplicates when traversing both sets). Main goal with this is to avoid spending time verifying the same analysis mulitple times in PMDataManager::verifyPreservedAnalysis when iterating over the Preserved "set". It is assumed that removing duplicates from a "set" shouldn't have any other negative impact (I have not seen any problems so far). If this ends up causing problems one could do some uniqueness filtering of the vector being traversed in verifyPreservedAnalysis instead. Reviewed By: foad Differential Revision: https://reviews.llvm.org/D94416
1 parent 42830f8 commit 985b9b7

File tree

3 files changed

+19
-18
lines changed

3 files changed

+19
-18
lines changed

llvm/include/llvm/PassAnalysisSupport.h

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,12 @@
1717

1818
#if !defined(LLVM_PASS_H) || defined(LLVM_PASSANALYSISSUPPORT_H)
1919
#error "Do not include <PassAnalysisSupport.h>; include <Pass.h> instead"
20-
#endif
20+
#endif
2121

2222
#ifndef LLVM_PASSANALYSISSUPPORT_H
2323
#define LLVM_PASSANALYSISSUPPORT_H
2424

25+
#include "llvm/ADT/STLExtras.h"
2526
#include "llvm/ADT/SmallVector.h"
2627
#include <cassert>
2728
#include <tuple>
@@ -58,6 +59,11 @@ class AnalysisUsage {
5859
SmallVector<AnalysisID, 0> Used;
5960
bool PreservesAll = false;
6061

62+
void pushUnique(VectorType &Set, AnalysisID ID) {
63+
if (!llvm::is_contained(Set, ID))
64+
Set.push_back(ID);
65+
}
66+
6167
public:
6268
AnalysisUsage() = default;
6369

@@ -80,17 +86,17 @@ class AnalysisUsage {
8086
///@{
8187
/// Add the specified ID to the set of analyses preserved by this pass.
8288
AnalysisUsage &addPreservedID(const void *ID) {
83-
Preserved.push_back(ID);
89+
pushUnique(Preserved, ID);
8490
return *this;
8591
}
8692
AnalysisUsage &addPreservedID(char &ID) {
87-
Preserved.push_back(&ID);
93+
pushUnique(Preserved, &ID);
8894
return *this;
8995
}
9096
/// Add the specified Pass class to the set of analyses preserved by this pass.
9197
template<class PassClass>
9298
AnalysisUsage &addPreserved() {
93-
Preserved.push_back(&PassClass::ID);
99+
pushUnique(Preserved, &PassClass::ID);
94100
return *this;
95101
}
96102
///@}
@@ -99,17 +105,17 @@ class AnalysisUsage {
99105
/// Add the specified ID to the set of analyses used by this pass if they are
100106
/// available..
101107
AnalysisUsage &addUsedIfAvailableID(const void *ID) {
102-
Used.push_back(ID);
108+
pushUnique(Used, ID);
103109
return *this;
104110
}
105111
AnalysisUsage &addUsedIfAvailableID(char &ID) {
106-
Used.push_back(&ID);
112+
pushUnique(Used, &ID);
107113
return *this;
108114
}
109115
/// Add the specified Pass class to the set of analyses used by this pass.
110116
template<class PassClass>
111117
AnalysisUsage &addUsedIfAvailable() {
112-
Used.push_back(&PassClass::ID);
118+
pushUnique(Used, &PassClass::ID);
113119
return *this;
114120
}
115121
///@}

llvm/lib/IR/LegacyPassManager.cpp

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,12 +1110,6 @@ void PMDataManager::collectRequiredAndUsedAnalyses(
11101110
UP.push_back(AnalysisPass);
11111111
else
11121112
RP_NotAvail.push_back(RequiredID);
1113-
1114-
for (const auto &RequiredID : AnUsage->getRequiredTransitiveSet())
1115-
if (Pass *AnalysisPass = findAnalysisPass(RequiredID, true))
1116-
UP.push_back(AnalysisPass);
1117-
else
1118-
RP_NotAvail.push_back(RequiredID);
11191113
}
11201114

11211115
// All Required analyses should be available to the pass as it runs! Here

llvm/lib/IR/Pass.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -259,22 +259,23 @@ void AnalysisUsage::setPreservesCFG() {
259259
AnalysisUsage &AnalysisUsage::addPreserved(StringRef Arg) {
260260
const PassInfo *PI = Pass::lookupPassInfo(Arg);
261261
// If the pass exists, preserve it. Otherwise silently do nothing.
262-
if (PI) Preserved.push_back(PI->getTypeInfo());
262+
if (PI)
263+
pushUnique(Preserved, PI->getTypeInfo());
263264
return *this;
264265
}
265266

266267
AnalysisUsage &AnalysisUsage::addRequiredID(const void *ID) {
267-
Required.push_back(ID);
268+
pushUnique(Required, ID);
268269
return *this;
269270
}
270271

271272
AnalysisUsage &AnalysisUsage::addRequiredID(char &ID) {
272-
Required.push_back(&ID);
273+
pushUnique(Required, &ID);
273274
return *this;
274275
}
275276

276277
AnalysisUsage &AnalysisUsage::addRequiredTransitiveID(char &ID) {
277-
Required.push_back(&ID);
278-
RequiredTransitive.push_back(&ID);
278+
pushUnique(Required, &ID);
279+
pushUnique(RequiredTransitive, &ID);
279280
return *this;
280281
}

0 commit comments

Comments
 (0)