Add support for LLVM globals corresponding to miri allocations should be named alloc123
Adds support for this request from @eddyb in #69134:
> That is, if -Zfewer-names is false (usually only because of --emit=llvm-ir), we should use the same name for LLVM globals we generate out of miri allocs as #67133 does in MIR output (allocN).
>
>This way, we can easily see the mapping between MIR and LLVM IR (and it shouldn't be any costlier for regular compilation, which would continue to use unnamed globals).
r? @eddyb
cc @oli-obk
rustc_codegen_ssa: only "spill" SSA-like values to the stack for debuginfo.
This is an implementation of the idea described in https://github.com/rust-lang/rust/issues/68817#issuecomment-583719182.
In short, instead of debuginfo forcing otherwise-SSA-like MIR locals into `alloca`s, and requiring a `load` for each use (or two, for scalar pairs), the `alloca` is now *only* used for attaching debuginfo with `llvm.dbg.declare`: the `OperandRef` is stored to the `alloca`, but *never loaded* from it.
Outside of `debug_introduce_local`, nothing cares about the debuginfo-only `alloca`, and instead works with `OperandRef` the same as MIR locals without debuginfo before this PR.
This should have some of the benefits of `llvm.dbg.value`, while working today.
cc @nagisa @nikomatsakis
Remove problematic specialization from RangeInclusive
Fixes#67194 using the approach [outlined by Mark-Simulacrum](https://github.com/rust-lang/rust/issues/67194#issuecomment-581669549).
> I believe the property we want is that if `PartialEq(&self, &other) == true`, then `self.next() == other.next()`. It is true that this is satisfied by removing the specialization and always doing `is_empty.unwrap_or_default()`; the "wrong" behavior there arises from calling `next()` having an effect on initially empty ranges, as we should be in `is_empty = true` but are not (yet) there. It might be possible to detect that the current state is always empty (i.e., `start > end`) and then not fill in the empty slot. I think this might solve the problem without regressing tests; however, this could have performance implications.
> That approach essentially states that we only use the `is_empty` slot for cases where `start <= end`. That means that `Idx: !Step` and `start > end` would both behave the same, and correctly -- we do not need the boolean if we're not ever going to emit any values from the iterator.
This is implemented here by replacing the `is_empty: Option<bool>` slot with an `exhausted: bool` slot. This flag is
- `false` upon construction,
- `false` when iteration has not yielded an element -- importantly, this means it is always `false` for an iterator empty by construction,
- `false` when iteration has yielded an element and the iterator is not exhausted, and
- only `true` when iteration has been used to exhaust the iterator.
For completeness, this also adds a note to the `Debug` representation to note when the range is exhausted.
This patch enables rustc to emit the required LLVM module flags to enable Control Flow Guard metadata (cfguard=1) or metadata and checks (cfguard=2). The LLVM module flags are ignored on unsupported targets and operating systems.
Stabilize `#[repr(transparent)]` on `enum`s in Rust 1.42.0
# Stabilization report
The following is the stabilization report for `#![feature(transparent_enums)]`.
Tracking issue: https://github.com/rust-lang/rust/issues/60405
[Version target](https://forge.rust-lang.org/#current-release-versions): 1.42 (2020-01-30 => beta, 2020-03-12 => stable).
## User guide
A `struct` with only a single non-ZST field (let's call it `foo`) can be marked as `#[repr(transparent)]`. Such a `struct` has the same layout and ABI as `foo`. Here, we also extend this ability to `enum`s with only one variant, subject to the same restrictions as for the equivalent `struct`. That is, you can now write:
```rust
#[repr(transparent)]
enum Foo { Bar(u8) }
```
which, in terms of layout and ABI, is equivalent to:
```rust
#[repr(transparent)]
struct Foo(u8);
```
## Motivation
This is not a major feature that will unlock new and important use-cases. The utility of `repr(transparent)` `enum`s is indeed limited. However, there is still some value in it:
1. It provides conceptual simplification of the language in terms of treating univariant `enum`s and `struct`s the same, as both are product types. Indeed, languages like Haskell only have `data` as the only way to construct user-defined ADTs in the language.
2. In rare occasions, it might be that the user started out with a univariant `enum` for whatever reason (e.g. they thought they might extend it later). Now they want to make this `enum` `transparent` without breaking users by turning it into a `struct`. By lifting the restriction here, now they can.
## Technical specification
The reference specifies [`repr(transparent)` on a `struct`](https://doc.rust-lang.org/nightly/reference/type-layout.html#the-transparent-representation) as:
> ### The transparent Representation
>
> The `transparent` representation can only be used on `struct`s that have:
> - a single field with non-zero size, and
> - any number of fields with size 0 and alignment 1 (e.g. `PhantomData<T>`).
>
> Structs with this representation have the same layout and ABI as the single non-zero sized field.
>
> This is different than the `C` representation because a struct with the `C` representation will always have the ABI of a `C` `struct` while, for example, a struct with the `transparent` representation with a primitive field will have the ABI of the primitive field.
>
> Because this representation delegates type layout to another type, it cannot be used with any other representation.
Here, we amend this to include univariant `enum`s as well with the same static restrictions and the same effects on dynamic semantics.
## Tests
All the relevant tests are adjusted in the PR diff but are recounted here:
- `src/test/ui/repr/repr-transparent.rs` checks that `repr(transparent)` on an `enum` must be univariant, rather than having zero or more than one variant. Restrictions on the fields inside the only variants, like for those on `struct`s, are also checked here.
- A number of codegen tests are provided as well:
- `src/test/codegen/repr-transparent.rs` (the canonical test)
- `src/test/codegen/repr-transparent-aggregates-1.rs`
- `src/test/codegen/repr-transparent-aggregates-2.rs`
- `src/test/codegen/repr-transparent-aggregates-3.rs`
- `src/test/ui/lint/lint-ctypes-enum.rs` tests the interactions with the `improper_ctypes` lint.
## History
- 2019-04-30, RFC https://github.com/rust-lang/rfcs/pull/2645
Author: @mjbshaw
Reviewers: The Language Team
This is the RFC that proposes allowing `#[repr(transparent)]` on `enum`s and `union`.
- 2019-06-11, PR https://github.com/rust-lang/rust/pull/60463
Author: @mjbshaw
Reviewers: @varkor and @rkruppe
The PR implements the RFC aforementioned in full.
- 2019, PR https://github.com/rust-lang/rust/pull/67323
Author: @Centril
Reviewers: @davidtwco
The PR reorganizes the static checks taking advantage of the fact that `struct`s and `union`s are internally represented as ADTs with a single variant.
- This PR stabilizes `transparent_enums`.
## Related / possible future work
The remaining work here is to figure out the semantics of `#[repr(transparent)]` on `union`s and stabilize those. This work continues to be tracked in https://github.com/rust-lang/rust/issues/60405.
Prepare for LLVM 10 upgrade
Split off from #67759, this just adds the necessary compatibility bits and updates codegen tests, without performing the actual LLVM upgrade.
r? @alexcrichton
Optimize Ord trait implementation for bool
Casting the booleans to `i8`s and converting their difference into `Ordering` generates better assembly than casting them to `u8`s and comparing them.
Fixes#66780
#### Comparison([Godbolt link](https://rust.godbolt.org/z/PjBpvF))
##### Old assembly:
```asm
example::boolean_cmp:
mov ecx, edi
xor ecx, esi
test esi, esi
mov eax, 255
cmove eax, ecx
test edi, edi
cmovne eax, ecx
ret
```
##### New assembly:
```asm
example::boolean_cmp:
mov eax, edi
sub al, sil
ret
```
##### Old LLVM-MCA statistics:
```
Iterations: 100
Instructions: 800
Total Cycles: 234
Total uOps: 1000
Dispatch Width: 6
uOps Per Cycle: 4.27
IPC: 3.42
Block RThroughput: 1.7
```
##### New LLVM-MCA statistics:
```
Iterations: 100
Instructions: 300
Total Cycles: 110
Total uOps: 500
Dispatch Width: 6
uOps Per Cycle: 4.55
IPC: 2.73
Block RThroughput: 1.0
```
LLVM 7 is over a year old, which should be plenty for compatibility. The
last LLVM 6 holdout was llvm-emscripten, which went away in #65501.
I've also included a fix for LLVM 8 lacking `MemorySanitizerOptions`,
which was broken by #66522.
This optimization depends on inlining for the identity
conversions introduced by the lowering of the `?`.
To take advantage of `SimplifyArmIdentity`, `-Z mir-opt-level=2`
is required because that triggers the inlining MIR optimization.
perf.rlo shows that running the `ConstProp` pass results in
across-the-board wins regardless of debug or opt complilation mode. As a
result, we're turning it on to get the compile time benefits.
`ConstProp` doesn't currently intern the memory used by its `Machine` so
we can't yet propagate allocations which is why
`ConstProp::should_const_prop()` checks if the value being propagated is
a scalar or not.
Re-enable Emscripten's exception handling support
Passes LLVM codegen and Emscripten link-time flags for exception
handling if and only if the panic strategy is `unwind`. Sets the
default panic strategy for Emscripten targets to `unwind`. Re-enables
tests that depend on unwinding support for Emscripten, including
`should_panic` tests.
r? @alexcrichton
Passes LLVM codegen and Emscripten link-time flags for exception
handling if and only if the panic strategy is `unwind`. Sets the
default panic strategy for Emscripten targets to `unwind`. Re-enables
tests that depend on unwinding support for Emscripten, including
`should_panic` tests.
Use revisions to run the EFIABI in multiple configurations, compiling
for each supported UEFI platform, and checking the ABI generated in the
LLVM IR is correct.
Use no_core to make it easier to test.