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