1/// Attribute base class.
2class Attr<string S> {
3  // String representation of this attribute in the IR.
4  string AttrString = S;
5}
6
7/// Enum attribute.
8class EnumAttr<string S> : Attr<S>;
9
10/// StringBool attribute.
11class StrBoolAttr<string S> : Attr<S>;
12
13/// Target-independent enum attributes.
14
15/// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias.
16/// 0 means unaligned (different from align(1)).
17def Alignment : EnumAttr<"align">;
18
19/// The result of the function is guaranteed to point to a number of bytes that
20/// we can determine if we know the value of the function's arguments.
21def AllocSize : EnumAttr<"allocsize">;
22
23/// inline=always.
24def AlwaysInline : EnumAttr<"alwaysinline">;
25
26/// Function can access memory only using pointers based on its arguments.
27def ArgMemOnly : EnumAttr<"argmemonly">;
28
29/// Callee is recognized as a builtin, despite nobuiltin attribute on its
30/// declaration.
31def Builtin : EnumAttr<"builtin">;
32
33/// Pass structure by value.
34def ByVal : EnumAttr<"byval">;
35
36/// Marks function as being in a cold path.
37def Cold : EnumAttr<"cold">;
38
39/// Can only be moved to control-equivalent blocks.
40def Convergent : EnumAttr<"convergent">;
41
42/// Pointer is known to be dereferenceable.
43def Dereferenceable : EnumAttr<"dereferenceable">;
44
45/// Pointer is either null or dereferenceable.
46def DereferenceableOrNull : EnumAttr<"dereferenceable_or_null">;
47
48/// Function may only access memory that is inaccessible from IR.
49def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">;
50
51/// Function may only access memory that is either inaccessible from the IR,
52/// or pointed to by its pointer arguments.
53def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly">;
54
55/// Pass structure in an alloca.
56def InAlloca : EnumAttr<"inalloca">;
57
58/// Source said inlining was desirable.
59def InlineHint : EnumAttr<"inlinehint">;
60
61/// Force argument to be passed in register.
62def InReg : EnumAttr<"inreg">;
63
64/// Build jump-instruction tables and replace refs.
65def JumpTable : EnumAttr<"jumptable">;
66
67/// Function must be optimized for size first.
68def MinSize : EnumAttr<"minsize">;
69
70/// Naked function.
71def Naked : EnumAttr<"naked">;
72
73/// Nested function static chain.
74def Nest : EnumAttr<"nest">;
75
76/// Considered to not alias after call.
77def NoAlias : EnumAttr<"noalias">;
78
79/// Callee isn't recognized as a builtin.
80def NoBuiltin : EnumAttr<"nobuiltin">;
81
82/// Function creates no aliases of pointer.
83def NoCapture : EnumAttr<"nocapture">;
84
85/// Call cannot be duplicated.
86def NoDuplicate : EnumAttr<"noduplicate">;
87
88/// Disable implicit floating point insts.
89def NoImplicitFloat : EnumAttr<"noimplicitfloat">;
90
91/// inline=never.
92def NoInline : EnumAttr<"noinline">;
93
94/// Function is called early and/or often, so lazy binding isn't worthwhile.
95def NonLazyBind : EnumAttr<"nonlazybind">;
96
97/// Pointer is known to be not null.
98def NonNull : EnumAttr<"nonnull">;
99
100/// The function does not recurse.
101def NoRecurse : EnumAttr<"norecurse">;
102
103/// Disable redzone.
104def NoRedZone : EnumAttr<"noredzone">;
105
106/// Mark the function as not returning.
107def NoReturn : EnumAttr<"noreturn">;
108
109/// Disable Indirect Branch Tracking.
110def NoCfCheck : EnumAttr<"nocf_check">;
111
112/// Function doesn't unwind stack.
113def NoUnwind : EnumAttr<"nounwind">;
114
115/// Select optimizations for best fuzzing signal.
116def OptForFuzzing : EnumAttr<"optforfuzzing">;
117
118/// opt_size.
119def OptimizeForSize : EnumAttr<"optsize">;
120
121/// Function must not be optimized.
122def OptimizeNone : EnumAttr<"optnone">;
123
124/// Function does not access memory.
125def ReadNone : EnumAttr<"readnone">;
126
127/// Function only reads from memory.
128def ReadOnly : EnumAttr<"readonly">;
129
130/// Return value is always equal to this argument.
131def Returned : EnumAttr<"returned">;
132
133/// Function can return twice.
134def ReturnsTwice : EnumAttr<"returns_twice">;
135
136/// Safe Stack protection.
137def SafeStack : EnumAttr<"safestack">;
138
139/// Shadow Call Stack protection.
140def ShadowCallStack : EnumAttr<"shadowcallstack">;
141
142/// Sign extended before/after call.
143def SExt : EnumAttr<"signext">;
144
145/// Alignment of stack for function (3 bits)  stored as log2 of alignment with
146/// +1 bias 0 means unaligned (different from alignstack=(1)).
147def StackAlignment : EnumAttr<"alignstack">;
148
149/// Function can be speculated.
150def Speculatable : EnumAttr<"speculatable">;
151
152/// Stack protection.
153def StackProtect : EnumAttr<"ssp">;
154
155/// Stack protection required.
156def StackProtectReq : EnumAttr<"sspreq">;
157
158/// Strong Stack protection.
159def StackProtectStrong : EnumAttr<"sspstrong">;
160
161/// Function was called in a scope requiring strict floating point semantics.
162def StrictFP : EnumAttr<"strictfp">;
163
164/// Hidden pointer to structure to return.
165def StructRet : EnumAttr<"sret">;
166
167/// AddressSanitizer is on.
168def SanitizeAddress : EnumAttr<"sanitize_address">;
169
170/// ThreadSanitizer is on.
171def SanitizeThread : EnumAttr<"sanitize_thread">;
172
173/// MemorySanitizer is on.
174def SanitizeMemory : EnumAttr<"sanitize_memory">;
175
176/// HWAddressSanitizer is on.
177def SanitizeHWAddress : EnumAttr<"sanitize_hwaddress">;
178
179/// Argument is swift error.
180def SwiftError : EnumAttr<"swifterror">;
181
182/// Argument is swift self/context.
183def SwiftSelf : EnumAttr<"swiftself">;
184
185/// Function must be in a unwind table.
186def UWTable : EnumAttr<"uwtable">;
187
188/// Function only writes to memory.
189def WriteOnly : EnumAttr<"writeonly">;
190
191/// Zero extended before/after call.
192def ZExt : EnumAttr<"zeroext">;
193
194/// Target-independent string attributes.
195def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">;
196def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">;
197def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">;
198def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">;
199def NoJumpTables : StrBoolAttr<"no-jump-tables">;
200def ProfileSampleAccurate : StrBoolAttr<"profile-sample-accurate">;
201
202class CompatRule<string F> {
203  // The name of the function called to check the attribute of the caller and
204  // callee and decide whether inlining should be allowed. The function's
205  // signature must match "bool(const Function&, const Function &)", where the
206  // first parameter is the reference to the caller and the second parameter is
207  // the reference to the callee. It must return false if the attributes of the
208  // caller and callee are incompatible, and true otherwise.
209  string CompatFunc = F;
210}
211
212def : CompatRule<"isEqual<SanitizeAddressAttr>">;
213def : CompatRule<"isEqual<SanitizeThreadAttr>">;
214def : CompatRule<"isEqual<SanitizeMemoryAttr>">;
215def : CompatRule<"isEqual<SanitizeHWAddressAttr>">;
216def : CompatRule<"isEqual<SafeStackAttr>">;
217def : CompatRule<"isEqual<ShadowCallStackAttr>">;
218
219class MergeRule<string F> {
220  // The name of the function called to merge the attributes of the caller and
221  // callee. The function's signature must match
222  // "void(Function&, const Function &)", where the first parameter is the
223  // reference to the caller and the second parameter is the reference to the
224  // callee.
225  string MergeFunc = F;
226}
227
228def : MergeRule<"setAND<LessPreciseFPMADAttr>">;
229def : MergeRule<"setAND<NoInfsFPMathAttr>">;
230def : MergeRule<"setAND<NoNansFPMathAttr>">;
231def : MergeRule<"setAND<UnsafeFPMathAttr>">;
232def : MergeRule<"setOR<NoImplicitFloatAttr>">;
233def : MergeRule<"setOR<NoJumpTablesAttr>">;
234def : MergeRule<"setOR<ProfileSampleAccurateAttr>">;
235def : MergeRule<"adjustCallerSSPLevel">;
236def : MergeRule<"adjustCallerStackProbes">;
237def : MergeRule<"adjustCallerStackProbeSize">;
238def : MergeRule<"adjustMinLegalVectorWidth">;
239def : MergeRule<"adjustNullPointerValidAttr">;
240