Implement optimize(size) and optimize(speed) attributes
This PR implements both `optimize(size)` and `optimize(speed)` attributes.
While the functionality itself works fine now, this PR is not yet complete: the code might be messy in places and, most importantly, the compiletest must be improved with functionality to run tests with custom optimization levels. Otherwise the new attribute cannot be tested properly. Oh, and not all of the RFC is implemented – attribute propagation is not implemented for example.
# TODO
* [x] Improve compiletest so that tests can be written;
* [x] Assign a proper error number (E9999 currently, no idea how to allocate a number properly);
* [ ] Perhaps reduce the duplication in LLVM attribute assignment code…
The new git submodule src/llvm-project is a monorepo replacing src/llvm
and src/tools/{clang,lld,lldb}. This also serves as a rebase for these
projects to the new 8.x branch from trunk.
The src/llvm-emscripten fork is unchanged for now.
Enable emission of alignment attrs for pointer params
Instead disable creation of assumptions during inlining using an LLVM opt flag. For non-inlined functions, this gives us alignment information, while not inserting any assumes that kill other optimizations.
The `-Z arg-align-attributes` option which previously controlled this behavior is removed.
Fixes#54982.
r? @nagisa
cc @eddyb who added the current behavior, and @scottmcm, who added the `-Z arg-align-attributes` flag.
Fix alignment for array indexing
We need to reduce the alignment with the used offset. If the offset isn't known, use the element size, as this will yield the minimum possible alignment.
This handles both direct array indexing, and array repeat expressions.
Fixes#56927.
r? @nagisa
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.
Bump minimum required LLVM version to 6.0
Based on the discussion in #55842, while the overall position of Rust wrt LLVM continues to be contentious, there does seem to be a consensus that there is no need for continued support of LLVM 5. This PR bumps our version requirement to LLVM 6.0 and makes Travis run against that.
I hope that this is going to unblock #52694. If I understand correctly, while this issue still exists in LLVM 6, Ubuntu has backported the relevant patch.
r? @alexcrichton
This is going to be required for binding a number of AVX-512 intrinsics
in the `stdsimd` repository, and this intrinsic is the same as
`simd_select` except that it takes a bitmask as the first argument
instead of a SIMD vector. This bitmask is then transmuted into a `<NN x
i8>` argument, depending on how many bits it is.
cc rust-lang-nursery/stdsimd#310
This was intended to land way back in 1.24, but it was backed out due to
breakage which has long since been fixed. An unstable `#[unwind]`
attribute can be used to tweak the behavior here, but this is currently
simply switching rustc's internal default to abort-by-default if an
`extern` function panics, making our codegen sound primarily (as
currently you can produce UB with safe code)
Closes#52652
If the Rust LLVM fork is used, enable the -mergefunc-use-aliases
flag, which will create aliases for merged functions, rather than
inserting a call from one to the other.
A number of codegen tests needed to be adjusted, because functions
that previously fell below the thunk limit are now being merged.
Merging is prevented either using -C no-prepopulate-passes, or by
making the functions non-identical.
I expect that this is going to break something, somewhere, because
it isn't able to deal with aliases properly, but we won't find out
until we try :)
This fixes#52651.
The alignment for the second element of a scalar pair is not the
same as for the first element. Make sure it is computed correctly
based on the element size.
Fix emission of niche-filling discriminant values
Bug #55606 points out a regression introduced by #54004; namely that
an assertion can erroneously fire when a niche-filling discriminant
value is emitted.
This fixes the bug by removing the assertion, and furthermore by
arranging for the discriminant value to be masked according to the
size of the niche. This makes handling the discriminant a bit simpler
for debuggers.
The test case is from Jonathan Turner.
Closes#55606
Bug #55606 points out a regression introduced by #54004; namely that
an assertion can erroneously fire when a niche-filling discriminant
value is emitted.
This fixes the bug by removing the assertion, and furthermore by
arranging for the discriminant value to be masked according to the
size of the niche. This makes handling the discriminant a bit simpler
for debuggers.
The test case is from Jonathan Turner.
Closes#55606
If LLVM 7 is used, generate memcpy/memmove with differing
src/dst alignment. I've added new FFI functions to construct
these through the builder API, which is more convenient than
dealing with differing intrinsic signatures depending on the
LLVM version.
The DWARF generated for Rust enums was always somewhat unusual.
Rather than using DWARF constructs directly, it would emit magic field
names like "RUST$ENCODED$ENUM$0$Name" and "RUST$ENUM$DISR". Since
PR #45225, though, even this has not worked -- the ad hoc scheme was
not updated to handle the wider variety of niche-filling layout
optimizations now available.
This patch changes the generated DWARF to use the standard tags meant
for this purpose; namely, DW_TAG_variant and DW_TAG_variant_part.
The patch to implement this went in to LLVM 7. In order to work with
older versions of LLVM, and because LLVM doesn't do anything here for
PDB, the existing code is kept as a fallback mode.
Support for this DWARF is in the Rust lldb and in gdb 8.2.
Closes#32920Closes#32924Closes#52762Closes#53153
rustc: Tweak filenames encoded into metadata
This commit is a fix for #54408 where on nightly right now whenever
generics are inlined the path name listed for the inlined function's
debuginfo is a relative path to the cwd, which surely doesn't exist!
Previously on beta/stable the debuginfo mentioned an absolute path which
still didn't exist, but more predictably didn't exist.
The change between stable/nightly is that nightly is now compiled with
`--remap-path-prefix` to give a deterministic prefix to all
rustc-generated paths in debuginfo. By using `--remap-path-prefix` the
previous logic would recognize that the cwd was remapped, causing the
original relative path name of the standard library to get emitted. If
`--remap-path-prefix` *wasn't* passed in then the logic would create an
absolute path name and then create a new source file entry.
The fix in this commit is to apply the "recreate the source file entry
with an absolute path" logic a bit more aggresively. If the source
file's name was remapped then we don't touch it, but otherwise we always
take the working dir (which may have been remapped) and then join it to
the file to ensure that we process all relative file names as well.
The end result is that the standard library should have an absolute path
for all file names in debuginfo (using our `--remap-path-prefix`
argument) as it does on stable after this patch.
Closes#54408
Disable the PLT where possible to improve performance
for indirect calls into shared libraries.
This optimization is enabled by default where possible.
- Add the `NonLazyBind` attribute to `rustllvm`:
This attribute informs LLVM to skip PLT calls in codegen.
- Disable PLT unconditionally:
Apply the `NonLazyBind` attribute on every function.
- Only enable no-plt when full relro is enabled:
Ensures we only enable it when we have linker support.
- Add `-Z plt` as a compiler option
This commit updates the compiler to allow the `#[no_mangle]` (and
`#[export_name]` attributes) to be located anywhere within a crate.
These attributes are unconditionally processed, causing the compiler to
always generate an exported symbol with the appropriate name.
After some discussion on #54135 it was found that not a great reason
this hasn't been allowed already, and it seems to match the behavior
that many expect! Previously the compiler would only export a
`#[no_mangle]` symbol if it were *publicly reachable*, meaning that it
itself is `pub` and it's otherwise publicly reachable from the root of
the crate. This new definition is that `#[no_mangle]` *is always
reachable*, no matter where it is in a crate or whether it has `pub` or
not.
This should make it much easier to declare an exported symbol with a
known and unique name, even when it's an internal implementation detail
of the crate itself. Note that these symbols will persist beyond LTO as
well, always making their way to the linker.
Along the way this commit removes the `private_no_mangle_functions` lint
(also for statics) as there's no longer any need to lint these
situations. Furthermore a good number of tests were updated now that
symbol visibility has been changed.
Closes#54135
Do not put noalias annotations by default
This will be re-enabled sooner or later depending on results of further
investigation.
Fixes#54462
Beta backport is: #54640
r? @nikomatsakis
Revert most of MaybeUninit, except for the new API itself
This reverts most of https://github.com/rust-lang/rust/pull/53508/ for perf reasons (first commit reverts that entire PR), except for the new API itself (added back in 2nd commit).