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