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 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