1# Code generation attributes
2
3The following [attributes] are used for controlling code generation.
4
5## Optimization hints
6
7The `cold` and `inline` [attributes] give suggestions to generate code in a
8way that may be faster than what it would do without the hint. The attributes
9are only hints, and may be ignored.
10
11Both attributes can be used on [functions]. When applied to a function in a
12[trait], they apply only to that function when used as a default function for
13a trait implementation and not to all trait implementations. The attributes
14have no effect on a trait function without a body.
15
16### The `inline` attribute
17
18The *`inline` [attribute]* suggests that a copy of the attributed function
19should be placed in the caller, rather than generating code to call the
20function where it is defined.
21
22> ***Note***: The `rustc` compiler automatically inlines functions based on
23> internal heuristics. Incorrectly inlining functions can make the program
24> slower, so this attribute should be used with care.
25
26There are three ways to use the inline attribute:
27
28* `#[inline]` *suggests* performing an inline expansion.
29* `#[inline(always)]` *suggests* that an inline expansion should always be
30  performed.
31* `#[inline(never)]` *suggests* that an inline expansion should never be
32  performed.
33
34> ***Note***: `#[inline]` in every form is a hint, with no *requirements*
35> on the language to place a copy of the attributed function in the caller.
36
37### The `cold` attribute
38
39The *`cold` [attribute]* suggests that the attributed function is unlikely to
40be called.
41
42## The `no_builtins` attribute
43
44The *`no_builtins` [attribute]* may be applied at the crate level to disable
45optimizing certain code patterns to invocations of library functions that are
46assumed to exist.
47
48## The `target_feature` attribute
49
50The *`target_feature` [attribute]* may be applied to a function to
51enable code generation of that function for specific platform architecture
52features. It uses the [_MetaListNameValueStr_] syntax with a single key of
53`enable` whose value is a string of comma-separated feature names to enable.
54
55```rust
56# #[cfg(target_feature = "avx2")]
57#[target_feature(enable = "avx2")]
58unsafe fn foo_avx2() {}
59```
60
61Each [target architecture] has a set of features that may be enabled. It is an
62error to specify a feature for a target architecture that the crate is not
63being compiled for.
64
65It is [undefined behavior] to call a function that is compiled with a feature
66that is not supported on the current platform the code is running on.
67
68Functions marked with `target_feature` are not inlined into a context that
69does not support the given features. The `#[inline(always)]` attribute may not
70be used with a `target_feature` attribute.
71
72### Available features
73
74The following is a list of the available feature names.
75
76#### `x86` or `x86_64`
77
78This platform requires that `#[target_feature]` is only applied to [`unsafe`
79functions][unsafe function].
80
81Feature     | Implicitly Enables | Description
82------------|--------------------|-------------------
83`aes`       | `sse2`   | [AES] — Advanced Encryption Standard
84`avx`       | `sse4.2` | [AVX] — Advanced Vector Extensions
85`avx2`      | `avx`    | [AVX2] — Advanced Vector Extensions 2
86`bmi1`      |          | [BMI1] — Bit Manipulation Instruction Sets
87`bmi2`      |          | [BMI2] — Bit Manipulation Instruction Sets 2
88`fma`       | `avx`    | [FMA3] — Three-operand fused multiply-add
89`fxsr`      |          | [`fxsave`] and [`fxrstor`] — Save and restore x87 FPU, MMX Technology, and SSE State
90`lzcnt`     |          | [`lzcnt`] — Leading zeros count
91`pclmulqdq` | `sse2`   | [`pclmulqdq`] — Packed carry-less multiplication quadword
92`popcnt`    |          | [`popcnt`] — Count of bits set to 1
93`rdrand`    |          | [`rdrand`] — Read random number
94`rdseed`    |          | [`rdseed`] — Read random seed
95`sha`       | `sse2`   | [SHA] — Secure Hash Algorithm
96`sse`       |          | [SSE] — Streaming <abbr title="Single Instruction Multiple Data">SIMD</abbr> Extensions
97`sse2`      | `sse`    | [SSE2] — Streaming SIMD Extensions 2
98`sse3`      | `sse2`   | [SSE3] — Streaming SIMD Extensions 3
99`sse4.1`    | `ssse3`  | [SSE4.1] — Streaming SIMD Extensions 4.1
100`sse4.2`    | `sse4.1` | [SSE4.2] — Streaming SIMD Extensions 4.2
101`ssse3`     | `sse3`   | [SSSE3] — Supplemental Streaming SIMD Extensions 3
102`xsave`     |          | [`xsave`] — Save processor extended states
103`xsavec`    |          | [`xsavec`] — Save processor extended states with compaction
104`xsaveopt`  |          | [`xsaveopt`] — Save processor extended states optimized
105`xsaves`    |          | [`xsaves`] — Save processor extended states supervisor
106
107<!-- Keep links near each table to make it easier to move and update. -->
108
109[AES]: https://en.wikipedia.org/wiki/AES_instruction_set
110[AVX]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions
111[AVX2]: https://en.wikipedia.org/wiki/Advanced_Vector_Extensions#AVX2
112[BMI1]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets
113[BMI2]: https://en.wikipedia.org/wiki/Bit_Manipulation_Instruction_Sets#BMI2
114[FMA3]: https://en.wikipedia.org/wiki/FMA_instruction_set
115[`fxsave`]: https://www.felixcloutier.com/x86/fxsave
116[`fxrstor`]: https://www.felixcloutier.com/x86/fxrstor
117[`lzcnt`]: https://www.felixcloutier.com/x86/lzcnt
118[`pclmulqdq`]: https://www.felixcloutier.com/x86/pclmulqdq
119[`popcnt`]: https://www.felixcloutier.com/x86/popcnt
120[`rdrand`]: https://en.wikipedia.org/wiki/RdRand
121[`rdseed`]: https://en.wikipedia.org/wiki/RdRand
122[SHA]: https://en.wikipedia.org/wiki/Intel_SHA_extensions
123[SSE]: https://en.wikipedia.org/wiki/Streaming_SIMD_Extensions
124[SSE2]: https://en.wikipedia.org/wiki/SSE2
125[SSE3]: https://en.wikipedia.org/wiki/SSE3
126[SSE4.1]: https://en.wikipedia.org/wiki/SSE4#SSE4.1
127[SSE4.2]: https://en.wikipedia.org/wiki/SSE4#SSE4.2
128[SSSE3]: https://en.wikipedia.org/wiki/SSSE3
129[`xsave`]: https://www.felixcloutier.com/x86/xsave
130[`xsavec`]: https://www.felixcloutier.com/x86/xsavec
131[`xsaveopt`]: https://www.felixcloutier.com/x86/xsaveopt
132[`xsaves`]: https://www.felixcloutier.com/x86/xsaves
133
134#### `wasm32` or `wasm64`
135
136This platform allows `#[target_feature]` to be applied to both safe and
137[`unsafe` functions][unsafe function].
138
139Feature     | Description
140------------|-------------------
141`simd128`   | [WebAssembly simd proposal][simd128]
142
143[simd128]: https://github.com/webassembly/simd
144
145### Additional information
146
147See the [`target_feature` conditional compilation option] for selectively
148enabling or disabling compilation of code based on compile-time settings. Note
149that this option is not affected by the `target_feature` attribute, and is
150only driven by the features enabled for the entire crate.
151
152See the [`is_x86_feature_detected`] macro in the standard library for runtime
153feature detection on the x86 platforms.
154
155> Note: `rustc` has a default set of features enabled for each target and CPU.
156> The CPU may be chosen with the [`-C target-cpu`] flag. Individual features
157> may be enabled or disabled for an entire crate with the
158> [`-C target-feature`] flag.
159
160## The `track_caller` attribute
161
162The `track_caller` attribute may be applied to any function with [`"Rust"` ABI][rust-abi]
163with the exception of the entry point `fn main`. When applied to functions and methods in
164trait declarations, the attribute applies to all implementations. If the trait provides a
165default implementation with the attribute, then the attribute also applies to override implementations.
166
167When applied to a function in an `extern` block the attribute must also be applied to any linked
168implementations, otherwise undefined behavior results. When applied to a function which is made
169available to an `extern` block, the declaration in the `extern` block must also have the attribute,
170otherwise undefined behavior results.
171
172### Behavior
173
174Applying the attribute to a function `f` allows code within `f` to get a hint of the [`Location`] of
175the "topmost" tracked call that led to `f`'s invocation. At the point of observation, an
176implementation behaves as if it walks up the stack from `f`'s frame to find the nearest frame of an
177*unattributed* function `outer`, and it returns the [`Location`] of the tracked call in `outer`.
178
179```rust
180#[track_caller]
181fn f() {
182    println!("{}", std::panic::Location::caller());
183}
184```
185
186> Note: `core` provides [`core::panic::Location::caller`] for observing caller locations. It wraps
187> the [`core::intrinsics::caller_location`] intrinsic implemented by `rustc`.
188
189> Note: because the resulting `Location` is a hint, an implementation may halt its walk up the stack
190> early. See [Limitations](#limitations) for important caveats.
191
192#### Examples
193
194When `f` is called directly by `calls_f`, code in `f` observes its callsite within `calls_f`:
195
196```rust
197# #[track_caller]
198# fn f() {
199#     println!("{}", std::panic::Location::caller());
200# }
201fn calls_f() {
202    f(); // <-- f() prints this location
203}
204```
205
206When `f` is called by another attributed function `g` which is in turn called by `calls_g`, code in
207both `f` and `g` observes `g`'s callsite within `calls_g`:
208
209```rust
210# #[track_caller]
211# fn f() {
212#     println!("{}", std::panic::Location::caller());
213# }
214#[track_caller]
215fn g() {
216    println!("{}", std::panic::Location::caller());
217    f();
218}
219
220fn calls_g() {
221    g(); // <-- g() prints this location twice, once itself and once from f()
222}
223```
224
225When `g` is called by another attributed function `h` which is in turn called by `calls_h`, all code
226in `f`, `g`, and `h` observes `h`'s callsite within `calls_h`:
227
228```rust
229# #[track_caller]
230# fn f() {
231#     println!("{}", std::panic::Location::caller());
232# }
233# #[track_caller]
234# fn g() {
235#     println!("{}", std::panic::Location::caller());
236#     f();
237# }
238#[track_caller]
239fn h() {
240    println!("{}", std::panic::Location::caller());
241    g();
242}
243
244fn calls_h() {
245    h(); // <-- prints this location three times, once itself, once from g(), once from f()
246}
247```
248
249And so on.
250
251### Limitations
252
253This information is a hint and implementations are not required to preserve it.
254
255In particular, coercing a function with `#[track_caller]` to a function pointer creates a shim which
256appears to observers to have been called at the attributed function's definition site, losing actual
257caller information across virtual calls. A common example of this coercion is the creation of a
258trait object whose methods are attributed.
259
260> Note: The aforementioned shim for function pointers is necessary because `rustc` implements
261> `track_caller` in a codegen context by appending an implicit parameter to the function ABI, but
262> this would be unsound for an indirect call because the parameter is not a part of the function's
263> type and a given function pointer type may or may not refer to a function with the attribute. The
264> creation of a shim hides the implicit parameter from callers of the function pointer, preserving
265> soundness.
266
267[_MetaListNameValueStr_]: ../attributes.md#meta-item-attribute-syntax
268[`-C target-cpu`]: ../../rustc/codegen-options/index.html#target-cpu
269[`-C target-feature`]: ../../rustc/codegen-options/index.html#target-feature
270[`is_x86_feature_detected`]: ../../std/macro.is_x86_feature_detected.html
271[`target_feature` conditional compilation option]: ../conditional-compilation.md#target_feature
272[attribute]: ../attributes.md
273[attributes]: ../attributes.md
274[functions]: ../items/functions.md
275[target architecture]: ../conditional-compilation.md#target_arch
276[trait]: ../items/traits.md
277[undefined behavior]: ../behavior-considered-undefined.md
278[unsafe function]: ../unsafe-functions.md
279[rust-abi]: ../items/external-blocks.md#abi
280[`core::intrinsics::caller_location`]: ../../core/intrinsics/fn.caller_location.html
281[`core::panic::Location::caller`]: ../../core/panic/struct.Location.html#method.caller
282[`Location`]: ../../core/panic/struct.Location.html
283