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