Commit Graph

1457 Commits

Author SHA1 Message Date
XXIV
9adc6a49aa
remove unnecessary heap allocation 2023-09-01 05:22:22 +03:00
bors
8c79e8d756 Auto merge of #115058 - Swatinem:inline-add-coverage, r=compiler-errors
Inline functions called from `add_coverage`

This removes quite a bit of indirection and duplicated code related to getting the `FunctionCoverage`.

CC `@Zalathar`
2023-08-30 17:43:38 +00:00
Matthias Krüger
56d7d93a4b
Rollup merge of #111580 - atsuzaki:layout-ice, r=oli-obk
Don't ICE on layout computation failure

Fixes #111176 regression.

r? `@oli-obk`
2023-08-29 20:49:02 +02:00
Ralf Jung
b2ebf1c23f const_eval and codegen: audit uses of is_zst 2023-08-29 09:03:46 +02:00
bors
f3284dc3ad Auto merge of #115260 - scottmcm:not-quite-so-cold, r=WaffleLapkin
Use `preserve_mostcc` for `extern "rust-cold"`

As experimentation in #115242 has shown looks better than `coldcc`.  Notably, clang exposes `preserve_most` (https://clang.llvm.org/docs/AttributeReference.html#preserve-most) but not `cold`, so this change should put us on a better-supported path.

And *don't* use a different convention for cold on Windows, because that actually ends up making things worse. (See comment in the code.)

cc tracking issue #97544
2023-08-29 02:23:43 +00:00
Katherine Philip
56b767322b Don't ICE on layout computation failure 2023-08-28 12:40:39 -07:00
Matthias Krüger
a5b7504f41
Rollup merge of #115240 - RalfJung:llvm-no-type, r=bjorn3
codegen_llvm/llvm_type: avoid matching on the Rust type

This `match` is highly suspicious. Looking at `scalar_llvm_type_at` I think it makes no difference. But if it were to make a difference that would be a huge problem, since it doesn't look through `repr(transparent)`!

Cc `@eddyb` `@bjorn3`
2023-08-28 19:53:55 +02:00
Ralf Jung
dc70fb6528 also avoid matching on the type in scalar_pair_element_llvm_type 2023-08-28 16:35:00 +02:00
Scott McMurray
754f488d46 Use preserve_mostcc for extern "rust-cold"
As experimentation in 115242 has shown looks better than `coldcc`.

And *don't* use a different convention for cold on Windows, because that actually ends up making things worse.

cc tracking issue 97544
2023-08-26 17:42:59 -07:00
bors
42857db66d Auto merge of #115232 - wesleywiser:revert_114643, r=tmiasko
Revert "Use the same DISubprogram for each instance of the same inline function within the caller"

This reverts commit 687bffa493.

Reverting to resolve ICEs reported on nightly.

cc `@dpaoliello`

Fixes #115156
2023-08-26 07:47:26 +00:00
Ralf Jung
0fde82fb97 codegen_llvm/llvm_type: avoid matching on the Rust type 2023-08-26 08:34:56 +02:00
Scott McMurray
84e305dd93 Stop emitting non-power-of-two vectors in basic LLVM codegen 2023-08-25 20:06:57 -07:00
Wesley Wiser
d0b2c4f727 Revert "Use the same DISubprogram for each instance of the same inlined function within the caller"
This reverts commit 687bffa493.

Reverting to resolve ICEs reported on nightly.
2023-08-25 19:49:10 -04:00
bors
154ae32a55 Auto merge of #114643 - dpaoliello:inlinedebuginfo, r=wesleywiser
Use the same DISubprogram for each instance of the same inlined function within a caller

# Issue Details:
The call to `panic` within a function like `Option::unwrap` is translated to LLVM as a `tail call` (as it will never return), when multiple calls to the same function like this is inlined LLVM will notice the common `tail call` block (i.e., loading the same panic string + location info and then calling `panic`) and merge them together.

