Please use GitHub pull requests for new patches. Phabricator shutdown timeline
Changeset View
Changeset View
Standalone View
Standalone View
llvm/unittests/IR/PassManagerTest.cpp
Show First 20 Lines • Show All 979 Lines • ▼ Show 20 Lines | TEST_F(PassManagerTest, FunctionPassMissedFunctionAnalysisInvalidation) { | ||||
FunctionAnalysisManager FAM; | FunctionAnalysisManager FAM; | ||||
ModuleAnalysisManager MAM; | ModuleAnalysisManager MAM; | ||||
PassInstrumentationCallbacks PIC; | PassInstrumentationCallbacks PIC; | ||||
StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ false); | StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ false); | ||||
SI.registerCallbacks(PIC, &MAM); | SI.registerCallbacks(PIC, &MAM); | ||||
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); | MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); | ||||
MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | ||||
FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | ||||
FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); | |||||
FunctionPassManager FPM; | FunctionPassManager FPM; | ||||
FPM.addPass(WrongFunctionPass()); | FPM.addPass(WrongFunctionPass()); | ||||
auto *F = M->getFunction("foo"); | auto *F = M->getFunction("foo"); | ||||
EXPECT_DEATH(FPM.run(*F, FAM), "Function @foo changed by WrongFunctionPass without invalidating analyses"); | EXPECT_DEATH(FPM.run(*F, FAM), "Function @foo changed by WrongFunctionPass without invalidating analyses"); | ||||
} | } | ||||
struct WrongModulePass : PassInfoMixin<WrongModulePass> { | struct WrongModulePass : PassInfoMixin<WrongModulePass> { | ||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) { | PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) { | ||||
for (Function &F : M) | for (Function &F : M) | ||||
F.getEntryBlock().begin()->eraseFromParent(); | F.getEntryBlock().begin()->eraseFromParent(); | ||||
return PreservedAnalyses::all(); | PreservedAnalyses PA; | ||||
PA.preserveSet<AllAnalysesOn<Function>>(); | |||||
PA.preserve<FunctionAnalysisManagerModuleProxy>(); | |||||
return PA; | |||||
} | } | ||||
static StringRef name() { return "WrongModulePass"; } | static StringRef name() { return "WrongModulePass"; } | ||||
}; | }; | ||||
TEST_F(PassManagerTest, ModulePassMissedFunctionAnalysisInvalidation) { | TEST_F(PassManagerTest, ModulePassMissedFunctionAnalysisInvalidation) { | ||||
LLVMContext Context; | LLVMContext Context; | ||||
auto M = parseIR(Context, "define void @foo() {\n" | auto M = parseIR(Context, "define void @foo() {\n" | ||||
" %a = add i32 0, 0\n" | " %a = add i32 0, 0\n" | ||||
" ret void\n" | " ret void\n" | ||||
"}\n"); | "}\n"); | ||||
FunctionAnalysisManager FAM; | FunctionAnalysisManager FAM; | ||||
ModuleAnalysisManager MAM; | ModuleAnalysisManager MAM; | ||||
PassInstrumentationCallbacks PIC; | PassInstrumentationCallbacks PIC; | ||||
StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ false); | StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ false); | ||||
SI.registerCallbacks(PIC, &MAM); | SI.registerCallbacks(PIC, &MAM); | ||||
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); | MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); | ||||
MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | ||||
FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | ||||
FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); | |||||
ModulePassManager MPM; | ModulePassManager MPM; | ||||
MPM.addPass(WrongModulePass()); | MPM.addPass(WrongModulePass()); | ||||
EXPECT_DEATH( | EXPECT_DEATH( | ||||
MPM.run(*M, MAM), | MPM.run(*M, MAM), | ||||
"Function @foo changed by WrongModulePass without invalidating analyses"); | "Function @foo changed by WrongModulePass without invalidating analyses"); | ||||
} | } | ||||
struct WrongModulePass2 : PassInfoMixin<WrongModulePass2> { | |||||
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM) { | |||||
for (Function &F : M) | |||||
F.getEntryBlock().begin()->eraseFromParent(); | |||||
PreservedAnalyses PA; | |||||
PA.preserveSet<AllAnalysesOn<Module>>(); | |||||
PA.abandon<FunctionAnalysisManagerModuleProxy>(); | |||||
return PA; | |||||
} | |||||
static StringRef name() { return "WrongModulePass2"; } | |||||
}; | |||||
TEST_F(PassManagerTest, ModulePassMissedModuleAnalysisInvalidation) { | |||||
LLVMContext Context; | |||||
auto M = parseIR(Context, "define void @foo() {\n" | |||||
" %a = add i32 0, 0\n" | |||||
" ret void\n" | |||||
"}\n"); | |||||
FunctionAnalysisManager FAM; | |||||
ModuleAnalysisManager MAM; | |||||
PassInstrumentationCallbacks PIC; | |||||
StandardInstrumentations SI(M->getContext(), /*DebugLogging*/ false); | |||||
SI.registerCallbacks(PIC, &MAM); | |||||
MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); }); | |||||
MAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | |||||
FAM.registerPass([&] { return PassInstrumentationAnalysis(&PIC); }); | |||||
FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); }); | |||||
ModulePassManager MPM; | |||||
MPM.addPass(WrongModulePass2()); | |||||
EXPECT_DEATH( | |||||
MPM.run(*M, MAM), | |||||
"Module changed by WrongModulePass2 without invalidating analyses"); | |||||
} | |||||
#endif | #endif | ||||
} | } |