Commit Graph

97 Commits

Author SHA1 Message Date
Jubilee Young
b895bf4fdc compiler: Directly use rustc_abi in codegen 2024-11-03 12:30:32 -08:00
Jubilee Young
7086dd83cc compiler: rustc_abi::Abi => BackendRepr
The initial naming of "Abi" was an awful mistake, conveying wrong ideas
about how psABIs worked and even more about what the enum meant.
It was only meant to represent the way the value would be described to
a codegen backend as it was lowered to that intermediate representation.
It was never meant to mean anything about the actual psABI handling!
The conflation is because LLVM typically will associate a certain form
with a certain ABI, but even that does not hold when the special cases
that actually exist arise, plus the IR annotations that modify the ABI.

Reframe `rustc_abi::Abi` as the `BackendRepr` of the type, and rename
`BackendRepr::Aggregate` as `BackendRepr::Memory`. Unfortunately, due to
the persistent misunderstandings, this too is now incorrect:
- Scattered ABI-relevant code is entangled with BackendRepr
- We do not always pre-compute a correct BackendRepr that reflects how
  we "actually" want this value to be handled, so we leave the backend
  interface to also inject various special-cases here
- In some cases `BackendRepr::Memory` is a "real" aggregate, but in
  others it is in fact using memory, and in some cases it is a scalar!

Our rustc-to-backend lowering code handles this sort of thing right now.
That will eventually be addressed by lifting duplicated lowering code
to either rustc_codegen_ssa or rustc_target as appropriate.
2024-10-29 14:56:00 -07:00
Jubilee Young
88a9edc091 compiler: Add is_uninhabited and use LayoutS accessors
This reduces the need of the compiler to peek on the fields of LayoutS.
2024-10-28 09:58:30 -07:00
Jubilee Young
1379ef592a compiler: Factor rustc_target::abi out of cg_llvm 2024-10-08 18:24:56 -07:00
Urgau
018ba0528f Use wide pointers consistenly across the compiler 2024-10-04 14:06:48 +02:00
Michael Goulet
c682aa162b Reformat using the new identifier sorting from rustfmt 2024-09-22 19:11:29 -04:00
Folkert de Vries
1ddd67a79a add C-cmse-nonsecure-entry ABI 2024-09-21 13:04:14 +02:00
Josh Stone
6fd8a50680 Update the minimum external LLVM to 18 2024-09-18 13:53:31 -07:00
Nicholas Nethercote
410a2de0c0 Rename {ArgAbi,IntrinsicCall}Methods.
They both are part of `BuilderMethods`, and so should have `Builder` in
their name like all the other traits in `BuilderMethods`.
2024-09-17 10:24:43 +10:00
Nicholas Nethercote
61627438eb Add warn(unreachable_pub) to rustc_codegen_llvm. 2024-08-16 08:46:57 +10:00
bors
e08b80c0fb Auto merge of #128371 - andjo403:rangeAttribute, r=nikic
Add range attribute to scalar function results and arguments

as LLVM 19 adds the range attribute this starts to use it for better optimization.
hade been interesting to see a perf run with the https://github.com/rust-lang/rust/pull/127513

closes https://github.com/rust-lang/rust/issues/50156
cc https://github.com/rust-lang/rust/issues/49572 shall be fixed but not possible to see as there is asserts that already trigger the optimization.
2024-08-12 10:20:00 +00:00
Andreas Jonson
cfadfabfcd Add range attribute to scalar function results and arguments 2024-08-11 19:40:44 +02:00
Ralf Jung
273c67db83 codegen: better centralize function attribute computation 2024-08-07 19:49:48 +02:00
bors
80d8270d84 Auto merge of #125016 - nicholasbishop:bishop-cb-112, r=tgross35
Update compiler_builtins to 0.1.114

The `weak-intrinsics` feature was removed from compiler_builtins in https://github.com/rust-lang/compiler-builtins/pull/598, so dropped the `compiler-builtins-weak-intrinsics` feature from alloc/std/sysroot.

In https://github.com/rust-lang/compiler-builtins/pull/593, some builtins for f16/f128 were added. These don't work for all compiler backends, so add a `compiler-builtins-no-f16-f128` feature and disable it for cranelift and gcc.
2024-07-29 07:41:33 +00:00
Nicholas Nethercote
84ac80f192 Reformat use declarations.
The previous commit updated `rustfmt.toml` appropriately. This commit is
the outcome of running `x fmt --all` with the new formatting options.
2024-07-29 08:26:52 +10:00
DianQK
c453dcd62a
Use the aligned size for alloca at args when the pass mode is cast.
The `load` and `store` instructions in LLVM access the aligned size.
2024-07-02 06:33:35 +08:00
Nicholas Bishop
99e6a28804 Add f16/f128 handling in a couple places 2024-05-30 18:33:50 -04:00
Michael Goulet
d50c2b0a52 Make builtin_deref just return a Ty 2024-05-09 22:55:00 -04:00
bors
284f94f9c0 Auto merge of #121298 - nikic:writable, r=cuviper
Set writable and dead_on_unwind attributes for sret arguments