When merging these instructions together, LLVM will also attempt to merge the debug locations as well, but this fails (i.e., debug info is dropped) as Rust emits a new `DISubprogram` at each inline site thus LLVM doesn't recognize that these are actually the same function and so thinks that there isn't a common debug location.

As an example of this when building for x86_64 Windows (note the lack of `.cv_loc` before the call to `panic`, thus it will be attributed to the same line at the `addq` instruction):

```
	.cv_loc	0 1 23 0                        # src\lib.rs:23:0
	addq	$40, %rsp
	retq
	leaq	.Lalloc_f570dea0a53168780ce9a91e67646421(%rip), %rcx
	leaq	.Lalloc_629ace53b7e5b76aaa810d549cc84ea3(%rip), %r8
	movl	$43, %edx
	callq	_ZN4core9panicking5panic17h12e60b9063f6dee8E
	int3
```

# Fix Details:
Cache the `DISubprogram` emitted for each inlined function instance within a caller so that this can be reused if that instance is encountered again, this also requires caching the `DILexicalBlock` and `DIVariable` objects to avoid creating duplicates.

After this change the above assembly now looks like:

```
	.cv_loc	0 1 23 0                        # src\lib.rs:23:0
	addq	$40, %rsp
	retq
	.cv_inline_site_id 5 within 0 inlined_at 1 0 0
	.cv_inline_site_id 6 within 5 inlined_at 1 12 0
	.cv_loc	6 2 935 0                       # library\core\src\option.rs:935:0
	leaq	.Lalloc_5f55955de67e57c79064b537689facea(%rip), %rcx
	leaq	.Lalloc_e741d4de8cb5801e1fd7a6c6795c1559(%rip), %r8
	movl	$43, %edx
	callq	_ZN4core9panicking5panic17hde1558f32d5b1c04E
	int3
```
2023-08-22 20:15:29 +00:00
Wesley Wiser
1097e0957e
Fix spelling mistake 2023-08-22 15:30:26 -04:00
Arpad Borsos
2ceea9ae9d
Inline functions called from add_coverage
This removes quite a bit of indirection and duplicated code related to getting the `FunctionCoverage`.
2023-08-22 10:59:19 +02:00
bors
2ceed0b6cb Auto merge of #113814 - ChoKyuWon:master, r=davidtwco
Replace the \01__gnu_mcount_nc to LLVM intrinsic for ARM

Current `-Zinstrument-mcount` for ARM32 use the `\01__gnu_mcount_nc` directly for its instrumentation function.

However, the LLVM does not use this mcount function directly, but it wraps it to intrinsic, `llvm.arm.gnu.eabi.mcount` and the transform pass also only handle the intrinsic.

As a result, current `-Zinstrument-mcount` not work on ARM32. Refer: https://github.com/namhyung/uftrace/issues/1764

This commit replaces the mcount name from native function to the LLVM intrinsic so that the transform pass can handle it.
2023-08-18 13:20:37 +00:00
ChoKyuWon
3bd54c14bc
Replace the \01__gnu_mcount_nc to LLVM intrinsic for ARM
Current `-Zinstrument-mcount` for ARM32 use the `\01__gnu_mcount_nc`
directly for its instrumentation function.

However, the LLVM does not use this mcount function directly, but it wraps
it to intrinsic, `llvm.arm.gnu.eabi.mcount` and the transform pass also
only handle the intrinsic.

As a result, current `-Zinstrument-mcount` not work on ARM32.
Refer: https://github.com/namhyung/uftrace/issues/1764

This commit replaces the mcount name from native function to the
LLVM intrinsic so that the transform pass can handle it.

Signed-off-by: ChoKyuWon <kyuwoncho18@gmail.com>
2023-08-18 01:52:40 +09:00
bors
c1699a79a6 Auto merge of #114467 - Amanieu:asm-unstable-features, r=davidtwco
Use `unstable_target_features` when checking inline assembly

