1/// Attribute base class. 2class Attr<string S> { 3 // String representation of this attribute in the IR. 4 string AttrString = S; 5} 6 7/// Enum attribute. 8class EnumAttr<string S> : Attr<S>; 9 10/// Int attribute. 11class IntAttr<string S> : Attr<S>; 12 13/// StringBool attribute. 14class StrBoolAttr<string S> : Attr<S>; 15 16/// Type attribute. 17class TypeAttr<string S> : Attr<S>; 18 19/// Target-independent enum attributes. 20 21/// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias. 22/// 0 means unaligned (different from align(1)). 23def Alignment : IntAttr<"align">; 24 25/// The result of the function is guaranteed to point to a number of bytes that 26/// we can determine if we know the value of the function's arguments. 27def AllocSize : IntAttr<"allocsize">; 28 29/// inline=always. 30def AlwaysInline : EnumAttr<"alwaysinline">; 31 32/// Function can access memory only using pointers based on its arguments. 33def ArgMemOnly : EnumAttr<"argmemonly">; 34 35/// Callee is recognized as a builtin, despite nobuiltin attribute on its 36/// declaration. 37def Builtin : EnumAttr<"builtin">; 38 39/// Pass structure by value. 40def ByVal : TypeAttr<"byval">; 41 42/// Parameter or return value may not contain uninitialized or poison bits. 43def NoUndef : EnumAttr<"noundef">; 44 45/// Marks function as being in a cold path. 46def Cold : EnumAttr<"cold">; 47 48/// Can only be moved to control-equivalent blocks. 49def Convergent : EnumAttr<"convergent">; 50 51/// Pointer is known to be dereferenceable. 52def Dereferenceable : IntAttr<"dereferenceable">; 53 54/// Pointer is either null or dereferenceable. 55def DereferenceableOrNull : IntAttr<"dereferenceable_or_null">; 56 57/// Function may only access memory that is inaccessible from IR. 58def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">; 59 60/// Function may only access memory that is either inaccessible from the IR, 61/// or pointed to by its pointer arguments. 62def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly">; 63 64/// Pass structure in an alloca. 65def InAlloca : EnumAttr<"inalloca">; 66 67/// Source said inlining was desirable. 68def InlineHint : EnumAttr<"inlinehint">; 69 70/// Force argument to be passed in register. 71def InReg : EnumAttr<"inreg">; 72 73/// Build jump-instruction tables and replace refs. 74def JumpTable : EnumAttr<"jumptable">; 75 76/// Function must be optimized for size first. 77def MinSize : EnumAttr<"minsize">; 78 79/// Naked function. 80def Naked : EnumAttr<"naked">; 81 82/// Nested function static chain. 83def Nest : EnumAttr<"nest">; 84 85/// Considered to not alias after call. 86def NoAlias : EnumAttr<"noalias">; 87 88/// Callee isn't recognized as a builtin. 89def NoBuiltin : EnumAttr<"nobuiltin">; 90 91/// Function creates no aliases of pointer. 92def NoCapture : EnumAttr<"nocapture">; 93 94/// Call cannot be duplicated. 95def NoDuplicate : EnumAttr<"noduplicate">; 96 97/// Function does not deallocate memory. 98def NoFree : EnumAttr<"nofree">; 99 100/// Disable implicit floating point insts. 101def NoImplicitFloat : EnumAttr<"noimplicitfloat">; 102 103/// inline=never. 104def NoInline : EnumAttr<"noinline">; 105 106/// Function is called early and/or often, so lazy binding isn't worthwhile. 107def NonLazyBind : EnumAttr<"nonlazybind">; 108 109/// Disable merging for call sites 110def NoMerge : EnumAttr<"nomerge">; 111 112/// Pointer is known to be not null. 113def NonNull : EnumAttr<"nonnull">; 114 115/// The function does not recurse. 116def NoRecurse : EnumAttr<"norecurse">; 117 118/// Disable redzone. 119def NoRedZone : EnumAttr<"noredzone">; 120 121/// Mark the function as not returning. 122def NoReturn : EnumAttr<"noreturn">; 123 124/// Function does not synchronize. 125def NoSync : EnumAttr<"nosync">; 126 127/// Disable Indirect Branch Tracking. 128def NoCfCheck : EnumAttr<"nocf_check">; 129 130/// Function doesn't unwind stack. 131def NoUnwind : EnumAttr<"nounwind">; 132 133/// Null pointer in address space zero is valid. 134def NullPointerIsValid : EnumAttr<"null_pointer_is_valid">; 135 136/// Select optimizations for best fuzzing signal. 137def OptForFuzzing : EnumAttr<"optforfuzzing">; 138 139/// opt_size. 140def OptimizeForSize : EnumAttr<"optsize">; 141 142/// Function must not be optimized. 143def OptimizeNone : EnumAttr<"optnone">; 144 145/// Similar to byval but without a copy. 146def Preallocated : TypeAttr<"preallocated">; 147 148/// Function does not access memory. 149def ReadNone : EnumAttr<"readnone">; 150 151/// Function only reads from memory. 152def ReadOnly : EnumAttr<"readonly">; 153 154/// Return value is always equal to this argument. 155def Returned : EnumAttr<"returned">; 156 157/// Parameter is required to be a trivial constant. 158def ImmArg : EnumAttr<"immarg">; 159 160/// Function can return twice. 161def ReturnsTwice : EnumAttr<"returns_twice">; 162 163/// Safe Stack protection. 164def SafeStack : EnumAttr<"safestack">; 165 166/// Shadow Call Stack protection. 167def ShadowCallStack : EnumAttr<"shadowcallstack">; 168 169/// Sign extended before/after call. 170def SExt : EnumAttr<"signext">; 171 172/// Alignment of stack for function (3 bits) stored as log2 of alignment with 173/// +1 bias 0 means unaligned (different from alignstack=(1)). 174def StackAlignment : IntAttr<"alignstack">; 175 176/// Function can be speculated. 177def Speculatable : EnumAttr<"speculatable">; 178 179/// Stack protection. 180def StackProtect : EnumAttr<"ssp">; 181 182/// Stack protection required. 183def StackProtectReq : EnumAttr<"sspreq">; 184 185/// Strong Stack protection. 186def StackProtectStrong : EnumAttr<"sspstrong">; 187 188/// Function was called in a scope requiring strict floating point semantics. 189def StrictFP : EnumAttr<"strictfp">; 190 191/// Hidden pointer to structure to return. 192def StructRet : EnumAttr<"sret">; 193 194/// AddressSanitizer is on. 195def SanitizeAddress : EnumAttr<"sanitize_address">; 196 197/// ThreadSanitizer is on. 198def SanitizeThread : EnumAttr<"sanitize_thread">; 199 200/// MemorySanitizer is on. 201def SanitizeMemory : EnumAttr<"sanitize_memory">; 202 203/// HWAddressSanitizer is on. 204def SanitizeHWAddress : EnumAttr<"sanitize_hwaddress">; 205 206/// MemTagSanitizer is on. 207def SanitizeMemTag : EnumAttr<"sanitize_memtag">; 208 209/// Speculative Load Hardening is enabled. 210/// 211/// Note that this uses the default compatibility (always compatible during 212/// inlining) and a conservative merge strategy where inlining an attributed 213/// body will add the attribute to the caller. This ensures that code carrying 214/// this attribute will always be lowered with hardening enabled. 215def SpeculativeLoadHardening : EnumAttr<"speculative_load_hardening">; 216 217/// Argument is swift error. 218def SwiftError : EnumAttr<"swifterror">; 219 220/// Argument is swift self/context. 221def SwiftSelf : EnumAttr<"swiftself">; 222 223/// Function must be in a unwind table. 224def UWTable : EnumAttr<"uwtable">; 225 226/// Function always comes back to callsite. 227def WillReturn : EnumAttr<"willreturn">; 228 229/// Function only writes to memory. 230def WriteOnly : EnumAttr<"writeonly">; 231 232/// Zero extended before/after call. 233def ZExt : EnumAttr<"zeroext">; 234 235/// Target-independent string attributes. 236def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">; 237def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">; 238def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">; 239def NoSignedZerosFPMath : StrBoolAttr<"no-signed-zeros-fp-math">; 240def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">; 241def NoJumpTables : StrBoolAttr<"no-jump-tables">; 242def NoInlineLineTables : StrBoolAttr<"no-inline-line-tables">; 243def ProfileSampleAccurate : StrBoolAttr<"profile-sample-accurate">; 244def UseSampleProfile : StrBoolAttr<"use-sample-profile">; 245 246class CompatRule<string F> { 247 // The name of the function called to check the attribute of the caller and 248 // callee and decide whether inlining should be allowed. The function's 249 // signature must match "bool(const Function&, const Function &)", where the 250 // first parameter is the reference to the caller and the second parameter is 251 // the reference to the callee. It must return false if the attributes of the 252 // caller and callee are incompatible, and true otherwise. 253 string CompatFunc = F; 254} 255 256def : CompatRule<"isEqual<SanitizeAddressAttr>">; 257def : CompatRule<"isEqual<SanitizeThreadAttr>">; 258def : CompatRule<"isEqual<SanitizeMemoryAttr>">; 259def : CompatRule<"isEqual<SanitizeHWAddressAttr>">; 260def : CompatRule<"isEqual<SanitizeMemTagAttr>">; 261def : CompatRule<"isEqual<SafeStackAttr>">; 262def : CompatRule<"isEqual<ShadowCallStackAttr>">; 263def : CompatRule<"isEqual<UseSampleProfileAttr>">; 264 265class MergeRule<string F> { 266 // The name of the function called to merge the attributes of the caller and 267 // callee. The function's signature must match 268 // "void(Function&, const Function &)", where the first parameter is the 269 // reference to the caller and the second parameter is the reference to the 270 // callee. 271 string MergeFunc = F; 272} 273 274def : MergeRule<"setAND<LessPreciseFPMADAttr>">; 275def : MergeRule<"setAND<NoInfsFPMathAttr>">; 276def : MergeRule<"setAND<NoNansFPMathAttr>">; 277def : MergeRule<"setAND<NoSignedZerosFPMathAttr>">; 278def : MergeRule<"setAND<UnsafeFPMathAttr>">; 279def : MergeRule<"setOR<NoImplicitFloatAttr>">; 280def : MergeRule<"setOR<NoJumpTablesAttr>">; 281def : MergeRule<"setOR<ProfileSampleAccurateAttr>">; 282def : MergeRule<"setOR<SpeculativeLoadHardeningAttr>">; 283def : MergeRule<"adjustCallerSSPLevel">; 284def : MergeRule<"adjustCallerStackProbes">; 285def : MergeRule<"adjustCallerStackProbeSize">; 286def : MergeRule<"adjustMinLegalVectorWidth">; 287def : MergeRule<"adjustNullPointerValidAttr">; 288