t4a_cubecl_ir/interfaces/
traits.rs1use pliron::{
2 builtin::ops::{FuncOp, ModuleOp},
3 dict_key,
4};
5
6#[macro_export]
7macro_rules! Pure {
8 ($ty: ty) => {
9 $crate::NoSideEffects!($ty);
10 $crate::NoMemoryEffect!($ty);
11 $crate::AlwaysSpeculatable!($ty);
12 };
13}
14
15#[macro_export]
16macro_rules! CanMaterialize {
17 ($ty: ty) => {
18 #[::pliron::derive::op_interface_impl]
19 impl $crate::interfaces::MaterializableOp for $ty {
20 fn materialize(
21 &self,
22 ctx: &mut pliron::context::Context,
23 result_ty: Vec<pliron::r#type::TypeHandle>,
24 operands: Vec<Value>,
25 attributes: pliron::attribute::AttributeDict,
26 ) -> pliron::context::Ptr<pliron::operation::Operation> {
27 use pliron::op::Op;
28 let op = pliron::operation::Operation::new(
29 ctx,
30 Self::get_concrete_op_info(),
31 result_ty,
32 operands,
33 vec![],
34 0,
35 );
36 op.deref_mut(ctx).attributes = attributes;
37 op
38 }
39 }
40 };
41}
42
43#[macro_export]
44macro_rules! NoMemoryEffect {
45 ($ty: ty) => {
46 #[::pliron::derive::op_interface_impl]
47 impl $crate::interfaces::side_effects::MemoryEffectsOp for $ty {
48 fn memory_effects(
49 &self,
50 _ctx: &pliron::context::Context,
51 ) -> $crate::alloc::vec::Vec<$crate::interfaces::side_effects::MemoryEffect> {
52 $crate::alloc::vec![]
53 }
54 }
55 };
56}
57
58#[macro_export]
59macro_rules! RecursiveMemoryEffects {
60 ($ty: ty) => {
61 #[::pliron::derive::op_interface_impl]
62 impl $crate::interfaces::side_effects::MemoryEffectsOp for $ty {
63 fn memory_effects(
64 &self,
65 ctx: &pliron::context::Context,
66 ) -> $crate::alloc::vec::Vec<$crate::interfaces::side_effects::MemoryEffect> {
67 $crate::interfaces::side_effects::get_nested_memory_effects(
68 ctx,
69 self.get_operation(),
70 )
71 }
72 }
73 };
74}
75
76#[macro_export]
77macro_rules! AlwaysSpeculatable {
78 ($ty: ty) => {
79 #[::pliron::derive::op_interface_impl]
80 impl $crate::interfaces::side_effects::ConditionallySpeculatable for $ty {
81 fn speculatability(
82 &self,
83 _ctx: &pliron::context::Context,
84 ) -> $crate::interfaces::side_effects::Speculatability {
85 $crate::interfaces::side_effects::Speculatability::Speculatable
86 }
87 }
88 };
89}
90
91#[macro_export]
92macro_rules! RecursivelySpeculatable {
93 ($ty: ty) => {
94 #[::pliron::derive::op_interface_impl]
95 impl $crate::interfaces::side_effects::ConditionallySpeculatable for $ty {
96 fn speculatability(
97 &self,
98 _ctx: &pliron::context::Context,
99 ) -> $crate::interfaces::side_effects::Speculatability {
100 $crate::interfaces::side_effects::Speculatability::RecursivelySpeculatable
101 }
102 }
103 };
104}
105
106#[macro_export]
107macro_rules! PropagatesUniformity {
108 ($ty: ty) => {
109 #[::pliron::derive::op_interface_impl]
110 impl $crate::interfaces::uniformity::UniformOpInterface for $ty {
111 fn uniformity(
112 &self,
113 _ctx: &pliron::context::Context,
114 operands: &[$crate::interfaces::uniformity::Uniformity],
115 ) -> $crate::interfaces::uniformity::Uniformity {
116 operands
117 .iter()
118 .copied()
119 .min()
120 .unwrap_or($crate::interfaces::uniformity::Uniformity::Device)
121 }
122 }
123 };
124}
125
126#[macro_export]
127macro_rules! ReturnLike {
128 ($ty: ty) => {
129 #[::pliron::derive::op_interface_impl]
130 impl $crate::interfaces::control_flow::RegionBranchTerminatorOpInterface for $ty {
131 fn successor_operands(&self, ctx: &Context, _: RegionSuccessor) -> Vec<Use<Value>> {
132 self.get_operation().deref(ctx).operands_as_uses().collect()
133 }
134 }
135
136 #[::pliron::derive::op_interface_impl]
137 impl $crate::interfaces::uniformity::UniformRegionTerminatorOpInterface for $ty {
138 fn successor_region_uniformity(
139 &self,
140 ctx: &Context,
141 _operands: &[$crate::interfaces::uniformity::Uniformity],
142 ) -> Vec<$crate::interfaces::uniformity::Uniformity> {
143 self.all_successor_regions(ctx)
144 .iter()
145 .map(|_| $crate::interfaces::uniformity::Uniformity::Cube)
146 .collect()
147 }
148 }
149
150 #[::pliron::derive::op_interface_impl]
151 impl $crate::interfaces::ReturnLike for $ty {}
152 };
153}
154
155#[macro_export]
156macro_rules! HasSideEffects {
157 ($ty: ty) => {
158 #[::pliron::derive::op_interface_impl]
159 impl pliron::opts::dce::SideEffects for $ty {
160 fn has_side_effects(&self, _ctx: &pliron::context::Context) -> bool {
161 true
162 }
163 }
164 };
165}
166
167#[macro_export]
168macro_rules! RecursiveSideEffects {
169 ($ty: ty) => {
170 #[::pliron::derive::op_interface_impl]
171 impl pliron::opts::dce::SideEffects for $ty {
172 fn has_side_effects(&self, ctx: &pliron::context::Context) -> bool {
173 $crate::interfaces::side_effects::get_nested_side_effects(ctx, self.get_operation())
174 }
175 }
176 };
177}
178
179#[macro_export]
180macro_rules! NoSideEffects {
181 ($ty: ty) => {
182 #[::pliron::derive::op_interface_impl]
183 impl pliron::opts::dce::SideEffects for $ty {
184 fn has_side_effects(&self, _ctx: &pliron::context::Context) -> bool {
185 false
186 }
187 }
188 };
189}
190
191#[macro_export]
192macro_rules! Commutative {
193 ($ty: ty) => {
194 #[::pliron::derive::op_interface_impl]
195 impl $crate::interfaces::ExpressionCanonicalize for $ty {
196 fn canonical_expression(
197 &self,
198 ctx: &pliron::context::Context,
199 mut operands: alloc::vec::Vec<$crate::interfaces::ExpressionValue>,
200 ) -> $crate::interfaces::Expression {
201 operands.sort();
202 $crate::interfaces::Expression::new(
203 self.result_type(ctx),
204 <$ty>::get_opid_static(),
205 operands,
206 self.get_operation()
207 .deref(ctx)
208 .attributes
209 .clone_skip_outlined(ctx),
210 )
211 }
212 }
213 };
214}
215
216dict_key!(
217 ATTR_KEY_SYM_VISIBILITY,
219 "sym_visibility"
220);
221
222#[macro_export]
223macro_rules! SymbolVisibility {
224 ($ty: ty) => {
225 #[$crate::pliron::derive::op_interface_impl]
226 impl $crate::interfaces::control_flow::SymbolOpInterface for $ty {
227 fn get_visibility(
228 &self,
229 ctx: &$crate::pliron::context::Context,
230 ) -> $crate::interfaces::control_flow::SymbolVisibility {
231 use $crate::pliron::op::Op;
232 let op = self.get_operation().deref(ctx);
233 let attr: Option<&$crate::attributes::SymbolVisibilityAttr> = op
234 .attributes
235 .get(&$crate::interfaces::traits::ATTR_KEY_SYM_VISIBILITY);
236 attr.map(|it| it.0)
237 .unwrap_or($crate::interfaces::control_flow::SymbolVisibility::Public)
238 }
239
240 fn set_visibility(
241 &self,
242 ctx: &mut $crate::pliron::context::Context,
243 visibility: $crate::interfaces::control_flow::SymbolVisibility,
244 ) {
245 use $crate::pliron::op::Op;
246 let mut op = self.get_operation().deref_mut(ctx);
247 op.attributes.set(
248 $crate::interfaces::traits::ATTR_KEY_SYM_VISIBILITY.clone(),
249 $crate::attributes::SymbolVisibilityAttr(visibility),
250 );
251 }
252 }
253 };
254}
255
256SymbolVisibility!(ModuleOp);
257SymbolVisibility!(FuncOp);