The OpenD Programming Language

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 }