1 //===- TestSidEffects.cpp - Pass to test side effects ---------------------===// 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 "TestOps.h" 10 #include "mlir/Pass/Pass.h" 11 12 using namespace mlir; 13 14 namespace { 15 struct SideEffectsPass 16 : public PassWrapper<SideEffectsPass, OperationPass<ModuleOp>> { MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID__anon269fbb1a0111::SideEffectsPass17 MLIR_DEFINE_EXPLICIT_INTERNAL_INLINE_TYPE_ID(SideEffectsPass) 18 19 StringRef getArgument() const final { return "test-side-effects"; } getDescription__anon269fbb1a0111::SideEffectsPass20 StringRef getDescription() const final { 21 return "Test side effects interfaces"; 22 } runOnOperation__anon269fbb1a0111::SideEffectsPass23 void runOnOperation() override { 24 auto module = getOperation(); 25 26 // Walk operations detecting side effects. 27 SmallVector<MemoryEffects::EffectInstance, 8> effects; 28 module.walk([&](MemoryEffectOpInterface op) { 29 effects.clear(); 30 op.getEffects(effects); 31 32 if (op->hasTrait<OpTrait::IsTerminator>()) { 33 return; 34 } 35 36 // Check to see if this operation has any memory effects. 37 if (effects.empty()) { 38 op.emitRemark() << "operation has no memory effects"; 39 return; 40 } 41 42 for (MemoryEffects::EffectInstance instance : effects) { 43 auto diag = op.emitRemark() << "found an instance of "; 44 45 if (isa<MemoryEffects::Allocate>(instance.getEffect())) 46 diag << "'allocate'"; 47 else if (isa<MemoryEffects::Free>(instance.getEffect())) 48 diag << "'free'"; 49 else if (isa<MemoryEffects::Read>(instance.getEffect())) 50 diag << "'read'"; 51 else if (isa<MemoryEffects::Write>(instance.getEffect())) 52 diag << "'write'"; 53 54 if (instance.getValue()) { 55 if (instance.getEffectValue<OpOperand *>()) 56 diag << " on a op operand,"; 57 else if (instance.getEffectValue<OpResult>()) 58 diag << " on a op result,"; 59 else if (instance.getEffectValue<BlockArgument>()) 60 diag << " on a block argument,"; 61 } else if (SymbolRefAttr symbolRef = instance.getSymbolRef()) 62 diag << " on a symbol '" << symbolRef << "',"; 63 64 diag << " on resource '" << instance.getResource()->getName() << "'"; 65 } 66 }); 67 68 SmallVector<TestEffects::EffectInstance, 1> testEffects; 69 module.walk([&](TestEffectOpInterface op) { 70 testEffects.clear(); 71 op.getEffects(testEffects); 72 73 if (testEffects.empty()) 74 return; 75 76 for (const TestEffects::EffectInstance &instance : testEffects) { 77 op.emitRemark() << "found a parametric effect with " 78 << instance.getParameters(); 79 } 80 }); 81 } 82 }; 83 } // namespace 84 85 namespace mlir { registerSideEffectTestPasses()86void registerSideEffectTestPasses() { PassRegistration<SideEffectsPass>(); } 87 } // namespace mlir 88