This commit adds a new option to target specifictions to specify that symbols
should be "hidden" visibility by default in LLVM. While there are no existing
targets that take advantage of this the `wasm32-unknown-unknown` target will
soon start to use this visibility. The LLD linker currently interprets `hidden`
as "don't export this from the wasm module" which is what we want for 90% of our
functions. While the LLD linker does have a "export this symbol" argument which
is what we use for other linkers, it was also somewhat easier to do this change
instead which'll involve less arguments flying around. Additionally there's no
need for non-`hidden` visibility for most of our symbols!
This change should not immediately impact the wasm targets as-is, but rather
this is laying the foundations for soon integrating LLD as a linker for wasm
code.
Whitelist v7 feature for ARM and AARCH64.
Needed for `v7` features in `coresimd`.
See b2f7be24d5/coresimd/src/arm/v7.rs (L40) which used to work but doesn't anymore.
r? alexcrichton
This commit introduces a separately compiled backend for Emscripten, avoiding
compiling the `JSBackend` target in the main LLVM codegen backend. This builds
on the foundation provided by #47671 to create a new codegen backend dedicated
solely to Emscripten, removing the `JSBackend` of the main codegen backend in
the process.
A new field was added to each target for this commit which specifies the backend
to use for translation, the default being `llvm` which is the main backend that
we use. The Emscripten targets specify an `emscripten` backend instead of the
main `llvm` one.
There's a whole bunch of consequences of this change, but I'll try to enumerate
them here:
* A *second* LLVM submodule was added in this commit. The main LLVM submodule
will soon start to drift from the Emscripten submodule, but currently they're
both at the same revision.
* Logic was added to rustbuild to *not* build the Emscripten backend by default.
This is gated behind a `--enable-emscripten` flag to the configure script. By
default users should neither check out the emscripten submodule nor compile
it.
* The `init_repo.sh` script was updated to fetch the Emscripten submodule from
GitHub the same way we do the main LLVM submodule (a tarball fetch).
* The Emscripten backend, turned off by default, is still turned on for a number
of targets on CI. We'll only be shipping an Emscripten backend with Tier 1
platforms, though. All cross-compiled platforms will not be receiving an
Emscripten backend yet.
This commit means that when you download the `rustc` package in Rustup for Tier
1 platforms you'll be receiving two trans backends, one for Emscripten and one
that's the general LLVM backend. If you never compile for Emscripten you'll
never use the Emscripten backend, so we may update this one day to only download
the Emscripten backend when you add the Emscripten target. For now though it's
just an extra 10MB gzip'd.
Closes#46819
Fix ICE on const eval of union field
MIR's `Const::get_field()` attempts to retrieve the value for a given field in a constant. In the case of a union constant it was falling through to a generic `const_get_elt` based on the field index. As union fields don't have an index this caused an ICE in `llvm_field_index`.
Fix by simply returning the current value when accessing any field in a union. This works because all union fields start at byte offset 0.
The added test uses `const_fn` it ensure the field is extracted using MIR's const evaluation. The crash is reproducible without it, however.
Fixes#47788
r? @eddyb
Building on the work of # 45684 this commit updates the compiler to
unconditionally load the `rustc_trans` crate at runtime instead of linking to it
at compile time. The end goal of this work is to implement # 46819 where rustc
will have multiple backends available to it to load.
This commit starts off by removing the `extern crate rustc_trans` from the
driver. This involved moving some miscellaneous functionality into the
`TransCrate` trait and also required an implementation of how to locate and load
the trans backend. This ended up being a little tricky because the sysroot isn't
always the right location (for example `--sysroot` arguments) so some extra code
was added as well to probe a directory relative to the current dll (the
rustc_driver dll).
Rustbuild has been updated accordingly as well to have a separate compilation
invocation for the `rustc_trans` crate and assembly it accordingly into the
sysroot. Finally, the distribution logic for the `rustc` package was also
updated to slurp up the trans backends folder.
A number of assorted fallout changes were included here as well to ensure tests
pass and such, and they should all be commented inline.
MIR's `Const::get_field()` attempts to retrieve the value for a given
field in a constant. In the case of a union constant it was falling
through to a generic `const_get_elt` based on the field index. As union
fields don't have an index this caused an ICE in `llvm_field_index`.
Fix by simply returning the current value when accessing any field in a
union. This works because all union fields start at byte offset 0.
The added test uses `const_fn` it ensure the field is extracted using
MIR's const evaluation. The crash is reproducible without it, however.
Fixes#47788
First round of LLVM 6.0.0 compatibility
This includes a number of commits for the first round of upgrading to LLVM 6. There are still [lingering bugs](https://github.com/rust-lang/rust/issues/47683) but I believe all of this will nonetheless be necessary!
Teach rustc about DW_AT_noreturn and a few more DIFlags
We achieve two small things with this PR:
1. We provide definitions for a few additional llvm debuginfo flags
1. We _use_ one of these new flags, `FlagNoReturn`, and add it to debuginfo for functions with the never return type (`!`).
This commit changes the ABI of SIMD types in the "Rust" ABI to unconditionally
be passed via pointers instead of being passed as immediates. This should fix a
longstanding issue, #44367, where SIMD-using programs ended up showing very odd
behavior at runtime because the ABI between functions was mismatched.
As a bit of a recap, this is sort of an LLVM bug and sort of an LLVM feature
(today's behavior). LLVM will generate code for a function solely looking at the
function it's generating, including calls to other functions. Let's then say
you've got something that looks like:
```llvm
define void @foo() { ; no target features enabled
call void @bar(<i64 x 4> zeroinitializer)
ret void
}
define void @bar(<i64 x 4>) #0 { ; enables the AVX feature
...
}
```
LLVM will codegen the call to `bar` *without* using AVX registers becauase `foo`
doesn't have access to these registers. Instead it's generated with emulation
that uses two 128-bit registers. The `bar` function, on the other hand, will
expect its argument in an AVX register (as it has AVX enabled). This means we've
got a codegen problem!
Comments on #44367 have some more contexutal information but the crux of the
issue is that if we want SIMD to work in general we'll need to ensure that
whenever a function calls another they ABI of the arguments being passed is in
agreement.
One possible solution to this would be to insert "shim functions" where whenever
a `target_feature` mismatch is detected the compiler inserts a shim function
where you pass arguments via memory to the shim and then the shim loads the
values and calls the target function (where the shim and the target have the
same target features enabled). This unfortunately is quite nontrivial to
implement in rustc today (especially when accounting for function pointers and
such).
This commit takes a different solution, *always* passing SIMD arguments through
memory instead of passing as immediates. This strategy solves the problem at the
LLVM layer because the ABI between two functions never uses SIMD registers. This
also shouldn't be a hit to performance because SIMD performance is thought to
often rely on inlining anyway, where a `call` instruction, even if using SIMD
registers, would be disastrous to performance regardless. LLVM should then be
more than capable of fixing all our memory usage to use registers instead after
enough inlining has been performed.
Note that there's a few caveats to this commit though:
* The "platform intrinsic" ABI is omitted from "always pass via memory". This
ABI is used to define intrinsics like `simd_shuffle4` where LLVM and rustc
need to have the arguments as an immediate.
* Additionally this commit does *not* fix the `extern` ("C") ABI. This means
that the bug in #44367 can still happen when using non-Rust-ABI functions. My
hope is that before stabilization we can ban and/or warn about SIMD types in
these functions (as AFAIK there's not much motivation to belong there anyway),
but I'll leave that for a later commit and if this is merged I'll file a
follow-up issue.
All in all this...
Closes#44367
Fix no_integrated_as option to work with new codegen architecture.
Old implementation called the assembler once per crate, but we need to call
it for each object file instead, because a single crate can now have more
than one object file.
This patch fixes issue #45836 (Can't compile core for msp430 in release mode)
This change can be tested on x86_64 using
```sh
export RUSTFLAGS="-C no_integrated_as -C save_temps"
```
r? @alexcrichton
cc @japaric
rustc_trans: ignore trailing padding larger than 8 bytes.
Fixes#45662 by ignoring a missing second register component, as it could be entirely padding.
rustc_trans: take into account primitives larger than 8 bytes.
Fixes#38763 by marking all "eightbytes" covered by a primitive appropriately, not just the first.
Add CGU size heuristic for partitioning
This addresses the concern of #47316 by estimating CGU size based on
the size of its MIR. Looking at the size estimate differences for a
small selection of crates, this heuristic produces different orderings,
which should more accurately reflect optimisation time. (Fixes #47316.)
r? @michaelwoerister
The comment for why cloning exists doesn't actually apply for wasm today and
apparently cloning is causing subtle bugs in LLVM, so let's just avoid it
altogether. More specifically after we emit the assembly for the wasm target we
don't actually use the module again, so there's no need to keep both around.
This seemed to be causing some scary verifier assertions in LLVM which seemed to
be uncovered by presumably (?) buggy behavior. Let's just avoid it for now and
make the wasm target slightly more lean in the process.
LLVM has since removed the `CodeModel::Default` enum value in favor of an
`Optional` implementationg throughout LLVM. Let's mirror the same change in Rust
and update the various bindings we call accordingly.
Removed in llvm-mirror/llvm@9aafb854c
Immovable generators
This adds support for immovable generators which allow you to borrow local values inside generator across suspension points. These are declared using a `static` keyword:
```rust
let mut generator = static || {
let local = &Vec::new();
yield;
local.push(0i8);
};
generator.resume();
// ERROR moving the generator after it has resumed would invalidate the interior reference
// drop(generator);
```
Region inference is no longer affected by the types stored in generators so the regions inside should be similar to other code (and unaffected by the presence of `yield` expressions). The borrow checker is extended to pick up the slack so interior references still result in errors for movable generators. This fixes#44197, #45259 and #45093.
This PR depends on [PR #44917 (immovable types)](https://github.com/rust-lang/rust/pull/44917), I suggest potential reviewers ignore the first commit as it adds immovable types.
This commit primarily adds the ability to control what kind of LTO happens when
rustc performs LTO, namely allowing values to be specified to the `-C lto`
option, such as `-C lto=thin` and `-C lto=fat`. (where "fat" is the previous
kind of LTO, throw everything in one giant module)
Along the way this also refactors a number of fields which store information
about whether LTO/ThinLTO are enabled to unify them all into one field through
which everything is dispatched, hopefully removing a number of special cases
throughout.
This is intended to help mitigate #47409 but will require a backport as well,
and this would unfortunately need to be an otherwise insta-stable option.
We needed to manually added the `DW_OP_deref` ourselves in earlier LLVM,
but starting with [D31439] in LLVM 5, it appears that LLVM will always
handle this itself. When we were still adding this manually, the
resulting `.debug_loc` had too many derefs, and this failed test
`debuginfo/by-value-self-argument-in-trait-impl.rs`.
[D31439]: https://reviews.llvm.org/D31439Fixes#47611.
cc @alexcrichton
r? @michaelwoerister
LLVM5: Update DW_OP_plus to DW_OP_plus_uconst
LLVM <= 4.0 used a non-standard interpretation of `DW_OP_plus`. In the
DWARF standard, this adds two items on the expressions stack. LLVM's
behavior was more like DWARF's `DW_OP_plus_uconst` -- adding a constant
that follows the op. The patch series starting with [D33892] switched
to the standard DWARF interpretation, so we need to follow.
[D33892]: https://reviews.llvm.org/D33892Fixes#47464
r? @eddyb
Fixes sparc64 cabi fixes.
Argument up to 16 bytes size is provided in registers.
Return value up to 32 bytes size is stored in registers.
Fixes: #46679
---
Firefox now (almost) build on sparc. Original rust issue seems to be gone. Note that I'm not rust expert and the fix was suggested in bug.
When spawning a linker rustc has historically been known to blow OS limits for
the command line being too large, notably on Windows. This is especially true of
incremental compilation where there can be dozens of object files per
compilation. The compiler currently has logic for detecting a failure to spawn
and instead passing arguments via a file instead, but this failure detection
only triggers if a process actually fails to spawn.
Unfortunately on Windows we've got something else to worry about which is
`cmd.exe`. The compiler may be running a linker through `cmd.exe` where
`cmd.exe` has a limit of 8192 on the command line vs 32k on `CreateProcess`.
Moreso rustc actually succeeds in spawning `cmd.exe` today, it's just that after
it's running `cmd.exe` fails to spawn its child, which rustc doesn't currently
detect.
Consequently this commit updates the logic for the spawning the linker on
Windows to instead have a heuristic to see if we need to pass arguments via a
file. This heuristic is an overly pessimistic and "inaccurate" calculation which
just calls `len` on a bunch of `OsString` instances (where `len` is not
precisely the length in u16 elements). This number, when exceeding the 6k
threshold, will force rustc to always pass arguments through a file.
This strategy should avoid us trying to parse the output on Windows of the
linker to see if it successfully spawned yet failed to actually sub-spawn the
linker. We may just be passing arguments through files a little more commonly
now...
The motivation for this commit was a recent bug in Gecko [1] when beta testing,
notably when incremental compilation was enabled it blew out the limit on
`cmd.exe`. This commit will also fix#46999 as well though as emscripten uses a
bat script as well (and we're blowing the limit there).
[1]: https://bugzilla.mozilla.org/show_bug.cgi?id=1430886Closes#46999
LLVM <= 4.0 used a non-standard interpretation of `DW_OP_plus`. In the
DWARF standard, this adds two items on the expressions stack. LLVM's
behavior was more like DWARF's `DW_OP_plus_uconst` -- adding a constant
that follows the op. The patch series starting with [D33892] switched
to the standard DWARF interpretation, so we need to follow.
[D33892]: https://reviews.llvm.org/D33892
Don't include DefIndex in proc-macro registrar function symbol.
There can only ever be one registrar function per plugin or proc-macro crate, so adding the `DefIndex` to the function's symbol name does not serve a real purpose. Remove the `DefIndex` from the symbol name makes it stable across incremental compilation sessions.
This should fix issue #47292.