Set the `writable` and `dead_on_unwind` attributes for `sret` arguments. This allows call slot optimization to remove more memcpy's.

See https://llvm.org/docs/LangRef.html#parameter-attributes for the specification of these attributes. In short, the statement we're making here is that:

 * The return slot is writable.
 * The return slot will not be read if the function unwinds.

Fixes https://github.com/rust-lang/rust/issues/90595.
2024-04-25 04:31:56 +00:00
Nikita Popov
3695af697e Set writable and dead_on_unwind attributes for sret arguments 2024-04-25 11:43:47 +09:00
bors
29a56a3b1c Auto merge of #122053 - erikdesjardins:alloca, r=nikic
Stop using LLVM struct types for alloca

The alloca type has no semantic meaning, only the size (and alignment, but we specify it explicitly) matter. Using `[N x i8]` is a more direct way to specify that we want `N` bytes, and avoids relying on LLVM's struct layout. It is likely that a future LLVM version will change to an untyped alloca representation.

Split out from #121577.

r? `@ghost`
2024-04-24 03:00:44 +00:00
Erik Desjardins
f4426c189f use [N x i8] for alloca types 2024-04-11 21:42:35 -04:00
Scott McMurray
3596098823 Put PlaceValue into OperandValue::Ref, rather than 3 tuple fields 2024-04-11 00:10:10 -07:00
Scott McMurray
89502e584b Make PlaceRef hold a PlaceValue for the non-layout fields (like OperandRef does) 2024-04-11 00:10:10 -07:00
Nikita Popov
1b7342b411 force_array -> is_consecutive
The actual ABI implication here is that in some cases the values
are required to be "consecutive", i.e. must either all be passed
in registers or all on stack (without padding).

Adjust the code to either use Uniform::new() or Uniform::consecutive()
depending on which behavior is needed.

Then, when lowering this in LLVM, skip the [1 x i128] to i128
simplification if is_consecutive is set. i128 is the only case
I'm aware of where this is problematic right now. If we find
other cases, we can extend this (either based on target information
or possibly just by not simplifying for is_consecutive entirely).
2024-04-08 11:31:43 +09:00
Nikita Popov
009280c5e3 Fix argument ABI for overaligned structs on ppc64le
When passing a 16 (or higher) aligned struct by value on ppc64le,
it needs to be passed as an array of `i128` rather than an array
of `i64`. This will force the use of an even starting register.

For the case of a 16 byte struct with alignment 16 it is important
that `[1 x i128]` is used instead of `i128` -- apparently, the
latter will get treated similarly to `[2 x i64]`, not exhibiting
the correct ABI. Add a `force_array` flag to `Uniform` to support
this.

The relevant clang code can be found here:
fe2119a7b0/clang/lib/CodeGen/Targets/PPC.cpp (L878-L884)
fe2119a7b0/clang/lib/CodeGen/Targets/PPC.cpp (L780-L784)

I think the corresponding psABI wording is this:

> Fixed size aggregates and unions passed by value are mapped to as
> many doublewords of the parameter save area as the value uses in
> memory. Aggregrates and unions are aligned according to their
> alignment requirements. This may result in doublewords being
> skipped for alignment.

In particular the last sentence.

Fixes https://github.com/rust-lang/rust/issues/122767.
2024-04-08 11:15:36 +09:00
Erik Desjardins
8841315d3e make PassMode::Cast consistently copy between Rust/ABI representation
Previously, we did this slightly incorrectly for return values, and
didn't do it at all for arguments.
2024-03-17 00:39:21 -04:00
Erik Desjardins
74ef47e90c make CastTarget::size and CastTarget::llvm_type consistent, remove
special case that's not present in Clang

Making the methods consistent doesn't require much justification. It's
required for us to generate correct code.

The special case was present near the end of `CastTarget::llvm_type`, and
resulted in the final integer component of the ABI type being shrunk to
the smallest integer that fits.

