1//===-- SideEffectInterfaceBase.td - Side Effect Base ------*- tablegen -*-===// 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// This file contains base class definitions for side effect interfaces, i.e. 10// the customizable interfaces that provide information about which effects are 11// applied by an operation. 12// 13//===----------------------------------------------------------------------===// 14 15#ifndef MLIR_INTERFACES_SIDEEFFECTS_BASE 16#define MLIR_INTERFACES_SIDEEFFECTS_BASE 17 18include "mlir/IR/OpBase.td" 19 20//===----------------------------------------------------------------------===// 21// Resource Bindings 22//===----------------------------------------------------------------------===// 23 24// A generic resource that can be attached to a general base side effect. 25class Resource<string resourceName> { 26 /// The resource that the associated effect is being applied to. 27 string name = resourceName; 28} 29 30// An intrinsic resource that lives in the ::mlir::SideEffects namespace. 31class IntrinsicResource<string resourceName> : 32 Resource<!strconcat("::mlir::SideEffects::", resourceName)> { 33} 34 35// A link to the DefaultResource class. 36def DefaultResource : IntrinsicResource<"DefaultResource">; 37// A link to the AutomaticAllocationScopeResource class. 38def AutomaticAllocationScopeResource : 39 IntrinsicResource<"AutomaticAllocationScopeResource">; 40 41//===----------------------------------------------------------------------===// 42// EffectOpInterface 43//===----------------------------------------------------------------------===// 44 45// A base interface used to query information about the side effects applied to 46// an operation. This template class takes the name of the derived interface 47// class, as well as the name of the base effect class. 48class EffectOpInterfaceBase<string name, string baseEffect> 49 : OpInterface<name> { 50 let methods = [ 51 InterfaceMethod<[{ 52 Collects all of the operation's effects into `effects`. 53 }], 54 "void", "getEffects", 55 (ins "SmallVectorImpl<::mlir::SideEffects::EffectInstance<" 56 # baseEffect # ">> &":$effects) 57 >, 58 ]; 59 60 let extraClassDeclaration = [{ 61 /// Collect all of the effect instances that correspond to the given 62 /// `Effect` and place them in 'effects'. 63 template <typename Effect> void getEffects( 64 SmallVectorImpl<::mlir::SideEffects::EffectInstance< 65 }] # baseEffect # [{>> &effects) { 66 getEffects(effects); 67 llvm::erase_if(effects, [&](auto &it) { 68 return !llvm::isa<Effect>(it.getEffect()); 69 }); 70 } 71 72 /// Returns true if this operation exhibits the given effect. 73 template <typename Effect> bool hasEffect() { 74 SmallVector<SideEffects::EffectInstance<}] # baseEffect # [{>, 4> effects; 75 getEffects(effects); 76 return llvm::any_of(effects, [](const auto &it) { 77 return llvm::isa<Effect>(it.getEffect()); 78 }); 79 } 80 81 /// Returns true if this operation only has the given effect. 82 template <typename Effect> bool onlyHasEffect() { 83 SmallVector<SideEffects::EffectInstance<}] # baseEffect # [{>, 4> effects; 84 getEffects(effects); 85 return !effects.empty() && llvm::all_of(effects, [](const auto &it) { 86 return isa<Effect>(it.getEffect()); 87 }); 88 } 89 90 /// Returns true if this operation has no effects. 91 bool hasNoEffect() { 92 SmallVector<::mlir::SideEffects::EffectInstance<}] # baseEffect # [{>, 4> effects; 93 getEffects(effects); 94 return effects.empty(); 95 } 96 97 /// Returns true if the given operation has no effects for this interface. 98 static bool hasNoEffect(Operation *op) { 99 if (auto interface = dyn_cast<}] # name # [{>(op)) 100 return interface.hasNoEffect(); 101 return op->hasTrait<::mlir::OpTrait::HasRecursiveSideEffects>(); 102 } 103 104 /// Collect all of the effect instances that operate on the provided value 105 /// and place them in 'effects'. 106 void getEffectsOnValue(::mlir::Value value, 107 llvm::SmallVectorImpl<::mlir::SideEffects::EffectInstance< 108 }] # baseEffect # [{>> & effects) { 109 getEffects(effects); 110 llvm::erase_if(effects, [&](auto &it) { return it.getValue() != value; }); 111 } 112 113 /// Collect all of the effect instances that operate on the provided symbol 114 /// reference and place them in 'effects'. 115 void getEffectsOnSymbol(::mlir::SymbolRefAttr value, 116 llvm::SmallVectorImpl<::mlir::SideEffects::EffectInstance< 117 }] # baseEffect # [{>> & effects) { 118 getEffects(effects); 119 llvm::erase_if(effects, [&](auto &it) { 120 return it.getSymbolRef() != value; 121 }); 122 } 123 124 /// Collect all of the effect instances that operate on the provided 125 /// resource and place them in 'effects'. 126 void getEffectsOnResource(::mlir::SideEffects::Resource *resource, 127 llvm::SmallVectorImpl<::mlir::SideEffects::EffectInstance< 128 }] # baseEffect # [{>> & effects) { 129 getEffects(effects); 130 llvm::erase_if(effects, [&](auto &it) { 131 return it.getResource() != resource; 132 }); 133 } 134 }]; 135 136 // The base effect name of this interface. 137 string baseEffectName = baseEffect; 138} 139 140// This class is the general base side effect class. This is used by derived 141// effect interfaces to define their effects. 142class SideEffect<EffectOpInterfaceBase interface, string effectName, 143 Resource resourceReference> : OpVariableDecorator { 144 /// The name of the base effects class. 145 string baseEffectName = interface.baseEffectName; 146 147 /// The parent interface that the effect belongs to. 148 string interfaceTrait = interface.trait; 149 150 /// The cpp namespace of the interface trait. 151 string cppNamespace = interface.cppNamespace; 152 153 /// The derived effect that is being applied. 154 string effect = effectName; 155 156 /// The resource that the effect is being applied to. 157 string resource = resourceReference.name; 158} 159 160// This class is the base used for specifying effects applied to an operation. 161class SideEffectsTraitBase<EffectOpInterfaceBase parentInterface, 162 list<SideEffect> staticEffects> 163 : OpInterfaceTrait<""> { 164 /// The name of the interface trait to use. 165 let trait = parentInterface.trait; 166 167 /// The cpp namespace of the interface trait. 168 string cppNamespace = parentInterface.cppNamespace; 169 170 /// The name of the base effects class. 171 string baseEffectName = parentInterface.baseEffectName; 172 173 /// The derived effects being applied. 174 list<SideEffect> effects = staticEffects; 175} 176 177#endif // MLIR_INTERFACES_SIDEEFFECTS_BASE 178