Home | History | Annotate | Download | only in IR
      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