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