Skip to main content

t4a_cubecl_ir/interfaces/
traits.rs

1use 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    /// Key for symbol visibility attribute when the operation defines a symbol visibility.
218    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);