1 //===- AnalysisManagerTest.cpp - AnalysisManager unit 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 "mlir/Pass/AnalysisManager.h" 10 #include "mlir/IR/Builders.h" 11 #include "mlir/IR/Function.h" 12 #include "gtest/gtest.h" 13 14 using namespace mlir; 15 using namespace mlir::detail; 16 17 namespace { 18 /// Minimal class definitions for two analyses. 19 struct MyAnalysis { 20 MyAnalysis(Operation *) {} 21 }; 22 struct OtherAnalysis { 23 OtherAnalysis(Operation *) {} 24 }; 25 26 TEST(AnalysisManagerTest, FineGrainModuleAnalysisPreservation) { 27 MLIRContext context; 28 29 // Test fine grain invalidation of the module analysis manager. 30 OwningModuleRef module(ModuleOp::create(UnknownLoc::get(&context))); 31 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr); 32 AnalysisManager am = mam; 33 34 // Query two different analyses, but only preserve one before invalidating. 35 am.getAnalysis<MyAnalysis>(); 36 am.getAnalysis<OtherAnalysis>(); 37 38 detail::PreservedAnalyses pa; 39 pa.preserve<MyAnalysis>(); 40 am.invalidate(pa); 41 42 // Check that only MyAnalysis is preserved. 43 EXPECT_TRUE(am.getCachedAnalysis<MyAnalysis>().hasValue()); 44 EXPECT_FALSE(am.getCachedAnalysis<OtherAnalysis>().hasValue()); 45 } 46 47 TEST(AnalysisManagerTest, FineGrainFunctionAnalysisPreservation) { 48 MLIRContext context; 49 Builder builder(&context); 50 51 // Create a function and a module. 52 OwningModuleRef module(ModuleOp::create(UnknownLoc::get(&context))); 53 FuncOp func1 = 54 FuncOp::create(builder.getUnknownLoc(), "foo", 55 builder.getFunctionType(llvm::None, llvm::None)); 56 module->push_back(func1); 57 58 // Test fine grain invalidation of the function analysis manager. 59 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr); 60 AnalysisManager am = mam; 61 AnalysisManager fam = am.slice(func1); 62 63 // Query two different analyses, but only preserve one before invalidating. 64 fam.getAnalysis<MyAnalysis>(); 65 fam.getAnalysis<OtherAnalysis>(); 66 67 detail::PreservedAnalyses pa; 68 pa.preserve<MyAnalysis>(); 69 fam.invalidate(pa); 70 71 // Check that only MyAnalysis is preserved. 72 EXPECT_TRUE(fam.getCachedAnalysis<MyAnalysis>().hasValue()); 73 EXPECT_FALSE(fam.getCachedAnalysis<OtherAnalysis>().hasValue()); 74 } 75 76 TEST(AnalysisManagerTest, FineGrainChildFunctionAnalysisPreservation) { 77 MLIRContext context; 78 Builder builder(&context); 79 80 // Create a function and a module. 81 OwningModuleRef module(ModuleOp::create(UnknownLoc::get(&context))); 82 FuncOp func1 = 83 FuncOp::create(builder.getUnknownLoc(), "foo", 84 builder.getFunctionType(llvm::None, llvm::None)); 85 module->push_back(func1); 86 87 // Test fine grain invalidation of a function analysis from within a module 88 // analysis manager. 89 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr); 90 AnalysisManager am = mam; 91 92 // Check that the analysis cache is initially empty. 93 EXPECT_FALSE(am.getCachedChildAnalysis<MyAnalysis>(func1).hasValue()); 94 95 // Query two different analyses, but only preserve one before invalidating. 96 am.getChildAnalysis<MyAnalysis>(func1); 97 am.getChildAnalysis<OtherAnalysis>(func1); 98 99 detail::PreservedAnalyses pa; 100 pa.preserve<MyAnalysis>(); 101 am.invalidate(pa); 102 103 // Check that only MyAnalysis is preserved. 104 EXPECT_TRUE(am.getCachedChildAnalysis<MyAnalysis>(func1).hasValue()); 105 EXPECT_FALSE(am.getCachedChildAnalysis<OtherAnalysis>(func1).hasValue()); 106 } 107 108 /// Test analyses with custom invalidation logic. 109 struct TestAnalysisSet {}; 110 111 struct CustomInvalidatingAnalysis { 112 CustomInvalidatingAnalysis(Operation *) {} 113 114 bool isInvalidated(const AnalysisManager::PreservedAnalyses &pa) { 115 return !pa.isPreserved<TestAnalysisSet>(); 116 } 117 }; 118 119 TEST(AnalysisManagerTest, CustomInvalidation) { 120 MLIRContext context; 121 Builder builder(&context); 122 123 // Create a function and a module. 124 OwningModuleRef module(ModuleOp::create(UnknownLoc::get(&context))); 125 ModuleAnalysisManager mam(*module, /*passInstrumentor=*/nullptr); 126 AnalysisManager am = mam; 127 128 detail::PreservedAnalyses pa; 129 130 // Check that the analysis is invalidated properly. 131 am.getAnalysis<CustomInvalidatingAnalysis>(); 132 am.invalidate(pa); 133 EXPECT_FALSE(am.getCachedAnalysis<CustomInvalidatingAnalysis>().hasValue()); 134 135 // Check that the analysis is preserved properly. 136 am.getAnalysis<CustomInvalidatingAnalysis>(); 137 pa.preserve<TestAnalysisSet>(); 138 am.invalidate(pa); 139 EXPECT_TRUE(am.getCachedAnalysis<CustomInvalidatingAnalysis>().hasValue()); 140 } 141 } // end namespace 142