1#ifdef GET_ATTR_ENUM
2#undef GET_ATTR_ENUM
3Alignment,
4AllocSize,
5AlwaysInline,
6ArgMemOnly,
7Builtin,
8ByVal,
9Cold,
10Convergent,
11Dereferenceable,
12DereferenceableOrNull,
13InAlloca,
14InReg,
15InaccessibleMemOnly,
16InaccessibleMemOrArgMemOnly,
17InlineHint,
18JumpTable,
19MinSize,
20Naked,
21Nest,
22NoAlias,
23NoBuiltin,
24NoCapture,
25NoCfCheck,
26NoDuplicate,
27NoImplicitFloat,
28NoInline,
29NoRecurse,
30NoRedZone,
31NoReturn,
32NoUnwind,
33NonLazyBind,
34NonNull,
35OptForFuzzing,
36OptimizeForSize,
37OptimizeNone,
38ReadNone,
39ReadOnly,
40Returned,
41ReturnsTwice,
42SExt,
43SafeStack,
44SanitizeAddress,
45SanitizeHWAddress,
46SanitizeMemory,
47SanitizeThread,
48ShadowCallStack,
49Speculatable,
50SpeculativeLoadHardening,
51StackAlignment,
52StackProtect,
53StackProtectReq,
54StackProtectStrong,
55StrictFP,
56StructRet,
57SwiftError,
58SwiftSelf,
59UWTable,
60WriteOnly,
61ZExt,
62#endif
63#ifdef GET_ATTR_KIND_FROM_NAME
64#undef GET_ATTR_KIND_FROM_NAME
65static Attribute::AttrKind getAttrKindFromName(StringRef AttrName) {
66 return StringSwitch<Attribute::AttrKind>(AttrName)
67 .Case("align", Attribute::Alignment)
68 .Case("allocsize", Attribute::AllocSize)
69 .Case("alwaysinline", Attribute::AlwaysInline)
70 .Case("argmemonly", Attribute::ArgMemOnly)
71 .Case("builtin", Attribute::Builtin)
72 .Case("byval", Attribute::ByVal)
73 .Case("cold", Attribute::Cold)
74 .Case("convergent", Attribute::Convergent)
75 .Case("dereferenceable", Attribute::Dereferenceable)
76 .Case("dereferenceable_or_null", Attribute::DereferenceableOrNull)
77 .Case("inalloca", Attribute::InAlloca)
78 .Case("inreg", Attribute::InReg)
79 .Case("inaccessiblememonly", Attribute::InaccessibleMemOnly)
80 .Case("inaccessiblemem_or_argmemonly", Attribute::InaccessibleMemOrArgMemOnly)
81 .Case("inlinehint", Attribute::InlineHint)
82 .Case("jumptable", Attribute::JumpTable)
83 .Case("minsize", Attribute::MinSize)
84 .Case("naked", Attribute::Naked)
85 .Case("nest", Attribute::Nest)
86 .Case("noalias", Attribute::NoAlias)
87 .Case("nobuiltin", Attribute::NoBuiltin)
88 .Case("nocapture", Attribute::NoCapture)
89 .Case("nocf_check", Attribute::NoCfCheck)
90 .Case("noduplicate", Attribute::NoDuplicate)
91 .Case("noimplicitfloat", Attribute::NoImplicitFloat)
92 .Case("noinline", Attribute::NoInline)
93 .Case("norecurse", Attribute::NoRecurse)
94 .Case("noredzone", Attribute::NoRedZone)
95 .Case("noreturn", Attribute::NoReturn)
96 .Case("nounwind", Attribute::NoUnwind)
97 .Case("nonlazybind", Attribute::NonLazyBind)
98 .Case("nonnull", Attribute::NonNull)
99 .Case("optforfuzzing", Attribute::OptForFuzzing)
100 .Case("optsize", Attribute::OptimizeForSize)
101 .Case("optnone", Attribute::OptimizeNone)
102 .Case("readnone", Attribute::ReadNone)
103 .Case("readonly", Attribute::ReadOnly)
104 .Case("returned", Attribute::Returned)
105 .Case("returns_twice", Attribute::ReturnsTwice)
106 .Case("signext", Attribute::SExt)
107 .Case("safestack", Attribute::SafeStack)
108 .Case("sanitize_address", Attribute::SanitizeAddress)
109 .Case("sanitize_hwaddress", Attribute::SanitizeHWAddress)
110 .Case("sanitize_memory", Attribute::SanitizeMemory)
111 .Case("sanitize_thread", Attribute::SanitizeThread)
112 .Case("shadowcallstack", Attribute::ShadowCallStack)
113 .Case("speculatable", Attribute::Speculatable)
114 .Case("speculative_load_hardening", Attribute::SpeculativeLoadHardening)
115 .Case("alignstack", Attribute::StackAlignment)
116 .Case("ssp", Attribute::StackProtect)
117 .Case("sspreq", Attribute::StackProtectReq)
118 .Case("sspstrong", Attribute::StackProtectStrong)
119 .Case("strictfp", Attribute::StrictFP)
120 .Case("sret", Attribute::StructRet)
121 .Case("swifterror", Attribute::SwiftError)
122 .Case("swiftself", Attribute::SwiftSelf)
123 .Case("uwtable", Attribute::UWTable)
124 .Case("writeonly", Attribute::WriteOnly)
125 .Case("zeroext", Attribute::ZExt)
126 .Default(Attribute::None);
127}
128
129#endif
130#ifdef GET_ATTR_COMPAT_FUNC
131#undef GET_ATTR_COMPAT_FUNC
132struct EnumAttr {
133 static bool isSet(const Function &Fn,
134 Attribute::AttrKind Kind) {
135 return Fn.hasFnAttribute(Kind);
136 }
137
138 static void set(Function &Fn,
139 Attribute::AttrKind Kind, bool Val) {
140 if (Val)
141 Fn.addFnAttr(Kind);
142 else
143 Fn.removeFnAttr(Kind);
144 }
145};
146
147struct StrBoolAttr {
148 static bool isSet(const Function &Fn,
149 StringRef Kind) {
150 auto A = Fn.getFnAttribute(Kind);
151 return A.getValueAsString().equals("true");
152 }
153
154 static void set(Function &Fn,
155 StringRef Kind, bool Val) {
156 Fn.addFnAttr(Kind, Val ? "true" : "false");
157 }
158};
159
160// EnumAttr classes
161struct AlignmentAttr : EnumAttr {
162 static enum Attribute::AttrKind getKind() {
163 return llvm::Attribute::Alignment;
164 }
165};
166struct AllocSizeAttr : EnumAttr {
167 static enum Attribute::AttrKind getKind() {
168 return llvm::Attribute::AllocSize;
169 }
170};
171struct AlwaysInlineAttr : EnumAttr {
172 static enum Attribute::AttrKind getKind() {
173 return llvm::Attribute::AlwaysInline;
174 }
175};
176struct ArgMemOnlyAttr : EnumAttr {
177 static enum Attribute::AttrKind getKind() {
178 return llvm::Attribute::ArgMemOnly;
179 }
180};
181struct BuiltinAttr : EnumAttr {
182 static enum Attribute::AttrKind getKind() {
183 return llvm::Attribute::Builtin;
184 }
185};
186struct ByValAttr : EnumAttr {
187 static enum Attribute::AttrKind getKind() {
188 return llvm::Attribute::ByVal;
189 }
190};
191struct ColdAttr : EnumAttr {
192 static enum Attribute::AttrKind getKind() {
193 return llvm::Attribute::Cold;
194 }
195};
196struct ConvergentAttr : EnumAttr {
197 static enum Attribute::AttrKind getKind() {
198 return llvm::Attribute::Convergent;
199 }
200};
201struct DereferenceableAttr : EnumAttr {
202 static enum Attribute::AttrKind getKind() {
203 return llvm::Attribute::Dereferenceable;
204 }
205};
206struct DereferenceableOrNullAttr : EnumAttr {
207 static enum Attribute::AttrKind getKind() {
208 return llvm::Attribute::DereferenceableOrNull;
209 }
210};
211struct InAllocaAttr : EnumAttr {
212 static enum Attribute::AttrKind getKind() {
213 return llvm::Attribute::InAlloca;
214 }
215};
216struct InRegAttr : EnumAttr {
217 static enum Attribute::AttrKind getKind() {
218 return llvm::Attribute::InReg;
219 }
220};
221struct InaccessibleMemOnlyAttr : EnumAttr {
222 static enum Attribute::AttrKind getKind() {
223 return llvm::Attribute::InaccessibleMemOnly;
224 }
225};
226struct InaccessibleMemOrArgMemOnlyAttr : EnumAttr {
227 static enum Attribute::AttrKind getKind() {
228 return llvm::Attribute::InaccessibleMemOrArgMemOnly;
229 }
230};
231struct InlineHintAttr : EnumAttr {
232 static enum Attribute::AttrKind getKind() {
233 return llvm::Attribute::InlineHint;
234 }
235};
236struct JumpTableAttr : EnumAttr {
237 static enum Attribute::AttrKind getKind() {
238 return llvm::Attribute::JumpTable;
239 }
240};
241struct MinSizeAttr : EnumAttr {
242 static enum Attribute::AttrKind getKind() {
243 return llvm::Attribute::MinSize;
244 }
245};
246struct NakedAttr : EnumAttr {
247 static enum Attribute::AttrKind getKind() {
248 return llvm::Attribute::Naked;
249 }
250};
251struct NestAttr : EnumAttr {
252 static enum Attribute::AttrKind getKind() {
253 return llvm::Attribute::Nest;
254 }
255};
256struct NoAliasAttr : EnumAttr {
257 static enum Attribute::AttrKind getKind() {
258 return llvm::Attribute::NoAlias;
259 }
260};
261struct NoBuiltinAttr : EnumAttr {
262 static enum Attribute::AttrKind getKind() {
263 return llvm::Attribute::NoBuiltin;
264 }
265};
266struct NoCaptureAttr : EnumAttr {
267 static enum Attribute::AttrKind getKind() {
268 return llvm::Attribute::NoCapture;
269 }
270};
271struct NoCfCheckAttr : EnumAttr {
272 static enum Attribute::AttrKind getKind() {
273 return llvm::Attribute::NoCfCheck;
274 }
275};
276struct NoDuplicateAttr : EnumAttr {
277 static enum Attribute::AttrKind getKind() {
278 return llvm::Attribute::NoDuplicate;
279 }
280};
281struct NoImplicitFloatAttr : EnumAttr {
282 static enum Attribute::AttrKind getKind() {
283 return llvm::Attribute::NoImplicitFloat;
284 }
285};
286struct NoInlineAttr : EnumAttr {
287 static enum Attribute::AttrKind getKind() {
288 return llvm::Attribute::NoInline;
289 }
290};
291struct NoRecurseAttr : EnumAttr {
292 static enum Attribute::AttrKind getKind() {
293 return llvm::Attribute::NoRecurse;
294 }
295};
296struct NoRedZoneAttr : EnumAttr {
297 static enum Attribute::AttrKind getKind() {
298 return llvm::Attribute::NoRedZone;
299 }
300};
301struct NoReturnAttr : EnumAttr {
302 static enum Attribute::AttrKind getKind() {
303 return llvm::Attribute::NoReturn;
304 }
305};
306struct NoUnwindAttr : EnumAttr {
307 static enum Attribute::AttrKind getKind() {
308 return llvm::Attribute::NoUnwind;
309 }
310};
311struct NonLazyBindAttr : EnumAttr {
312 static enum Attribute::AttrKind getKind() {
313 return llvm::Attribute::NonLazyBind;
314 }
315};
316struct NonNullAttr : EnumAttr {
317 static enum Attribute::AttrKind getKind() {
318 return llvm::Attribute::NonNull;
319 }
320};
321struct OptForFuzzingAttr : EnumAttr {
322 static enum Attribute::AttrKind getKind() {
323 return llvm::Attribute::OptForFuzzing;
324 }
325};
326struct OptimizeForSizeAttr : EnumAttr {
327 static enum Attribute::AttrKind getKind() {
328 return llvm::Attribute::OptimizeForSize;
329 }
330};
331struct OptimizeNoneAttr : EnumAttr {
332 static enum Attribute::AttrKind getKind() {
333 return llvm::Attribute::OptimizeNone;
334 }
335};
336struct ReadNoneAttr : EnumAttr {
337 static enum Attribute::AttrKind getKind() {
338 return llvm::Attribute::ReadNone;
339 }
340};
341struct ReadOnlyAttr : EnumAttr {
342 static enum Attribute::AttrKind getKind() {
343 return llvm::Attribute::ReadOnly;
344 }
345};
346struct ReturnedAttr : EnumAttr {
347 static enum Attribute::AttrKind getKind() {
348 return llvm::Attribute::Returned;
349 }
350};
351struct ReturnsTwiceAttr : EnumAttr {
352 static enum Attribute::AttrKind getKind() {
353 return llvm::Attribute::ReturnsTwice;
354 }
355};
356struct SExtAttr : EnumAttr {
357 static enum Attribute::AttrKind getKind() {
358 return llvm::Attribute::SExt;
359 }
360};
361struct SafeStackAttr : EnumAttr {
362 static enum Attribute::AttrKind getKind() {
363 return llvm::Attribute::SafeStack;
364 }
365};
366struct SanitizeAddressAttr : EnumAttr {
367 static enum Attribute::AttrKind getKind() {
368 return llvm::Attribute::SanitizeAddress;
369 }
370};
371struct SanitizeHWAddressAttr : EnumAttr {
372 static enum Attribute::AttrKind getKind() {
373 return llvm::Attribute::SanitizeHWAddress;
374 }
375};
376struct SanitizeMemoryAttr : EnumAttr {
377 static enum Attribute::AttrKind getKind() {
378 return llvm::Attribute::SanitizeMemory;
379 }
380};
381struct SanitizeThreadAttr : EnumAttr {
382 static enum Attribute::AttrKind getKind() {
383 return llvm::Attribute::SanitizeThread;
384 }
385};
386struct ShadowCallStackAttr : EnumAttr {
387 static enum Attribute::AttrKind getKind() {
388 return llvm::Attribute::ShadowCallStack;
389 }
390};
391struct SpeculatableAttr : EnumAttr {
392 static enum Attribute::AttrKind getKind() {
393 return llvm::Attribute::Speculatable;
394 }
395};
396struct SpeculativeLoadHardeningAttr : EnumAttr {
397 static enum Attribute::AttrKind getKind() {
398 return llvm::Attribute::SpeculativeLoadHardening;
399 }
400};
401struct StackAlignmentAttr : EnumAttr {
402 static enum Attribute::AttrKind getKind() {
403 return llvm::Attribute::StackAlignment;
404 }
405};
406struct StackProtectAttr : EnumAttr {
407 static enum Attribute::AttrKind getKind() {
408 return llvm::Attribute::StackProtect;
409 }
410};
411struct StackProtectReqAttr : EnumAttr {
412 static enum Attribute::AttrKind getKind() {
413 return llvm::Attribute::StackProtectReq;
414 }
415};
416struct StackProtectStrongAttr : EnumAttr {
417 static enum Attribute::AttrKind getKind() {
418 return llvm::Attribute::StackProtectStrong;
419 }
420};
421struct StrictFPAttr : EnumAttr {
422 static enum Attribute::AttrKind getKind() {
423 return llvm::Attribute::StrictFP;
424 }
425};
426struct StructRetAttr : EnumAttr {
427 static enum Attribute::AttrKind getKind() {
428 return llvm::Attribute::StructRet;
429 }
430};
431struct SwiftErrorAttr : EnumAttr {
432 static enum Attribute::AttrKind getKind() {
433 return llvm::Attribute::SwiftError;
434 }
435};
436struct SwiftSelfAttr : EnumAttr {
437 static enum Attribute::AttrKind getKind() {
438 return llvm::Attribute::SwiftSelf;
439 }
440};
441struct UWTableAttr : EnumAttr {
442 static enum Attribute::AttrKind getKind() {
443 return llvm::Attribute::UWTable;
444 }
445};
446struct WriteOnlyAttr : EnumAttr {
447 static enum Attribute::AttrKind getKind() {
448 return llvm::Attribute::WriteOnly;
449 }
450};
451struct ZExtAttr : EnumAttr {
452 static enum Attribute::AttrKind getKind() {
453 return llvm::Attribute::ZExt;
454 }
455};
456
457// StrBoolAttr classes
458struct LessPreciseFPMADAttr : StrBoolAttr {
459 static StringRef getKind() {
460 return "less-precise-fpmad";
461 }
462};
463struct NoInfsFPMathAttr : StrBoolAttr {
464 static StringRef getKind() {
465 return "no-infs-fp-math";
466 }
467};
468struct NoJumpTablesAttr : StrBoolAttr {
469 static StringRef getKind() {
470 return "no-jump-tables";
471 }
472};
473struct NoNansFPMathAttr : StrBoolAttr {
474 static StringRef getKind() {
475 return "no-nans-fp-math";
476 }
477};
478struct ProfileSampleAccurateAttr : StrBoolAttr {
479 static StringRef getKind() {
480 return "profile-sample-accurate";
481 }
482};
483struct UnsafeFPMathAttr : StrBoolAttr {
484 static StringRef getKind() {
485 return "unsafe-fp-math";
486 }
487};
488
489static inline bool hasCompatibleFnAttrs(const Function &Caller,
490 const Function &Callee) {
491 bool Ret = true;
492
493 Ret &= isEqual<SanitizeAddressAttr>(Caller, Callee);
494 Ret &= isEqual<SanitizeThreadAttr>(Caller, Callee);
495 Ret &= isEqual<SanitizeMemoryAttr>(Caller, Callee);
496 Ret &= isEqual<SanitizeHWAddressAttr>(Caller, Callee);
497 Ret &= isEqual<SafeStackAttr>(Caller, Callee);
498 Ret &= isEqual<ShadowCallStackAttr>(Caller, Callee);
499
500 return Ret;
501}
502
503static inline void mergeFnAttrs(Function &Caller,
504 const Function &Callee) {
505 setOR<NoImplicitFloatAttr>(Caller, Callee);
506 setOR<NoJumpTablesAttr>(Caller, Callee);
507 setOR<ProfileSampleAccurateAttr>(Caller, Callee);
508 setOR<SpeculativeLoadHardeningAttr>(Caller, Callee);
509 adjustCallerSSPLevel(Caller, Callee);
510 adjustCallerStackProbes(Caller, Callee);
511 adjustCallerStackProbeSize(Caller, Callee);
512 adjustMinLegalVectorWidth(Caller, Callee);
513 adjustNullPointerValidAttr(Caller, Callee);
514 setAND<LessPreciseFPMADAttr>(Caller, Callee);
515 setAND<NoInfsFPMathAttr>(Caller, Callee);
516 setAND<NoNansFPMathAttr>(Caller, Callee);
517 setAND<UnsafeFPMathAttr>(Caller, Callee);
518}
519
520#endif
521