xref: /llvm-project/mlir/include/mlir/Interfaces/SideEffectInterfaces.td (revision 0c63122713c2d719789aef4bdfaf4e0b29c3b79e)
1//===-- SideEffectInterfaces.td - Side Effect Interfaces ---*- 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 a set of interfaces that can be used to define information
10// about what effects are applied by an operation.
11//
12//===----------------------------------------------------------------------===//
13
14#ifndef MLIR_INTERFACES_SIDEEFFECTS
15#define MLIR_INTERFACES_SIDEEFFECTS
16
17include "mlir/Interfaces/SideEffectInterfaceBase.td"
18
19//===----------------------------------------------------------------------===//
20// MemoryEffects
21//===----------------------------------------------------------------------===//
22
23// This def represents the definition for the memory effects interface. Users
24// should generally not use this directly, and should instead use
25// `MemoryEffects`.
26def MemoryEffectsOpInterface
27    : EffectOpInterfaceBase<"MemoryEffectOpInterface",
28                            "::mlir::MemoryEffects::Effect"> {
29  let description = [{
30    An interface used to query information about the memory effects applied by
31    an operation.
32  }];
33  let cppNamespace = "::mlir";
34}
35
36// The base class for defining specific memory effects.
37class MemoryEffect<string effectName, Resource resource, int stage,
38                   EffectRange range>
39  : SideEffect<MemoryEffectsOpInterface, effectName, resource, stage, range>;
40
41// This class represents the trait for memory effects that may be placed on
42// operations.
43class MemoryEffects<list<MemoryEffect> effects = []>
44  : SideEffectsTraitBase<MemoryEffectsOpInterface, effects>;
45
46//===----------------------------------------------------------------------===//
47// Effects
48
49// The following effect indicates that the operation allocates from some
50// resource. An 'allocate' effect implies only allocation of the resource, and
51// not any visible mutation or dereference.
52class MemAlloc<Resource resource, int stage = 0,
53               EffectRange range = PartialEffect>
54  : MemoryEffect<"::mlir::MemoryEffects::Allocate", resource, stage, range>;
55def MemAlloc : MemAlloc<DefaultResource, 0, PartialEffect>;
56class MemAllocAt<int stage, EffectRange range = PartialEffect>
57  : MemAlloc<DefaultResource, stage, range>;
58
59// The following effect indicates that the operation frees some resource that
60// has been allocated. A 'free' effect implies only de-allocation of the
61// resource, and not any visible allocation, mutation or dereference.
62class MemFree<Resource resource, int stage = 0,
63              EffectRange range = PartialEffect>
64  : MemoryEffect<"::mlir::MemoryEffects::Free", resource, stage, range>;
65def MemFree : MemFree<DefaultResource, 0, PartialEffect>;
66class MemFreeAt<int stage, EffectRange range = PartialEffect>
67  : MemFree<DefaultResource, stage, range>;
68
69// The following effect indicates that the operation reads from some
70// resource. A 'read' effect implies only dereferencing of the resource, and
71// not any visible mutation.
72class MemRead<Resource resource, int stage = 0,
73              EffectRange range = PartialEffect>
74  : MemoryEffect<"::mlir::MemoryEffects::Read", resource, stage, range>;
75def MemRead : MemRead<DefaultResource, 0, PartialEffect>;
76class MemReadAt<int stage, EffectRange range = PartialEffect>
77  : MemRead<DefaultResource, stage, range>;
78
79// The following effect indicates that the operation writes to some
80// resource. A 'write' effect implies only mutating a resource, and not any
81// visible dereference or read.
82class MemWrite<Resource resource, int stage = 0,
83               EffectRange range = PartialEffect>
84  : MemoryEffect<"::mlir::MemoryEffects::Write", resource, stage, range>;
85def MemWrite : MemWrite<DefaultResource, 0, PartialEffect>;
86class MemWriteAt<int stage, EffectRange range = PartialEffect>
87  : MemWrite<DefaultResource, stage, range>;
88
89//===----------------------------------------------------------------------===//
90// Effect Traits
91//===----------------------------------------------------------------------===//
92
93// Op has no effect on memory but may have undefined behavior.
94def NoMemoryEffect : MemoryEffects<[]>;
95
96// Op has recursively computed side effects.
97def RecursiveMemoryEffects : NativeOpTrait<"HasRecursiveMemoryEffects">;
98
99//===----------------------------------------------------------------------===//
100// Speculation
101//===----------------------------------------------------------------------===//
102
103// Used to inject an implementation of getSpeculatability.  Users should not use
104// this directly.
105def RecursivelySpeculatableImplTrait
106  : NativeOpTrait<"RecursivelySpeculatableImplTrait">;
107
108// Used to inject an implementation of getSpeculatability.  Users should not use
109// this directly.
110def AlwaysSpeculatableImplTrait
111  : NativeOpTrait<"AlwaysSpeculatableImplTrait">;
112
113// This op interface enables Op authors to inject custom logic to determine
114// whether an Operation can be speculatively executed.  Ops that implement this
115// interface need to implement the custom logic in the `getSpeculatability` method.
116// For instance, the `getSpeculatability` for a specific op may check the attributes
117// or input types to determine whether that specific Operation is speculatable.
118def ConditionallySpeculatable : OpInterface<"ConditionallySpeculatable"> {
119  let description = [{
120    An interface used to query information about the speculability of an
121    operation.
122  }];
123  let cppNamespace = "::mlir";
124
125  let methods = [
126    InterfaceMethod<[{
127        Returns value indicating whether the specific operation in question can
128        be speculatively executed.  Please see the documentation on the
129        Speculatability enum to know how to interpret the return value.
130      }],
131      "::mlir::Speculation::Speculatability", "getSpeculatability", (ins)>
132  ];
133}
134
135// Marks an Operation as always speculatable.
136def AlwaysSpeculatable : TraitList<[
137    ConditionallySpeculatable, AlwaysSpeculatableImplTrait]>;
138
139// Marks an Operation as speculatable only if all the operations in all attached
140// regions are also speculatable.
141def RecursivelySpeculatable : TraitList<[
142    ConditionallySpeculatable, RecursivelySpeculatableImplTrait]>;
143
144// Always speculatable operation that does not touch memory.  These operations
145// are always legal to hoist or sink.
146def Pure : TraitList<[AlwaysSpeculatable, NoMemoryEffect]>;
147
148#endif // MLIR_INTERFACES_SIDEEFFECTS
149