1 #ifdef GET_ATTR_ENUM 2 #undef GET_ATTR_ENUM 3 Alignment, 4 AllocSize, 5 AlwaysInline, 6 ArgMemOnly, 7 Builtin, 8 ByVal, 9 Cold, 10 Convergent, 11 Dereferenceable, 12 DereferenceableOrNull, 13 InAlloca, 14 InReg, 15 InaccessibleMemOnly, 16 InaccessibleMemOrArgMemOnly, 17 InlineHint, 18 JumpTable, 19 MinSize, 20 Naked, 21 Nest, 22 NoAlias, 23 NoBuiltin, 24 NoCapture, 25 NoCfCheck, 26 NoDuplicate, 27 NoImplicitFloat, 28 NoInline, 29 NoRecurse, 30 NoRedZone, 31 NoReturn, 32 NoUnwind, 33 NonLazyBind, 34 NonNull, 35 OptForFuzzing, 36 OptimizeForSize, 37 OptimizeNone, 38 ReadNone, 39 ReadOnly, 40 Returned, 41 ReturnsTwice, 42 SExt, 43 SafeStack, 44 SanitizeAddress, 45 SanitizeHWAddress, 46 SanitizeMemory, 47 SanitizeThread, 48 ShadowCallStack, 49 Speculatable, 50 StackAlignment, 51 StackProtect, 52 StackProtectReq, 53 StackProtectStrong, 54 StrictFP, 55 StructRet, 56 SwiftError, 57 SwiftSelf, 58 UWTable, 59 WriteOnly, 60 ZExt, 61 #endif 62 #ifdef GET_ATTR_KIND_FROM_NAME 63 #undef GET_ATTR_KIND_FROM_NAME 64 static 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 130 struct 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 145 struct 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 159 struct AlignmentAttr : EnumAttr { 160 static enum Attribute::AttrKind getKind() { 161 return llvm::Attribute::Alignment; 162 } 163 }; 164 struct AllocSizeAttr : EnumAttr { 165 static enum Attribute::AttrKind getKind() { 166 return llvm::Attribute::AllocSize; 167 } 168 }; 169 struct AlwaysInlineAttr : EnumAttr { 170 static enum Attribute::AttrKind getKind() { 171 return llvm::Attribute::AlwaysInline; 172 } 173 }; 174 struct ArgMemOnlyAttr : EnumAttr { 175 static enum Attribute::AttrKind getKind() { 176 return llvm::Attribute::ArgMemOnly; 177 } 178 }; 179 struct BuiltinAttr : EnumAttr { 180 static enum Attribute::AttrKind getKind() { 181 return llvm::Attribute::Builtin; 182 } 183 }; 184 struct ByValAttr : EnumAttr { 185 static enum Attribute::AttrKind getKind() { 186 return llvm::Attribute::ByVal; 187 } 188 }; 189 struct ColdAttr : EnumAttr { 190 static enum Attribute::AttrKind getKind() { 191 return llvm::Attribute::Cold; 192 } 193 }; 194 struct ConvergentAttr : EnumAttr { 195 static enum Attribute::AttrKind getKind() { 196 return llvm::Attribute::Convergent; 197 } 198 }; 199 struct DereferenceableAttr : EnumAttr { 200 static enum Attribute::AttrKind getKind() { 201 return llvm::Attribute::Dereferenceable; 202 } 203 }; 204 struct DereferenceableOrNullAttr : EnumAttr { 205 static enum Attribute::AttrKind getKind() { 206 return llvm::Attribute::DereferenceableOrNull; 207 } 208 }; 209 struct InAllocaAttr : EnumAttr { 210 static enum Attribute::AttrKind getKind() { 211 return llvm::Attribute::InAlloca; 212 } 213 }; 214 struct InRegAttr : EnumAttr { 215 static enum Attribute::AttrKind getKind() { 216 return llvm::Attribute::InReg; 217 } 218 }; 219 struct InaccessibleMemOnlyAttr : EnumAttr { 220 static enum Attribute::AttrKind getKind() { 221 return llvm::Attribute::InaccessibleMemOnly; 222 } 223 }; 224 struct InaccessibleMemOrArgMemOnlyAttr : EnumAttr { 225 static enum Attribute::AttrKind getKind() { 226 return llvm::Attribute::InaccessibleMemOrArgMemOnly; 227 } 228 }; 229 struct InlineHintAttr : EnumAttr { 230 static enum Attribute::AttrKind getKind() { 231 return llvm::Attribute::InlineHint; 232 } 233 }; 234 struct JumpTableAttr : EnumAttr { 235 static enum Attribute::AttrKind getKind() { 236 return llvm::Attribute::JumpTable; 237 } 238 }; 239 struct MinSizeAttr : EnumAttr { 240 static enum Attribute::AttrKind getKind() { 241 return llvm::Attribute::MinSize; 242 } 243 }; 244 struct NakedAttr : EnumAttr { 245 static enum Attribute::AttrKind getKind() { 246 return llvm::Attribute::Naked; 247 } 248 }; 249 struct NestAttr : EnumAttr { 250 static enum Attribute::AttrKind getKind() { 251 return llvm::Attribute::Nest; 252 } 253 }; 254 struct NoAliasAttr : EnumAttr { 255 static enum Attribute::AttrKind getKind() { 256 return llvm::Attribute::NoAlias; 257 } 258 }; 259 struct NoBuiltinAttr : EnumAttr { 260 static enum Attribute::AttrKind getKind() { 261 return llvm::Attribute::NoBuiltin; 262 } 263 }; 264 struct NoCaptureAttr : EnumAttr { 265 static enum Attribute::AttrKind getKind() { 266 return llvm::Attribute::NoCapture; 267 } 268 }; 269 struct NoCfCheckAttr : EnumAttr { 270 static enum Attribute::AttrKind getKind() { 271 return llvm::Attribute::NoCfCheck; 272 } 273 }; 274 struct NoDuplicateAttr : EnumAttr { 275 static enum Attribute::AttrKind getKind() { 276 return llvm::Attribute::NoDuplicate; 277 } 278 }; 279 struct NoImplicitFloatAttr : EnumAttr { 280 static enum Attribute::AttrKind getKind() { 281 return llvm::Attribute::NoImplicitFloat; 282 } 283 }; 284 struct NoInlineAttr : EnumAttr { 285 static enum Attribute::AttrKind getKind() { 286 return llvm::Attribute::NoInline; 287 } 288 }; 289 struct NoRecurseAttr : EnumAttr { 290 static enum Attribute::AttrKind getKind() { 291 return llvm::Attribute::NoRecurse; 292 } 293 }; 294 struct NoRedZoneAttr : EnumAttr { 295 static enum Attribute::AttrKind getKind() { 296 return llvm::Attribute::NoRedZone; 297 } 298 }; 299 struct NoReturnAttr : EnumAttr { 300 static enum Attribute::AttrKind getKind() { 301 return llvm::Attribute::NoReturn; 302 } 303 }; 304 struct NoUnwindAttr : EnumAttr { 305 static enum Attribute::AttrKind getKind() { 306 return llvm::Attribute::NoUnwind; 307 } 308 }; 309 struct NonLazyBindAttr : EnumAttr { 310 static enum Attribute::AttrKind getKind() { 311 return llvm::Attribute::NonLazyBind; 312 } 313 }; 314 struct NonNullAttr : EnumAttr { 315 static enum Attribute::AttrKind getKind() { 316 return llvm::Attribute::NonNull; 317 } 318 }; 319 struct OptForFuzzingAttr : EnumAttr { 320 static enum Attribute::AttrKind getKind() { 321 return llvm::Attribute::OptForFuzzing; 322 } 323 }; 324 struct OptimizeForSizeAttr : EnumAttr { 325 static enum Attribute::AttrKind getKind() { 326 return llvm::Attribute::OptimizeForSize; 327 } 328 }; 329 struct OptimizeNoneAttr : EnumAttr { 330 static enum Attribute::AttrKind getKind() { 331 return llvm::Attribute::OptimizeNone; 332 } 333 }; 334 struct ReadNoneAttr : EnumAttr { 335 static enum Attribute::AttrKind getKind() { 336 return llvm::Attribute::ReadNone; 337 } 338 }; 339 struct ReadOnlyAttr : EnumAttr { 340 static enum Attribute::AttrKind getKind() { 341 return llvm::Attribute::ReadOnly; 342 } 343 }; 344 struct ReturnedAttr : EnumAttr { 345 static enum Attribute::AttrKind getKind() { 346 return llvm::Attribute::Returned; 347 } 348 }; 349 struct ReturnsTwiceAttr : EnumAttr { 350 static enum Attribute::AttrKind getKind() { 351 return llvm::Attribute::ReturnsTwice; 352 } 353 }; 354 struct SExtAttr : EnumAttr { 355 static enum Attribute::AttrKind getKind() { 356 return llvm::Attribute::SExt; 357 } 358 }; 359 struct SafeStackAttr : EnumAttr { 360 static enum Attribute::AttrKind getKind() { 361 return llvm::Attribute::SafeStack; 362 } 363 }; 364 struct SanitizeAddressAttr : EnumAttr { 365 static enum Attribute::AttrKind getKind() { 366 return llvm::Attribute::SanitizeAddress; 367 } 368 }; 369 struct SanitizeHWAddressAttr : EnumAttr { 370 static enum Attribute::AttrKind getKind() { 371 return llvm::Attribute::SanitizeHWAddress; 372 } 373 }; 374 struct SanitizeMemoryAttr : EnumAttr { 375 static enum Attribute::AttrKind getKind() { 376 return llvm::Attribute::SanitizeMemory; 377 } 378 }; 379 struct SanitizeThreadAttr : EnumAttr { 380 static enum Attribute::AttrKind getKind() { 381 return llvm::Attribute::SanitizeThread; 382 } 383 }; 384 struct ShadowCallStackAttr : EnumAttr { 385 static enum Attribute::AttrKind getKind() { 386 return llvm::Attribute::ShadowCallStack; 387 } 388 }; 389 struct SpeculatableAttr : EnumAttr { 390 static enum Attribute::AttrKind getKind() { 391 return llvm::Attribute::Speculatable; 392 } 393 }; 394 struct StackAlignmentAttr : EnumAttr { 395 static enum Attribute::AttrKind getKind() { 396 return llvm::Attribute::StackAlignment; 397 } 398 }; 399 struct StackProtectAttr : EnumAttr { 400 static enum Attribute::AttrKind getKind() { 401 return llvm::Attribute::StackProtect; 402 } 403 }; 404 struct StackProtectReqAttr : EnumAttr { 405 static enum Attribute::AttrKind getKind() { 406 return llvm::Attribute::StackProtectReq; 407 } 408 }; 409 struct StackProtectStrongAttr : EnumAttr { 410 static enum Attribute::AttrKind getKind() { 411 return llvm::Attribute::StackProtectStrong; 412 } 413 }; 414 struct StrictFPAttr : EnumAttr { 415 static enum Attribute::AttrKind getKind() { 416 return llvm::Attribute::StrictFP; 417 } 418 }; 419 struct StructRetAttr : EnumAttr { 420 static enum Attribute::AttrKind getKind() { 421 return llvm::Attribute::StructRet; 422 } 423 }; 424 struct SwiftErrorAttr : EnumAttr { 425 static enum Attribute::AttrKind getKind() { 426 return llvm::Attribute::SwiftError; 427 } 428 }; 429 struct SwiftSelfAttr : EnumAttr { 430 static enum Attribute::AttrKind getKind() { 431 return llvm::Attribute::SwiftSelf; 432 } 433 }; 434 struct UWTableAttr : EnumAttr { 435 static enum Attribute::AttrKind getKind() { 436 return llvm::Attribute::UWTable; 437 } 438 }; 439 struct WriteOnlyAttr : EnumAttr { 440 static enum Attribute::AttrKind getKind() { 441 return llvm::Attribute::WriteOnly; 442 } 443 }; 444 struct ZExtAttr : EnumAttr { 445 static enum Attribute::AttrKind getKind() { 446 return llvm::Attribute::ZExt; 447 } 448 }; 449 450 // StrBoolAttr classes 451 struct LessPreciseFPMADAttr : StrBoolAttr { 452 static StringRef getKind() { 453 return "less-precise-fpmad"; 454 } 455 }; 456 struct NoInfsFPMathAttr : StrBoolAttr { 457 static StringRef getKind() { 458 return "no-infs-fp-math"; 459 } 460 }; 461 struct NoJumpTablesAttr : StrBoolAttr { 462 static StringRef getKind() { 463 return "no-jump-tables"; 464 } 465 }; 466 struct NoNansFPMathAttr : StrBoolAttr { 467 static StringRef getKind() { 468 return "no-nans-fp-math"; 469 } 470 }; 471 struct ProfileSampleAccurateAttr : StrBoolAttr { 472 static StringRef getKind() { 473 return "profile-sample-accurate"; 474 } 475 }; 476 struct UnsafeFPMathAttr : StrBoolAttr { 477 static StringRef getKind() { 478 return "unsafe-fp-math"; 479 } 480 }; 481 482 static 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 496 static 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