You can see this in action here (https://godbolt.org/z/Pe73cr91d),
where, for a struct with 5 u16 elements, rustc generates
`{ i64, i16 }`, while Clang generates `[2 x i64]`.

This special case was added a long time ago, when the function was
originally written [1]. That commit consolidated logic from many
backends, and in some of the code it deleted, sparc64 [2] and
powerpc64 [3] had similar special cases.

However, looking at Clang today, it doesn't have this special case for
sparc64 (https://godbolt.org/z/YaafvYWdf) or powerpc64
(https://godbolt.org/z/5c3YePTje), so this change just removes it.

[1]: f0636b61c7 (diff-183c4dadf10704bd1f521b71f71d89bf755c9603a93f894d66c03bb1effc6021R231)
[2]: f0636b61c7 (diff-2d8f87ea6db6d7f0a6fbeb1d5549adc07e93331278d951a1e051a40f92914436L163-L166)
[3]: f0636b61c7 (diff-88af4a9df9ead503a5c7774a0455d270dea3ba60e9b0ec1ce550b4c53d3bce3bL172-L175)
2024-03-17 00:38:19 -04:00
Erik Desjardins
207fe38630 copy byval argument to alloca if alignment is insufficient 2024-03-11 09:38:54 -04:00
Erik Desjardins
96a72676d1 use [N x i8] for byval/sret types
This avoids depending on LLVM's struct types to determine the size of
the byval/sret slot.
2024-03-05 18:54:45 -05:00
clubby789
f6b21e90d1 Remove the abi_amdgpu_kernel feature 2024-01-30 15:46:40 +00:00
Nikita Popov
c2fd26a115 Separate immediate and in-memory ScalarPair representation
Currently, we assume that ScalarPair is always represented using
a two-element struct, both as an immediate value and when stored
in memory.

This currently works fairly well, but runs into problems with
https://github.com/rust-lang/rust/pull/116672, where a ScalarPair
involving an i128 type can no longer be represented as a two-element
struct in memory. For example, the tuple `(i32, i128)` needs to be
represented in-memory as `{ i32, [3 x i32], i128 }` to satisfy
alignment requirement. Using `{ i32, i128 }` instead will result in
the second element being stored at the wrong offset (prior to
LLVM 18).

Resolve this issue by no longer requiring that the immediate and
in-memory type for ScalarPair are the same. The in-memory type
will now look the same as for normal struct types (and will include
padding filler and similar), while the immediate type stays a
simple two-element struct type. This also means that booleans in
immediate ScalarPair are now represented as i1 rather than i8,
just like we do everywhere else.

The core change here is to llvm_type (which now treats ScalarPair
as a normal struct) and immediate_llvm_type (which returns the
two-element struct that llvm_type used to produce). The rest is
fixing things up to no longer assume these are the same. In
particular, this switches places that try to get pointers to the
ScalarPair elements to use byte-geps instead of struct-geps.
2023-12-15 17:42:05 +01:00
surechen
40ae34194c remove redundant imports
detects redundant imports that can be eliminated.

for #117772 :

In order to facilitate review and modification, split the checking code and
removing redundant imports code into two PR.
2023-12-10 10:56:22 +08:00
Nilstrieb
21a870515b Fix clippy::needless_borrow in the compiler
`x clippy compiler -Aclippy::all -Wclippy::needless_borrow --fix`.

Then I had to remove a few unnecessary parens and muts that were exposed
now.
2023-11-21 20:13:40 +01:00
Ralf Jung
405e4204d0 move ABI sanity check from LLVM codegen backend to ABI computation logic 2023-11-03 07:14:27 +01:00
Kjetil Kjeka
bb45c812e0 Link to correct issue in PassMode::Direct ptx-kernel exception 2023-10-27 11:39:20 +02:00
Kjetil Kjeka
4d33876778 Documentation and error message improvements related to PassMode::Direct assert
Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
2023-10-27 00:55:24 +02:00
Kjetil Kjeka
84c9c4aca7 NVPTX: Allow PassMode::Direct for ptx kernels for now 2023-10-26 21:57:19 +02:00
Ralf Jung
3ee65c28e9 cannot have Direct for unsized types 2023-09-15 10:45:37 +02:00
Ralf Jung
89139d4c46 clarify PassMode::Indirect as well 2023-09-15 10:43:44 +02:00
Ralf Jung
7740476a43 explain PassMode::Cast 2023-09-15 10:43:44 +02:00
Ralf Jung
28d152935e the wasm ABI behavior is a bug 2023-09-08 09:14:07 +02:00
Ralf Jung
c981026195 extend comments around PassMode::Direct 2023-09-07 09:14:02 +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
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
Erik Desjardins
b6540777fe cg_llvm: remove pointee types and pointercast/bitcast-of-ptr 2023-07-29 13:18:17 -04:00
Boxy
12138b8e5e Move TyCtxt::mk_x to Ty::new_x where applicable 2023-07-05 20:27:07 +01:00
Maybe Waffle
6a28fb42a8 Remove double spaces after dots in comments 2023-01-17 08:09:33 +00:00
Erik Desjardins
d165a6d708 cleanup: handle -Zmutable-noalias like -Zbox-noalias 2023-01-04 19:24:42 -05:00
Ayush Singh
9f0a8620bd
Improve generating Custom entry function
This commit is aimed at making compiler generated entry functions
(Basically just C `main` right now) more generic so other targets can do
similar things for custom entry. This was initially implemented as part
of https://github.com/rust-lang/rust/pull/100316.

Currently, this moves the entry function name and Call convention to the
target spec.

Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
2022-11-11 01:04:39 +05:30