1 /** 2 * Contains compiler-recognized user-defined attribute types. 3 * 4 * Copyright: Authors 2015-2018 5 * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) 6 * Authors: LDC team 7 */ 8 module ldc.attributes; 9 10 /// Helper template 11 private template AliasSeq(TList...) 12 { 13 alias AliasSeq = TList; 14 } 15 16 /** 17 * Specifies that the function returns `null` or a pointer to at least a 18 * certain number of allocated bytes. `sizeArgIdx` and `numArgIdx` specify 19 * the 0-based index of the function arguments that should be used to calculate 20 * the number of bytes returned: 21 * 22 * bytes = arg[sizeArgIdx] * (numArgIdx < 0) ? arg[numArgIdx] : 1 23 * 24 * The optimizer may assume that an @allocSize function has no other side 25 * effects and that it is valid to eliminate calls to the function if the 26 * allocated memory is not used. The optimizer will eliminate all code from 27 * `foo` in this example: 28 * @allocSize(0) void* myAlloc(size_t size); 29 * void foo() { 30 * auto p = myAlloc(100); 31 * p[0] = 1; 32 * } 33 * 34 * See LLVM LangRef for more details: 35 * http://llvm.org/docs/LangRef.html#function-attributes 36 * 37 * This attribute has no effect for LLVM < 3.9. 38 * 39 * Example: 40 * --- 41 * import ldc.attributes; 42 * 43 * @allocSize(0) extern(C) void* malloc(size_t size); 44 * @allocSize(2,1) extern(C) void* reallocarray(void *ptr, size_t nmemb, 45 * size_t size); 46 * @allocSize(0,1) void* my_calloc(size_t element_size, size_t count, 47 * bool irrelevant); 48 * --- 49 */ 50 struct allocSize 51 { 52 int sizeArgIdx; 53 54 /// If numArgIdx < 0, there is no argument specifying the element count 55 int numArgIdx = int.min; 56 } 57 58 /++ 59 + When applied to a global symbol, the compiler, assembler, and linker are 60 + required to treat the symbol as if there is a reference to the symbol that 61 + it cannot see (which is why they have to be named). For example, it 62 + prevents the deletion by the linker of an unreferenced symbol. 63 + 64 + This attribute corresponds to “attribute((used))” in GNU C. 65 + 66 + Examples: 67 + --- 68 + import ldc.attributes; 69 + 70 + @assumeUsed int dont_remove; 71 + --- 72 +/ 73 immutable assumeUsed = _assumeUsed(); 74 private struct _assumeUsed 75 { 76 } 77 78 /++ 79 + Meant for expert use. Overrides the default calling convention. The supported 80 + names for calling conventions depends on the target. 81 + If specified multiple times, the last applied UDA is used. 82 + The calling convention is not part of the type of the function, which means that 83 + this attribute cannot be used in combination with function pointers (the function 84 + referenced by a function pointer will be called using the default calling convention). 85 + Semantic analysis does NOT (yet?) check for correctness. For example when 86 + this is applied to a class function, it is up to the user to ensure that the base 87 + function and all overrides (in child classes) have the same calling convention 88 + applied. 89 + 90 + Example (for X86): 91 + --- 92 + import ldc.attributes; 93 + 94 + @callingConvention("vectorcall"): // all functions in scope get this UDA 95 + 96 + int vector_call_convention() { return 42; } 97 + 98 + @callingConvention("default") // overrides the first UDA 99 + int func_with_default_calling_convention() { return 1; } 100 + --- 101 +/ 102 struct callingConvention 103 { 104 string convention; 105 } 106 107 /++ 108 + When applied to a function, marks this function for dynamic compilation. 109 + Calls to the function will be to the dynamically compiled function, 110 + instead of to the statically compiled function (the statically compiled 111 + function is still emitted into the object file). 112 + All functions marked with this attribute must be explicitly compiled in 113 + runtime via ldc.dynamic_compile api before usage. 114 + 115 + This attribute has no effect if dynamic compilation wasn't enabled with 116 + -enable-dynamic-compile 117 + 118 + Examples: 119 + --- 120 + import ldc.attributes; 121 + 122 + @dynamicCompile int foo() { return 42; } 123 + --- 124 +/ 125 immutable dynamicCompile = _dynamicCompile(); 126 private struct _dynamicCompile 127 { 128 } 129 130 /++ 131 + When applied to global variable, this variable will be treated as constant 132 + by any dynamically compiled functions and is subject to optimizations. 133 + All dynamically compiled functions must be recompiled after any update to 134 + such variable. 135 + 136 + This attribute has no effect if dynamic compilation wasn't enabled with 137 + -enable-dynamic-compile 138 + 139 + Examples: 140 + --- 141 + import ldc.attributes; 142 + 143 + @dynamicCompileConst __gshared int value = 1; 144 + 145 + @dynamicCompile int foo() { return value * 42; } 146 + --- 147 +/ 148 immutable dynamicCompileConst = _dynamicCompileConst(); 149 private struct _dynamicCompileConst 150 { 151 } 152 153 /++ 154 + When applied to a function, makes this function available for dynamic 155 + compilation. 156 + In contrast to `@dynamicCompile`, calls to the function will be to the 157 + statically compiled function (like normal functions). The function body 158 + is made available for dynamic compilation with the jit facilities (e.g. 159 + jit bind). 160 + If both @dynamicCompile and @dynamicCompileEmit attributes are 161 + applied to function, @dynamicCompile will get precedence. 162 + 163 + This attribute has no effect if dynamic compilation wasn't enabled with 164 + -enable-dynamic-compile 165 + 166 + Examples: 167 + --- 168 + import ldc.attributes; 169 + 170 + @dynamicCompileEmit int foo() { return 42; } 171 + --- 172 +/ 173 immutable dynamicCompileEmit = _dynamicCompileEmit(); 174 private struct _dynamicCompileEmit 175 { 176 } 177 178 /** 179 * Explicitly sets "fast math" for a function, enabling aggressive math 180 * optimizations. These optimizations may dramatically change the outcome of 181 * floating point calculations (e.g. because of reassociation). 182 * 183 * Example: 184 * --- 185 * import ldc.attributes; 186 * 187 * @fastmath 188 * double dot(double[] a, double[] b) { 189 * double s = 0; 190 * foreach(size_t i; 0..a.length) 191 * { 192 * // will result in vectorized fused-multiply-add instructions 193 * s += a * b; 194 * } 195 * return s; 196 * } 197 * --- 198 */ 199 alias fastmath = AliasSeq!(llvmAttr("unsafe-fp-math", "true"), llvmFastMathFlag("fast")); 200 201 /** 202 * Sets the visibility of a function or global variable to "hidden". 203 * Such symbols aren't directly accessible from outside the DSO 204 * (executable or DLL/.so/.dylib) and are resolved inside the DSO 205 * during linking. If unreferenced within the DSO, the linker can 206 * strip a hidden symbol. 207 * An `export` visibility overrides this attribute. 208 */ 209 immutable hidden = _hidden(); 210 private struct _hidden {} 211 212 /** 213 * Adds an LLVM attribute to a function, without checking the validity or 214 * applicability of the attribute. 215 * The attribute is specified as key-value pair: 216 * @llvmAttr("key", "value") 217 * If the value string is empty, just the key is added as attribute. 218 * 219 * Example: 220 * --- 221 * import ldc.attributes; 222 * 223 * @llvmAttr("unsafe-fp-math", "true") 224 * double dot(double[] a, double[] b) { 225 * double s = 0; 226 * foreach(size_t i; 0..a.length) 227 * { 228 * import ldc.llvmasm: __ir; 229 * s = __ir!(`%p = fmul fast double %0, %1 230 * %r = fadd fast double %p, %2 231 * ret double %r`, double)(a[i], b[i], s); 232 * } 233 * return s; 234 * } 235 * --- 236 */ 237 struct llvmAttr 238 { 239 string key; 240 string value; 241 } 242 243 /** 244 * Sets LLVM's fast-math flags for floating point operations in the function 245 * this attribute is applied to. 246 * See LLVM LangRef for possible values: 247 * http://llvm.org/docs/LangRef.html#fast-math-flags 248 * @llvmFastMathFlag("clear") clears all flags. 249 */ 250 struct llvmFastMathFlag 251 { 252 string flag; 253 } 254 255 /** 256 * Adds LLVM's "naked" attribute to a function, disabling function prologue / 257 * epilogue emission, incl. LDC's. 258 * Intended to be used in combination with a function body defined via 259 * ldc.llvmasm.__asm() and/or ldc.simd.inlineIR(). 260 */ 261 enum naked = llvmAttr("naked"); 262 263 /** 264 * Adds LLVM's "noalias" attribute to a function parameter, with semantics 265 * very similar to C99 "restrict". 266 * The parameter needs to boil down to a pointer, e.g., be a D pointer, class 267 * reference or a `ref` parameter. 268 */ 269 enum restrict = llvmAttr("noalias"); 270 271 /** 272 * Adds LLVM's "cold" attribute to a function, indicating that this function is 273 * rarely called. Control-flow paths calling cold functions are thus considered 274 * to be cold too. 275 */ 276 enum cold = llvmAttr("cold"); 277 278 /** 279 * Add LLVM's "nonlazybind" attribute to a function, suppresses lazy symbol binding. 280 * This may make calls to function faster, at the cost of extra program startup time 281 * if the function is not called during program startup. 282 */ 283 enum noplt = llvmAttr("nonlazybind"); 284 285 /** 286 * Disables a particular sanitizer for this function. 287 * Valid sanitizer names are all names accepted by `-fsanitize=` commandline option. 288 * Multiple sanitizers can be disabled by applying this UDA multiple times, e.g. 289 * `@noSanitize("address") `@noSanitize("thread")` to disable both ASan and TSan. 290 */ 291 struct noSanitize { 292 string sanitizerName; 293 } 294 295 /++ 296 + Disables split-stack instrumentation for this function, overriding the 297 + `-fsplit-stack` commandline function. 298 + 299 + Examples: 300 + --- 301 + import ldc.attributes; 302 + 303 + @noSplitStack int user_function() { return 1; } 304 + --- 305 +/ 306 immutable noSplitStack = _noSplitStack(); 307 private struct _noSplitStack 308 { 309 } 310 311 /** 312 * Sets the optimization strategy for a function. 313 * Valid strategies are "none", "optsize", "minsize". The strategies are mutually exclusive. 314 * 315 * @optStrategy("none") in particular is useful to selectively debug functions when a 316 * fully unoptimized program cannot be used (e.g. due to too low performance). 317 * 318 * Strategy "none": 319 * Disables most optimizations for a function. 320 * It implies `pragma(inline, false)`: the function is never inlined 321 * in a calling function, and the attribute cannot be combined with 322 * `pragma(inline, true)`. 323 * Functions with `pragma(inline, true)` are still candidates for inlining into 324 * the function. 325 * 326 * Strategy "optsize": 327 * Tries to keep the code size of the function low and does optimizations to 328 * reduce code size as long as they do not significantly impact runtime performance. 329 * 330 * Strategy "minsize": 331 * Tries to keep the code size of the function low and does optimizations to 332 * reduce code size that may reduce runtime performance. 333 */ 334 struct optStrategy { 335 string strategy; 336 } 337 338 /++ 339 + When applied to a function, specifies that the function should be optimzed by 340 + Polly, LLVM's polyhedral optimizer. Useful for optimizing loops for data locatily, 341 + vectorization and parallelism. 342 + 343 + Experimental! 344 + 345 + Only effective when LDC was built with Polly included. 346 +/ 347 348 immutable polly = _polly(); 349 private struct _polly 350 { 351 } 352 353 /** 354 * When applied to a global variable or function, causes it to be emitted to a 355 * non-standard object file/executable section. 356 * 357 * The target platform might impose certain restrictions on the format for 358 * section names. 359 * 360 * Examples: 361 * --- 362 * import ldc.attributes; 363 * 364 * @section(".mySection") int myGlobal; 365 * --- 366 */ 367 struct section 368 { 369 string name; 370 } 371 372 /** 373 * When applied to a function, specifies that the function should be compiled 374 * with different target options than on the command line. 375 * 376 * The passed string should be a comma-separated list of options. The options 377 * are passed to LLVM by adding them to the "target-features" function 378 * attribute, after minor processing: negative options (e.g. "no-sse") have the 379 * "no" stripped (--> "-sse"), whereas positive options (e.g. sse") gain a 380 * leading "+" (--> "+sse"). Negative options override positive options 381 * regardless of their order. 382 * The "arch=" option is a special case and is passed to LLVM via the 383 * "target-cpu" function attribute. 384 * 385 * Examples: 386 * --- 387 * import ldc.attributes; 388 * 389 * @target("no-sse") 390 * void foo_nosse(float *A, float* B, float K, uint n) { 391 * for (int i = 0; i < n; ++i) 392 * A[i] *= B[i] + K; 393 * } 394 * @target("arch=haswell") 395 * void foo_haswell(float *A, float* B, float K, uint n) { 396 * for (int i = 0; i < n; ++i) 397 * A[i] *= B[i] + K; 398 * } 399 * --- 400 */ 401 struct target 402 { 403 string specifier; 404 } 405 406 /++ 407 + When applied to a global symbol, specifies that the symbol should be emitted 408 + with weak linkage. An example use case is a library function that should be 409 + overridable by user code. 410 + 411 + Quote from the LLVM manual: "Note that weak linkage does not actually allow 412 + the optimizer to inline the body of this function into callers because it 413 + doesn’t know if this definition of the function is the definitive definition 414 + within the program or whether it will be overridden by a stronger 415 + definition." 416 + 417 + Examples: 418 + --- 419 + import ldc.attributes; 420 + 421 + @weak int user_hook() { return 1; } 422 + --- 423 +/ 424 immutable weak = _weak(); 425 private struct _weak 426 { 427 }