Skip to content

Commit 4e78c9c

Browse files
committed
[Analysis] Add unittests
1 parent a887d24 commit 4e78c9c

File tree

2 files changed

+118
-0
lines changed

2 files changed

+118
-0
lines changed

llvm/unittests/Analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ set(ANALYSIS_TEST_SOURCES
3333
InlineCostTest.cpp
3434
IRSimilarityIdentifierTest.cpp
3535
IVDescriptorsTest.cpp
36+
LastRunTrackingAnalysisTest.cpp
3637
LazyCallGraphTest.cpp
3738
LoadsTest.cpp
3839
LoopInfoTest.cpp
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
//===--- LastRunTrackingAnalysisTest.cpp - LastRunTrackingAnalysis tests---===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#include "llvm/Analysis/LastRunTrackingAnalysis.h"
10+
#include "llvm/IR/LLVMContext.h"
11+
#include "llvm/IR/Module.h"
12+
#include "llvm/Passes/PassBuilder.h"
13+
#include "gtest/gtest.h"
14+
15+
namespace {
16+
17+
using namespace llvm;
18+
19+
class LastRunTrackingAnalysisTest : public testing::Test {
20+
protected:
21+
LLVMContext C;
22+
Module M;
23+
PassBuilder PB;
24+
25+
LoopAnalysisManager LAM;
26+
FunctionAnalysisManager FAM;
27+
CGSCCAnalysisManager CGAM;
28+
ModulePassManager MPM;
29+
ModuleAnalysisManager MAM;
30+
31+
LastRunTrackingAnalysisTest() : M("LastRunTrackingAnalysisTest", C) {
32+
PB.registerModuleAnalyses(MAM);
33+
PB.registerCGSCCAnalyses(CGAM);
34+
PB.registerFunctionAnalyses(FAM);
35+
PB.registerLoopAnalyses(LAM);
36+
PB.crossRegisterProxies(LAM, FAM, CGAM, MAM);
37+
}
38+
};
39+
40+
struct PassOption final {
41+
uint32_t Threshold;
42+
43+
/// Assume that this pass doesn't make changes with threshold A if we already
44+
/// know it doesn't make changes with a larger threshold B.
45+
bool isCompatibleWith(const PassOption &LastOpt) const {
46+
return Threshold <= LastOpt.Threshold;
47+
}
48+
};
49+
50+
class ModuleNoopPass : public PassInfoMixin<ModuleNoopPass> {
51+
uint32_t &ExecutedBitMap;
52+
uint32_t RunID;
53+
void *PassID;
54+
bool ShouldChange;
55+
std::optional<PassOption> Option;
56+
57+
bool shouldSkip(LastRunTrackingInfo &LRT) {
58+
if (Option.has_value())
59+
return LRT.shouldSkip(PassID, *Option);
60+
return LRT.shouldSkip(PassID);
61+
}
62+
63+
void update(LastRunTrackingInfo &LRT) {
64+
if (Option.has_value())
65+
return LRT.update(PassID, ShouldChange, *Option);
66+
return LRT.update(PassID, ShouldChange);
67+
}
68+
69+
public:
70+
explicit ModuleNoopPass(uint32_t &ExecutedBitMapRef, uint32_t RunIDVal,
71+
void *PassIDVal, bool ShouldChangeVal,
72+
std::optional<PassOption> OptionVal = std::nullopt)
73+
: ExecutedBitMap(ExecutedBitMapRef), RunID(RunIDVal), PassID(PassIDVal),
74+
ShouldChange(ShouldChangeVal), Option(OptionVal) {}
75+
76+
PreservedAnalyses run(Module &F, ModuleAnalysisManager &AM) {
77+
auto &LRT = AM.getResult<LastRunTrackingAnalysis>(F);
78+
if (shouldSkip(LRT)) {
79+
EXPECT_FALSE(ShouldChange) << "This pass is incorrectly skipped.";
80+
return PreservedAnalyses::all();
81+
}
82+
ExecutedBitMap |= 1U << RunID;
83+
update(LRT);
84+
PreservedAnalyses PA;
85+
PA.preserve<LastRunTrackingAnalysis>();
86+
return PA;
87+
}
88+
};
89+
90+
static char PassA, PassB;
91+
92+
TEST_F(LastRunTrackingAnalysisTest, SkipTest) {
93+
uint32_t BitMap = 0;
94+
// Executed. This is first run of PassA.
95+
MPM.addPass(ModuleNoopPass(BitMap, 0, &PassA, true));
96+
// Skipped since PassA has just been executed.
97+
MPM.addPass(ModuleNoopPass(BitMap, 1, &PassA, false));
98+
// Skipped since PassA has just been executed.
99+
MPM.addPass(ModuleNoopPass(BitMap, 2, &PassA, false));
100+
// Executed. This is first run of PassB.
101+
MPM.addPass(ModuleNoopPass(BitMap, 3, &PassB, false, PassOption{2}));
102+
// Skipped. PassB doesn't make changes with lower threshold.
103+
MPM.addPass(ModuleNoopPass(BitMap, 4, &PassB, false, PassOption{1}));
104+
// Executed. PassB may make changes with higher threshold.
105+
MPM.addPass(ModuleNoopPass(BitMap, 5, &PassB, false, PassOption{3}));
106+
// Skipped. We don't make changes since last run of PassA.
107+
MPM.addPass(ModuleNoopPass(BitMap, 6, &PassA, false));
108+
// Executed. PassB may make changes with higher threshold.
109+
MPM.addPass(ModuleNoopPass(BitMap, 7, &PassB, true, PassOption{4}));
110+
// Executed. This module has been modified by PassB.
111+
MPM.addPass(ModuleNoopPass(BitMap, 8, &PassA, false));
112+
MPM.run(M, MAM);
113+
114+
ASSERT_EQ(BitMap, 0b110101001);
115+
}
116+
117+
} // namespace

0 commit comments

Comments
 (0)