This is necessary to properly validate register classes even when the relevant target feature name is still unstable.
2023-08-15 11:59:02 +00:00
dirreke
74817b7053 Upgrade Object and related deps 2023-08-14 23:05:45 +08:00
Dirreke
184a9afffb add details for csky-unknown-linux-gnuabiv2 and add docs 2023-08-14 23:02:37 +08:00
Dirreke
d16409fe22 add a csky-unknown-linux-gnuabiv2 target 2023-08-14 23:02:36 +08:00
bors
644e8068cb Auto merge of #113722 - bjorn3:allocator_shim_refactor, r=jackh726
Extract a create_wrapper_function for use in allocator shim writing

This deduplicates some logic and makes it easier to follow what wrappers are produced. In the future it may allow moving the code to determine which wrappers to create to cg_ssa.
2023-08-13 16:49:49 +00:00
Daniel Paoliello
687bffa493 Use the same DISubprogram for each instance of the same inlined function within the caller 2023-08-11 10:21:52 -07:00
Michael Goulet
94533d924e
Rollup merge of #114622 - petrochenkov:noplugin, r=oli-obk
rustc: Move `crate_types` and `stable_crate_id` from `Session` to `GlobalCtxt`

Removes two pieces of mutable state.
Follow up to https://github.com/rust-lang/rust/pull/114578.
2023-08-10 21:17:07 -07:00
bors
a9b2c6a0ce Auto merge of #114005 - Zalathar:no-cstr, r=jackh726
coverage: Don't convert filename/symbol strings to `CString` for FFI

LLVM APIs are usually perfectly happy to accept pointer/length strings, as long as we supply a suitable length value when creating a `StringRef` or `std::string`.

This lets us avoid quite a few intermediate `CString` copies during coverage codegen. It also lets us use an `IndexSet<Symbol>` (instead of an `IndexSet<CString>`) when building the deduplicated filename table.
2023-08-10 23:06:10 +00:00
Matthias Krüger
7d78885a8e
Rollup merge of #111891 - rustbox:feat/riscv-isr-cconv, r=jackh726
feat: `riscv-interrupt-{m,s}` calling conventions

Similar to prior support added for the mips430, avr, and x86 targets this change implements the rough equivalent of clang's [`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling e.g.

```rust
static mut CNT: usize = 0;

pub extern "riscv-interrupt-m" fn isr_m() {
    unsafe {
        CNT += 1;
    }
}
```

to produce highly effective assembly like:

```asm
pub extern "riscv-interrupt-m" fn isr_m() {
420003a0:       1141                    addi    sp,sp,-16
    unsafe {
        CNT += 1;
420003a2:       c62a                    sw      a0,12(sp)
420003a4:       c42e                    sw      a1,8(sp)
420003a6:       3fc80537                lui     a0,0x3fc80
420003aa:       63c52583                lw      a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0>
420003ae:       0585                    addi    a1,a1,1
420003b0:       62b52e23                sw      a1,1596(a0)
    }
}
420003b4:       4532                    lw      a0,12(sp)
420003b6:       45a2                    lw      a1,8(sp)
420003b8:       0141                    addi    sp,sp,16
420003ba:       30200073                mret
```

(disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`)

This outcome is superior to hand-coded interrupt routines which, lacking visibility into any non-assembly body of the interrupt handler, have to be very conservative and save the [entire CPU state to the stack frame][full-frame-save]. By instead asking LLVM to only save the registers that it uses, we defer the decision to the tool with the best context: it can more accurately account for the cost of spills if it knows that every additional register used is already at the cost of an implicit spill.

At the LLVM level, this is apparently [implemented by] marking every register as "[callee-save]," matching the semantics of an interrupt handler nicely (it has to leave the CPU state just as it found it after its `{m|s}ret`).

This approach is not suitable for every interrupt handler, as it makes no attempt to e.g. save the state in a user-accessible stack frame. For a full discussion of those challenges and tradeoffs, please refer to [the interrupt calling conventions RFC][rfc].

Inside rustc, this implementation differs from prior art because LLVM does not expose the "all-saved" function flavor as a calling convention directly, instead preferring to use an attribute that allows for differentiating between "machine-mode" and "superivsor-mode" interrupts.

Finally, some effort has been made to guide those who may not yet be aware of the differences between machine-mode and supervisor-mode interrupts as to why no `riscv-interrupt` calling convention is exposed through rustc, and similarly for why `riscv-interrupt-u` makes no appearance (as it would complicate future LLVM upgrades).

[clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v
[full-frame-save]: 9281af2ecf/src/lib.rs (L440-L469)
[implemented by]: b7fb2a3fec/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp (L61-L67)
[callee-save]: 973f1fe7a8/llvm/lib/Target/RISCV/RISCVCallingConv.td (L30-L37)
[rfc]: https://github.com/rust-lang/rfcs/pull/3246
2023-08-09 22:59:58 +02:00
Vadim Petrochenkov
0b89aac08d rustc: Move crate_types from Session to GlobalCtxt
Removes a piece of mutable state.
Follow up to #114578.
2023-08-09 14:17:54 +08:00
Seth Pellegrino
897c7bb23b feat: riscv-interrupt-{m,s} calling conventions
Similar to prior support added for the mips430, avr, and x86 targets
this change implements the rough equivalent of clang's
[`__attribute__((interrupt))`][clang-attr] for riscv targets, enabling
e.g.

```rust
static mut CNT: usize = 0;

pub extern "riscv-interrupt-m" fn isr_m() {
    unsafe {
        CNT += 1;
    }
}
```

to produce highly effective assembly like:

```asm
pub extern "riscv-interrupt-m" fn isr_m() {
420003a0:       1141                    addi    sp,sp,-16
    unsafe {
        CNT += 1;
420003a2:       c62a                    sw      a0,12(sp)
420003a4:       c42e                    sw      a1,8(sp)
420003a6:       3fc80537                lui     a0,0x3fc80
420003aa:       63c52583                lw      a1,1596(a0) # 3fc8063c <_ZN12esp_riscv_rt3CNT17hcec3e3a214887d53E.0>
420003ae:       0585                    addi    a1,a1,1
420003b0:       62b52e23                sw      a1,1596(a0)
    }
}
420003b4:       4532                    lw      a0,12(sp)
420003b6:       45a2                    lw      a1,8(sp)
420003b8:       0141                    addi    sp,sp,16
420003ba:       30200073                mret
```

(disassembly via `riscv64-unknown-elf-objdump -C -S --disassemble ./esp32c3-hal/target/riscv32imc-unknown-none-elf/release/examples/gpio_interrupt`)

This outcome is superior to hand-coded interrupt routines which, lacking
visibility into any non-assembly body of the interrupt handler, have to
be very conservative and save the [entire CPU state to the stack
frame][full-frame-save]. By instead asking LLVM to only save the
registers that it uses, we defer the decision to the tool with the best
context: it can more accurately account for the cost of spills if it
knows that every additional register used is already at the cost of an
implicit spill.

At the LLVM level, this is apparently [implemented by] marking every
register as "[callee-save]," matching the semantics of an interrupt
handler nicely (it has to leave the CPU state just as it found it after
its `{m|s}ret`).

This approach is not suitable for every interrupt handler, as it makes
no attempt to e.g. save the state in a user-accessible stack frame. For
a full discussion of those challenges and tradeoffs, please refer to
[the interrupt calling conventions RFC][rfc].

Inside rustc, this implementation differs from prior art because LLVM
does not expose the "all-saved" function flavor as a calling convention
directly, instead preferring to use an attribute that allows for
differentiating between "machine-mode" and "superivsor-mode" interrupts.

Finally, some effort has been made to guide those who may not yet be
aware of the differences between machine-mode and supervisor-mode
interrupts as to why no `riscv-interrupt` calling convention is exposed
through rustc, and similarly for why `riscv-interrupt-u` makes no
appearance (as it would complicate future LLVM upgrades).

[clang-attr]: https://clang.llvm.org/docs/AttributeReference.html#interrupt-risc-v
[full-frame-save]: 9281af2ecf/src/lib.rs (L440-L469)
[implemented by]: b7fb2a3fec/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp (L61-L67)
[callee-save]: 973f1fe7a8/llvm/lib/Target/RISCV/RISCVCallingConv.td (L30-L37)
[rfc]: https://github.com/rust-lang/rfcs/pull/3246
2023-08-08 18:09:56 -07:00
Matthias Krüger
c097e48082
Rollup merge of #113593 - rcvalle:rust-cfi-fix-90546, r=wesleywiser
CFI: Fix error compiling core with LLVM CFI enabled

Fix #90546 by filtering out global value function pointer types from the type tests, and adding the LowerTypeTests pass to the rustc LTO optimization pipelines.
2023-08-08 21:44:43 +02:00
bors
f525bb4e2a Auto merge of #114439 - Kobzol:remark-pgo-hotness, r=tmiasko
Add hotness data to LLVM remarks

Slight improvement of https://github.com/rust-lang/rust/pull/113040. This makes sure that if PGO is used, remarks generated using `-Zremark-dir` will include the `Hotness` attribute.

r? `@tmiasko`
2023-08-08 15:41:44 +00:00
Jakub Beránek
9d417d7c86
Only enable hotness information when PGO is available 2023-08-08 15:36:55 +02:00
Ramon de C Valle
f837c48f0d CFI: Fix error compiling core with LLVM CFI enabled
Fix #90546 by filtering out global value function pointer types from the
type tests, and adding the LowerTypeTests pass to the rustc LTO
optimization pipelines.
2023-08-07 15:59:15 -07:00
Nikita Popov
ad7ea8b7e6 Update powerpc data layouts
Function pointer alignment is specified since https://reviews.llvm.org/D147016.
2023-08-07 20:35:55 +02:00
Matthias Krüger
cbe2522652
Rollup merge of #114382 - scottmcm:compare-bytes-intrinsic, r=cjgillot
Add a new `compare_bytes` intrinsic instead of calling `memcmp` directly

As discussed in #113435, this lets the backends be the place that can have the "don't call the function if n == 0" logic, if it's needed for the target.  (I didn't actually *add* those checks, though, since as I understood it we didn't actually need them on known targets?)

Doing this also let me make it `const` (unstable), which I don't think `extern "C" fn memcmp` can be.

cc `@RalfJung` `@Amanieu`
2023-08-07 05:29:12 +02:00
scottmcm
75277a6606 Apply suggestions from code review
Co-authored-by: Ralf Jung <post@ralfj.de>
2023-08-06 15:47:40 -07:00
Scott McMurray
502af03445 Add a new compare_bytes intrinsic instead of calling memcmp directly 2023-08-06 15:47:40 -07:00
David Tolnay
704aa56ba0
Generate better function argument names in global_allocator expansion 2023-08-06 07:36:05 -07:00
Matthias Krüger
a0fd747e38
Rollup merge of #114450 - chenyukang:yukang-fix-114435, r=compiler-errors
Fix ICE failed to get layout for ReferencesError

Fixes #114435

r? `@compiler-errors`
2023-08-04 21:31:57 +02:00
yukang
3d25b5c7e8 Fix ICE failed to get layout for ReferencesError 2023-08-05 01:38:14 +08:00
Amanieu d'Antras
a3ab31c0f9 Use unstable_target_features when checking inline assembly
This is necessary to properly validate register classes even when the
relevant target feature name is still unstable.
2023-08-04 16:09:54 +01:00
bjorn3
49ae3b7867 Extract a create_wrapper_function for use in allocator shim writing
This deduplicates some logic and makes it easier to follow what wrappers
are produced. In the future it may allow moving the code to determine
which wrappers to create to cg_ssa.
2023-08-04 13:26:36 +00:00
bors
73dc6f03a2 Auto merge of #114350 - erikdesjardins:ident, r=tmiasko
cg_llvm: stop identifying ADTs in LLVM IR

This is an extension of https://github.com/rust-lang/rust/pull/94107. It may be a minor perf win.

Fixes #96242.

Now that we use opaque pointers, ADTs can no longer be recursive, so we
do not need to name them. Previously, this would be necessary if you had
a struct like

```rs
struct Foo(Box<Foo>, u64, u64);
```

which would be represented with something like

```ll
%Foo = type { %Foo*, i64, i64 }
```

which is now just

```ll
{ ptr, i64, i64 }
```

r? `@tmiasko`
2023-08-04 07:17:02 +00:00
Zalathar
4b154bc8e2 coverage: Don't convert symbol names to CString for FFI 2023-08-04 10:48:05 +10:00
Zalathar
e184118683 coverage: Don't convert filenames to CString for FFI 2023-08-04 10:48:05 +10:00
Oli Scherer
4457ef2c6d Forbid old-style simd_shuffleN intrinsics 2023-08-03 09:29:00 +00:00
Nilstrieb
46f6b05eb7
Rollup merge of #114079 - compiler-errors:closure-upvars, r=oli-obk
Use `upvar_tys` in more places, make it return a list

Just a cleanup that fell out of a PR that I was gonna write, but that PR kinda got stuck.
2023-08-02 13:46:54 +02:00
Zalathar
d6ed6e3904 coverage: Consolidate FFI types into one module
Coverage FFI types were historically split across two modules, because some of
them were needed by code in `rustc_codegen_ssa`.

Now that all of the coverage codegen code has been moved into
`rustc_codegen_llvm` (#113355), it's possible to move all of the FFI types into
a single module, making it easier to see all of them at once.
2023-08-02 15:26:47 +10:00
Michael Goulet
99969d282b Use upvar_tys in more places, make it a list 2023-08-01 23:19:31 +00:00
bors
f77c624c03 Auto merge of #113339 - lqd:respect-filters, r=tmiasko
Filter out short-lived LLVM diagnostics before they reach the rustc handler

During profiling I saw remark passes being unconditionally enabled: for example `Machine Optimization Remark Emitter`.

The diagnostic remarks enabled by default are [from missed optimizations and opt analyses](https://github.com/rust-lang/rust/pull/113339#discussion_r1259480303). They are created by LLVM, passed to the diagnostic handler on the C++ side, emitted to rust, where they are unpacked, C++ strings are converted to rust, etc.

Then they are discarded in the vast majority of the time (i.e. unless some kind of `-Cremark` has enabled some of these passes' output to be printed).

These unneeded allocations are very short-lived, basically only lasting between the LLVM pass emitting them and the rust handler where they are discarded. So it doesn't hugely impact max-rss, and is only a slight reduction in instruction count (cachegrind reports a reduction between 0.3% and 0.5%) _on linux_. It's possible that targets without `jemalloc` or with a worse allocator, may optimize these less.

It is however significant in the aggregate, looking at the total number of allocated bytes:
- it's the biggest source of allocations according to dhat, on the benchmarks I've tried e.g. `syn` or `cargo`
- allocations on `syn` are reduced by 440MB, 17% (from 2440722647 bytes total, to 2030461328 bytes)
- allocations on `cargo` are reduced by 6.6GB, 19% (from 35371886402 bytes total, to 28723987743 bytes)

Some of these diagnostics objects [are allocated in LLVM](https://github.com/rust-lang/rust/pull/113339#discussion_r1252387484) *before* they're emitted to our diagnostic handler, where they'll be filtered out. So we could remove those in the future, but that will require changing a few LLVM call-sites upstream, so I left a FIXME.
2023-08-01 23:15:20 +00:00