1 /// Attribute base class. 2 class Attr<string S> { 3 // String representation of this attribute in the IR. 4 string AttrString = S; 5 } 6 7 /// Enum attribute. 8 class EnumAttr<string S> : Attr<S>; 9 10 /// StringBool attribute. 11 class StrBoolAttr<string S> : Attr<S>; 12 13 /// Target-independent enum attributes. 14 15 /// Alignment of parameter (5 bits) stored as log2 of alignment with +1 bias. 16 /// 0 means unaligned (different from align(1)). 17 def Alignment : EnumAttr<"align">; 18 19 /// The result of the function is guaranteed to point to a number of bytes that 20 /// we can determine if we know the value of the function's arguments. 21 def AllocSize : EnumAttr<"allocsize">; 22 23 /// inline=always. 24 def AlwaysInline : EnumAttr<"alwaysinline">; 25 26 /// Function can access memory only using pointers based on its arguments. 27 def ArgMemOnly : EnumAttr<"argmemonly">; 28 29 /// Callee is recognized as a builtin, despite nobuiltin attribute on its 30 /// declaration. 31 def Builtin : EnumAttr<"builtin">; 32 33 /// Pass structure by value. 34 def ByVal : EnumAttr<"byval">; 35 36 /// Marks function as being in a cold path. 37 def Cold : EnumAttr<"cold">; 38 39 /// Can only be moved to control-equivalent blocks. 40 def Convergent : EnumAttr<"convergent">; 41 42 /// Pointer is known to be dereferenceable. 43 def Dereferenceable : EnumAttr<"dereferenceable">; 44 45 /// Pointer is either null or dereferenceable. 46 def DereferenceableOrNull : EnumAttr<"dereferenceable_or_null">; 47 48 /// Function may only access memory that is inaccessible from IR. 49 def InaccessibleMemOnly : EnumAttr<"inaccessiblememonly">; 50 51 /// Function may only access memory that is either inaccessible from the IR, 52 /// or pointed to by its pointer arguments. 53 def InaccessibleMemOrArgMemOnly : EnumAttr<"inaccessiblemem_or_argmemonly">; 54 55 /// Pass structure in an alloca. 56 def InAlloca : EnumAttr<"inalloca">; 57 58 /// Source said inlining was desirable. 59 def InlineHint : EnumAttr<"inlinehint">; 60 61 /// Force argument to be passed in register. 62 def InReg : EnumAttr<"inreg">; 63 64 /// Build jump-instruction tables and replace refs. 65 def JumpTable : EnumAttr<"jumptable">; 66 67 /// Function must be optimized for size first. 68 def MinSize : EnumAttr<"minsize">; 69 70 /// Naked function. 71 def Naked : EnumAttr<"naked">; 72 73 /// Nested function static chain. 74 def Nest : EnumAttr<"nest">; 75 76 /// Considered to not alias after call. 77 def NoAlias : EnumAttr<"noalias">; 78 79 /// Callee isn't recognized as a builtin. 80 def NoBuiltin : EnumAttr<"nobuiltin">; 81 82 /// Function creates no aliases of pointer. 83 def NoCapture : EnumAttr<"nocapture">; 84 85 /// Call cannot be duplicated. 86 def NoDuplicate : EnumAttr<"noduplicate">; 87 88 /// Disable implicit floating point insts. 89 def NoImplicitFloat : EnumAttr<"noimplicitfloat">; 90 91 /// inline=never. 92 def NoInline : EnumAttr<"noinline">; 93 94 /// Function is called early and/or often, so lazy binding isn't worthwhile. 95 def NonLazyBind : EnumAttr<"nonlazybind">; 96 97 /// Pointer is known to be not null. 98 def NonNull : EnumAttr<"nonnull">; 99 100 /// The function does not recurse. 101 def NoRecurse : EnumAttr<"norecurse">; 102 103 /// Disable redzone. 104 def NoRedZone : EnumAttr<"noredzone">; 105 106 /// Mark the function as not returning. 107 def NoReturn : EnumAttr<"noreturn">; 108 109 /// Function doesn't unwind stack. 110 def NoUnwind : EnumAttr<"nounwind">; 111 112 /// opt_size. 113 def OptimizeForSize : EnumAttr<"optsize">; 114 115 /// Function must not be optimized. 116 def OptimizeNone : EnumAttr<"optnone">; 117 118 /// Function does not access memory. 119 def ReadNone : EnumAttr<"readnone">; 120 121 /// Function only reads from memory. 122 def ReadOnly : EnumAttr<"readonly">; 123 124 /// Return value is always equal to this argument. 125 def Returned : EnumAttr<"returned">; 126 127 /// Function can return twice. 128 def ReturnsTwice : EnumAttr<"returns_twice">; 129 130 /// Safe Stack protection. 131 def SafeStack : EnumAttr<"safestack">; 132 133 /// Sign extended before/after call. 134 def SExt : EnumAttr<"signext">; 135 136 /// Alignment of stack for function (3 bits) stored as log2 of alignment with 137 /// +1 bias 0 means unaligned (different from alignstack=(1)). 138 def StackAlignment : EnumAttr<"alignstack">; 139 140 /// Function can be speculated. 141 def Speculatable : EnumAttr<"speculatable">; 142 143 /// Stack protection. 144 def StackProtect : EnumAttr<"ssp">; 145 146 /// Stack protection required. 147 def StackProtectReq : EnumAttr<"sspreq">; 148 149 /// Strong Stack protection. 150 def StackProtectStrong : EnumAttr<"sspstrong">; 151 152 /// Function was called in a scope requiring strict floating point semantics. 153 def StrictFP : EnumAttr<"strictfp">; 154 155 /// Hidden pointer to structure to return. 156 def StructRet : EnumAttr<"sret">; 157 158 /// AddressSanitizer is on. 159 def SanitizeAddress : EnumAttr<"sanitize_address">; 160 161 /// ThreadSanitizer is on. 162 def SanitizeThread : EnumAttr<"sanitize_thread">; 163 164 /// MemorySanitizer is on. 165 def SanitizeMemory : EnumAttr<"sanitize_memory">; 166 167 /// Argument is swift error. 168 def SwiftError : EnumAttr<"swifterror">; 169 170 /// Argument is swift self/context. 171 def SwiftSelf : EnumAttr<"swiftself">; 172 173 /// Function must be in a unwind table. 174 def UWTable : EnumAttr<"uwtable">; 175 176 /// Function only writes to memory. 177 def WriteOnly : EnumAttr<"writeonly">; 178 179 /// Zero extended before/after call. 180 def ZExt : EnumAttr<"zeroext">; 181 182 /// Target-independent string attributes. 183 def LessPreciseFPMAD : StrBoolAttr<"less-precise-fpmad">; 184 def NoInfsFPMath : StrBoolAttr<"no-infs-fp-math">; 185 def NoNansFPMath : StrBoolAttr<"no-nans-fp-math">; 186 def UnsafeFPMath : StrBoolAttr<"unsafe-fp-math">; 187 def NoJumpTables : StrBoolAttr<"no-jump-tables">; 188 def ProfileSampleAccurate : StrBoolAttr<"profile-sample-accurate">; 189 190 class CompatRule<string F> { 191 // The name of the function called to check the attribute of the caller and 192 // callee and decide whether inlining should be allowed. The function's 193 // signature must match "bool(const Function&, const Function &)", where the 194 // first parameter is the reference to the caller and the second parameter is 195 // the reference to the callee. It must return false if the attributes of the 196 // caller and callee are incompatible, and true otherwise. 197 string CompatFunc = F; 198 } 199 200 def : CompatRule<"isEqual<SanitizeAddressAttr>">; 201 def : CompatRule<"isEqual<SanitizeThreadAttr>">; 202 def : CompatRule<"isEqual<SanitizeMemoryAttr>">; 203 def : CompatRule<"isEqual<SafeStackAttr>">; 204 205 class MergeRule<string F> { 206 // The name of the function called to merge the attributes of the caller and 207 // callee. The function's signature must match 208 // "void(Function&, const Function &)", where the first parameter is the 209 // reference to the caller and the second parameter is the reference to the 210 // callee. 211 string MergeFunc = F; 212 } 213 214 def : MergeRule<"setAND<LessPreciseFPMADAttr>">; 215 def : MergeRule<"setAND<NoInfsFPMathAttr>">; 216 def : MergeRule<"setAND<NoNansFPMathAttr>">; 217 def : MergeRule<"setAND<UnsafeFPMathAttr>">; 218 def : MergeRule<"setOR<NoImplicitFloatAttr>">; 219 def : MergeRule<"setOR<NoJumpTablesAttr>">; 220 def : MergeRule<"setOR<ProfileSampleAccurateAttr>">; 221 def : MergeRule<"adjustCallerSSPLevel">; 222 def : MergeRule<"adjustCallerStackProbes">; 223 def : MergeRule<"adjustCallerStackProbeSize">; 224