Skip to main content

melior/dialect/llvm/
load_store_options.rs

1use crate::{
2    ir::{
3        attribute::{ArrayAttribute, IntegerAttribute},
4        Attribute, Identifier,
5    },
6    Context,
7};
8
9const ATTRIBUTE_COUNT: usize = 7;
10
11// spell-checker: disable
12
13/// Load/store options.
14#[derive(Debug, Default, Clone, Copy)]
15pub struct LoadStoreOptions<'c> {
16    align: Option<IntegerAttribute<'c>>,
17    volatile: bool,
18    nontemporal: bool,
19    access_groups: Option<ArrayAttribute<'c>>,
20    alias_scopes: Option<ArrayAttribute<'c>>,
21    noalias_scopes: Option<ArrayAttribute<'c>>,
22    tbaa: Option<ArrayAttribute<'c>>,
23}
24
25impl<'c> LoadStoreOptions<'c> {
26    /// Creates load/store options.
27    pub fn new() -> Self {
28        Self::default()
29    }
30
31    /// Sets an alignment.
32    pub fn align(mut self, align: Option<IntegerAttribute<'c>>) -> Self {
33        self.align = align;
34        self
35    }
36
37    /// Sets a volatile flag.
38    pub fn volatile(mut self, volatile: bool) -> Self {
39        self.volatile = volatile;
40        self
41    }
42
43    /// Sets a nontemporal flag.
44    pub fn nontemporal(mut self, nontemporal: bool) -> Self {
45        self.nontemporal = nontemporal;
46        self
47    }
48
49    /// Sets access groups.
50    pub fn access_groups(mut self, access_groups: Option<ArrayAttribute<'c>>) -> Self {
51        self.access_groups = access_groups;
52        self
53    }
54
55    /// Sets alias scopes.
56    pub fn alias_scopes(mut self, alias_scopes: Option<ArrayAttribute<'c>>) -> Self {
57        self.alias_scopes = alias_scopes;
58        self
59    }
60
61    /// Sets noalias scopes.
62    pub fn nonalias_scopes(mut self, noalias_scopes: Option<ArrayAttribute<'c>>) -> Self {
63        self.noalias_scopes = noalias_scopes;
64        self
65    }
66
67    /// Sets TBAA metadata.
68    pub const fn tbaa(mut self, tbaa: ArrayAttribute<'c>) -> Self {
69        self.tbaa = Some(tbaa);
70        self
71    }
72
73    pub(super) fn into_attributes(
74        self,
75        context: &'c Context,
76    ) -> Vec<(Identifier<'c>, Attribute<'c>)> {
77        let mut attributes = Vec::with_capacity(ATTRIBUTE_COUNT);
78
79        if let Some(align) = self.align {
80            attributes.push((Identifier::new(context, "alignment"), align.into()));
81        }
82
83        if self.volatile {
84            attributes.push((
85                Identifier::new(context, "volatile_"),
86                Attribute::unit(context),
87            ));
88        }
89
90        if self.nontemporal {
91            attributes.push((
92                Identifier::new(context, "nontemporal"),
93                Attribute::unit(context),
94            ));
95        }
96
97        if let Some(access_groups) = self.access_groups {
98            attributes.push((
99                Identifier::new(context, "access_groups"),
100                access_groups.into(),
101            ));
102        }
103
104        if let Some(alias_scopes) = self.alias_scopes {
105            attributes.push((
106                Identifier::new(context, "alias_scopes"),
107                alias_scopes.into(),
108            ));
109        }
110
111        if let Some(noalias_scopes) = self.noalias_scopes {
112            attributes.push((
113                Identifier::new(context, "noalias_scopes"),
114                noalias_scopes.into(),
115            ));
116        }
117
118        if let Some(tbaa) = self.tbaa {
119            attributes.push((Identifier::new(context, "tbaa"), tbaa.into()));
120        }
121
122        attributes
123    }
124}