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