about summary refs log tree commit diff
path: root/src/test/codegen/function-arguments.rs
AgeCommit message (Collapse)AuthorLines
2022-10-21Introduce deduced parameter attributes, and use them for deducing `readonly` onPatrick Walton-1/+1
indirect immutable freeze by-value function parameters. Right now, `rustc` only examines function signatures and the platform ABI when determining the LLVM attributes to apply to parameters. This results in missed optimizations, because there are some attributes that can be determined via analysis of the MIR making up the function body. In particular, `readonly` could be applied to most indirectly-passed by-value function arguments (specifically, those that are freeze and are observed not to be mutated), but it currently is not. This patch introduces the machinery that allows `rustc` to determine those attributes. It consists of a query, `deduced_param_attrs`, that, when evaluated, analyzes the MIR of the function to determine supplementary attributes. The results of this query for each function are written into the crate metadata so that the deduced parameter attributes can be applied to cross-crate functions. In this patch, we simply check the parameter for mutations to determine whether the `readonly` attribute should be applied to parameters that are indirect immutable freeze by-value. More attributes could conceivably be deduced in the future: `nocapture` and `noalias` come to mind. Adding `readonly` to indirect function parameters where applicable enables some potential optimizations in LLVM that are discussed in [issue 103103] and [PR 103070] around avoiding stack-to-stack memory copies that appear in functions like `core::fmt::Write::write_fmt` and `core::panicking::assert_failed`. These functions pass a large structure unchanged by value to a subfunction that also doesn't mutate it. Since the structure in this case is passed as an indirect parameter, it's a pointer from LLVM's perspective. As a result, the intermediate copy of the structure that our codegen emits could be optimized away by LLVM's MemCpyOptimizer if it knew that the pointer is `readonly nocapture noalias` in both the caller and callee. We already pass `nocapture noalias`, but we're missing `readonly`, as we can't determine whether a by-value parameter is mutated by examining the signature in Rust. I didn't have much success with having LLVM infer the `readonly` attribute, even with fat LTO; it seems that deducing it at the MIR level is necessary. No large benefits should be expected from this optimization *now*; LLVM needs some changes (discussed in [PR 103070]) to more aggressively use the `noalias nocapture readonly` combination in its alias analysis. I have some LLVM patches for these optimizations and have had them looked over. With all the patches applied locally, I enabled LLVM to remove all the `memcpy`s from the following code: ```rust fn main() { println!("Hello {}", 3); } ``` which is a significant codegen improvement over the status quo. I expect that if this optimization kicks in in multiple places even for such a simple program, then it will apply to Rust code all over the place. [issue 103103]: https://github.com/rust-lang/rust/issues/103103 [PR 103070]: https://github.com/rust-lang/rust/pull/103070
2022-07-27Remove outdated rustc_allocator testNikita Popov-7/+0
This attribute now does more than just place noalias on the return, and has specific requirements for the signature. Drop the test entirely, as we already check __rust_alloc attributes in other codegen tests.
2022-07-22do not mark interior mutable shared refs as dereferenceableRalf Jung-1/+19
2022-05-25Update some codegen tests for opaque pointersNikita Popov-22/+22
2022-02-26Apply noundef attribute to all scalar types which do not permit raw initErik Desjardins-1/+49
Beyond `&`/`&mut`/`Box`, this covers `char`, discriminants, `NonZero*`, etc. All such types currently cause a Miri error if left uninitialized, and an `invalid_value` lint in cases like `mem::uninitialized::<char>()` Note that this _does not_ change whether or not it is UB for `u64` (or other integer types with no invalid values) to be undef.
2022-02-06apply noundef explicitly in all cases instead of relying on dereferenceable ↵Erik Desjardins-12/+12
implying it
2022-02-06test that MaybeUninit<bool> is not noundefErik Desjardins-0/+8
2022-02-05Apply noundef attribute to &T, &mut T, Box<T>, boolErik Desjardins-11/+26
This doesn't handle `char` because it's a bit awkward to distinguish it from u32 at this point in codegen. Note that for some types (like `&Struct` and `&mut Struct`), we already apply `dereferenceable`, which implies `noundef`, so the IR does not change.
2021-10-22Update the minimum external LLVM to 12Josh Stone-2/+0
2021-04-03Remove redundant `ignore-tidy-linelength` annotationsSimon Jakobi-1/+1
This is step 2 towards fixing #77548. In the codegen and codegen-units test suites, the `//` comment markers were kept in order not to affect any source locations. This is because these tests cannot be automatically `--bless`ed.
2021-03-21Don't compute optimized PointerKind for unoptimized buildsNikita Popov-1/+1
This saves us both the Freeze/Unpin queries, and avoids placing noalias attributes, which have a compile-time impact on LLVM even in optnone builds (due to always_inline functions).
2021-03-21Enable mutable noalias by default for LLVM 12Nikita Popov-3/+3
We don't have any known noalias bugs for LLVM 12 ... yet.
2021-02-28Support LLVM 12 in rustcNikita Popov-1/+2
2020-01-07Update codegen tests with unnamed argumentsNikita Popov-2/+2
2019-11-22remove the 'dereferenceable' attribute from BoxRalf Jung-1/+3
2019-09-13codegen: use "_N" (like for other locals) instead of "argN", for argument names.Eduard-Mihai Burtescu-14/+14
2019-06-08Turn `#[allocator]` into a built-in attribute and rename it to ↵Vadim Petrochenkov-2/+2
`#[rustc_allocator]`
2018-12-25Remove licensesMark Rousskov-10/+0
2018-12-21Enable emission of alignment attrs for pointer paramsNikita Popov-16/+16
Instead disable creation of assumptions during inlining using an LLVM opt flag. The -Z arg-align-attributes option which previously controlled this behavior is removed.
2018-12-09Bump minimum required LLVM version to 6.0Nikita Popov-1/+0
2018-09-29Do not put noalias annotations by defaultSimonas Kazlauskas-3/+3
This will be re-enabled sooner or later depending on results of further investigation. Fixes #54462
2018-08-28Use partial but correct vtable layoutOliver Schneider-2/+2
2018-07-29dont hardcode vtable size in codegen testRalf Jung-2/+2
2018-07-29update codegen testsRalf Jung-2/+2
2018-07-05Store scalar pair bools as i8 in memoryJosh Stone-1/+1
We represent `bool` as `i1` in a `ScalarPair`, unlike other aggregates, to optimize IR for checked operators and the like. With this patch, we still do so when the pair is an immediate value, but we use the `i8` memory type when the value is loaded or stored as an LLVM aggregate. So `(bool, bool)` looks like an `{ i1, i1 }` immediate, but `{ i8, i8 }` in memory. When a pair is a direct function argument, `PassMode::Pair`, it is still passed using the immediate `i1` type, but as a return value it will use the `i8` memory type. Also, `bool`-like` enum tags will now use scalar pairs when possible, where they were previously excluded due to optimization issues.
2018-05-17Emit noalias on &mut parameters by defaultNikita Popov-6/+4
This used to be disabled due to LLVM bugs in the handling of noalias information in conjunction with unwinding. However, according to #31681 all known LLVM bugs have been fixed by LLVM 6.0, so it's probably time to reenable this optimization. Noalias annotations will not be emitted by default if either -C panic=abort (as previously) or LLVM >= 6.0 (new). -Z mutable-noalias=no is left as an escape-hatch to allow debugging problems suspected to stem from this change.
2018-04-26Use ScalarPair for tagged enumsAnthony Ramine-0/+12
2018-03-26Allow niche-filling dataful variants to be represented as a ScalarPairAnthony Ramine-0/+6
2018-01-31rustc_trans: keep LLVM types for trait objects anonymous.Eduard-Mihai Burtescu-2/+2
2017-11-19rustc_trans: work around i686-pc-windows-msvc byval align LLVM bug.Eduard-Mihai Burtescu-2/+2
2017-11-19rustc: unpack scalar newtype layout ABIs.Eduard-Mihai Burtescu-3/+3
2017-11-19rustc: encode scalar pairs in layout ABI.Eduard-Mihai Burtescu-1/+1
2017-11-19rustc_trans: compute better align/dereferenceable attributes from pointees.Eduard-Mihai Burtescu-5/+5
2017-11-19rustc_trans: go through layouts uniformly for fat pointers and variants.Eduard-Mihai Burtescu-7/+7
2017-11-19rustc_trans: always insert alignment padding, even before the first field.Eduard-Mihai Burtescu-1/+2
2017-11-19rustc_trans: use *[T; 0] for slice data pointers instead of *T.Eduard-Mihai Burtescu-1/+1
2017-11-07Update codegen tests.Michael Woerister-7/+7
2017-10-26Avoid unnecessary copies of arguments that are simple bindingsBjörn Steinbrink-16/+16
Initially MIR differentiated between arguments and locals, which introduced a need to add extra copies assigning the argument to a local, even for simple bindings. This differentiation no longer exists, but we're still creating those copies, bloating the MIR and LLVM IR we emit. Additionally, the current approach means that we create debug info for both the incoming argument (marking it as an argument), and then immediately shadow it a local that goes by the same name. This can be confusing when using e.g. "info args" in gdb, or when e.g. a debugger with a GUI displays the function arguments separately from the local variables, especially when the binding is mutable, because the argument doesn't change, while the local variable does.
2017-07-05rustc: Implement the #[global_allocator] attributeAlex Crichton-1/+1
This PR is an implementation of [RFC 1974] which specifies a new method of defining a global allocator for a program. This obsoletes the old `#![allocator]` attribute and also removes support for it. [RFC 1974]: https://github.com/rust-lang/rfcs/pull/197 The new `#[global_allocator]` attribute solves many issues encountered with the `#![allocator]` attribute such as composition and restrictions on the crate graph itself. The compiler now has much more control over the ABI of the allocator and how it's implemented, allowing much more freedom in terms of how this feature is implemented. cc #27389
2017-04-09rustc_trans: use ty::layout for ABI computation instead of LLVM types.Eduard-Mihai Burtescu-2/+2
2017-02-22Update codegen test with new attributesJames Miller-2/+2
2016-02-10Workaround LLVM optimizer bug by not marking &mut pointers as noaliasBjörn Steinbrink-3/+6
LLVM's memory dependence analysis doesn't properly account for calls that could unwind and thus effectively act as a branching point. This can lead to stores that are only visible when the call unwinds being removed, possibly leading to calls to drop() functions with b0rked memory contents. As there is no fix for this in LLVM yet and we want to keep compatibility to current LLVM versions anyways, we have to workaround this bug by omitting the noalias attribute on &mut function arguments. Benchmarks suggest that the performance loss by this change is very small. Thanks to @RalfJung for pushing me towards not removing too many noalias annotations and @alexcrichton for helping out with the test for this bug. Fixes #29485
2015-09-21Avoid loading the whole gdb debug scripts section.Richard Diamond-0/+1
This is so LLVM isn't forced to load every byte of it. Also sets the alignment of the load. Adds a test for the debug script section.
2015-06-20Pass fat pointers in two immediate argumentsBjörn Steinbrink-0/+47
This has a number of advantages compared to creating a copy in memory and passing a pointer. The obvious one is that we don't have to put the data into memory but can keep it in registers. Since we're currently passing a pointer anyway (instead of using e.g. a known offset on the stack, which is what the `byval` attribute would achieve), we only use a single additional register for each fat pointer, but save at least two pointers worth of stack in exchange (sometimes more because more than one copy gets eliminated). On archs that pass arguments on the stack, we save a pointer worth of stack even without considering the omitted copies. Additionally, LLVM can optimize the code a lot better, to a large degree due to the fact that lots of copies are gone or can be optimized away. Additionally, we can now emit attributes like nonnull on the data and/or vtable pointers contained in the fat pointer, potentially allowing for even more optimizations. This results in LLVM passes being about 3-7% faster (depending on the crate), and the resulting code is also a few percent smaller, for example: text data filename 5671479 3941461 before/librustc-d8ace771.so 5447663 3905745 after/librustc-d8ace771.so 1944425 2394024 before/libstd-d8ace771.so 1896769 2387610 after/libstd-d8ace771.so I had to remove a call in the backtrace-debuginfo test, because LLVM can now merge the tails of some blocks when optimizations are turned on, which can't correctly preserve line info. Fixes #22924 Cc #22891 (at least for fat pointers the code is good now)
2015-05-27Revamp codegen tests to check IR quality instead of quantityBjörn Steinbrink-0/+95
The current codegen tests only compare IR line counts between similar rust and C programs, the latter getting compiled with clang. That looked like a good idea back then, but actually things like lifetime intrinsics mean that less IR isn't always better, so the metric isn't really helpful. Instead, we can start doing tests that check specific aspects of the generated IR, like attributes or metadata. To do that, we can use LLVM's FileCheck tool which has a number of useful features for such tests. To start off, I created some tests for a few things that were recently added and/or broken.