about summary refs log tree commit diff
path: root/compiler/rustc_ty_utils
AgeCommit message (Collapse)AuthorLines
2023-08-08feat: `riscv-interrupt-{m,s}` calling conventionsSeth Pellegrino-0/+3
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]: https://github.com/esp-rs/esp-riscv-rt/blob/9281af2ecffe13e40992917316f36920c26acaf3/src/lib.rs#L440-L469 [implemented by]: https://github.com/llvm/llvm-project/blob/b7fb2a3fec7c187d58a6d338ab512d9173bca987/llvm/lib/Target/RISCV/RISCVRegisterInfo.cpp#L61-L67 [callee-save]: https://github.com/llvm/llvm-project/blob/973f1fe7a8591c7af148e573491ab68cc15b6ecf/llvm/lib/Target/RISCV/RISCVCallingConv.td#L30-L37 [rfc]: https://github.com/rust-lang/rfcs/pull/3246
2023-08-08Auto merge of #114602 - compiler-errors:rpit-outlives-sadness, r=oli-obkbors-22/+13
Map RPIT duplicated lifetimes back to fn captured lifetimes Use the [`lifetime_mapping`](https://doc.rust-lang.org/nightly/nightly-rustc/rustc_hir/hir/struct.OpaqueTy.html#structfield.lifetime_mapping) to map an RPIT's captured lifetimes back to the early- or late-bound lifetimes from its parent function. We may be going thru several layers of mapping, since opaques can be nested, so we introduce `TyCtxt::map_rpit_lifetime_to_fn_lifetime` to loop through several opaques worth of mapping, and handle turning it into a `ty::Region` as well. We can then use this instead of the identity substs for RPITs in `check_opaque_meets_bounds` to address #114285. We can then also use `map_rpit_lifetime_to_fn_lifetime` to properly install bidirectional-outlives predicates for both RPITs and RPITITs. This addresses #114601. I based this on #114574, but I don't actually know how much of that PR we still need, so some code may be redundant now... :shrug: --- Fixes #114597 Fixes #114579 Fixes #114285 Also fixes #114601, since it turns out we had other bugs with RPITITs and their duplicated lifetime params :sweat_smile:. Supersedes #114574 r? `@oli-obk`
2023-08-08Install bidirectional outlives predicates for RPITITs (and RPITs) correctlyMichael Goulet-22/+13
2023-08-08Unconditionally record lifetime mappingMichael Goulet-1/+1
2023-08-07Store the laziness of type aliases in the DefKindLeón Orell Valerian Liehr-5/+7
2023-08-02Rollup merge of #114079 - compiler-errors:closure-upvars, r=oli-obkNilstrieb-4/+12
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-01Use upvar_tys in more places, make it a listMichael Goulet-4/+12
2023-08-01Fix a commentMichael Goulet-1/+2
2023-08-01don't create a predicate for just a comparisonMichael Goulet-4/+10
2023-08-01Convert adt_sized_constraint to early-binder, use listMichael Goulet-4/+7
2023-07-31Rollup merge of #114267 - compiler-errors:rpitit-opaque-bounds, r=spastorinoMatthias Krüger-2/+4
Map RPITIT's opaque type bounds back from projections to opaques An RPITIT in a program's AST is eventually translated into both a projection GAT and an opaque. The opaque is used for default trait methods, like: ``` trait Foo { fn bar() -> impl Sized { 0i32 } } ``` The item bounds for both the projection and opaque are identical, and both have a *projection* self ty. This is mostly okay, since we can normalize this projection within the default trait method body to the opaque, but it does two things: 1. it leads to bugs in places where we don't normalize item bounds, like `deduce_future_output_from_obligations` 2. it leads to extra match arms that are both suspicious looking and also easy to miss This PR maps the opaque type bounds of the RPITIT's *opaque* back to the opaque's self type to avoid this quirk. Then we can fix the UI test for #108304 (1.) and also remove a bunch of match arms (2.). Fixes #108304 r? `@spastorino`
2023-07-31We don't need impl_trait_in_trait_parent_fn anymoreMichael Goulet-2/+4
2023-07-30Don't install default projection bound for RPITITsMichael Goulet-1/+3
2023-07-29some nits, bless testMichael Goulet-5/+27
2023-07-29Implement assumed_wf_types for RPITITs' implementationsMichael Goulet-33/+58
2023-07-29Take RPITITs inherit the assumed_wf_types of their parent fnMichael Goulet-0/+38
2023-07-29Rollup merge of #113773 - compiler-errors:err-layout-bail, r=cjgillotMatthias Krüger-2/+13
Don't attempt to compute layout of type referencing error Leads to more ICEs and strange diagnostics than are worth it. Fixes #113760
2023-07-28Rollup merge of #114146 - compiler-errors:dont-report-rpitit-name, r=spastorinoMatthias Krüger-2/+10
Skip reporting item name when checking RPITIT GAT's associated type bounds hold Doesn't really make sense to label an item that has a name that users can't really mention. Fixes #114145. Also fixes #113794. r? `@spastorino`
2023-07-27tighten span slightly for synthetic itemMichael Goulet-2/+10
2023-07-27Don't attempt to compute layout of type referencing errorMichael Goulet-2/+13
2023-07-27Remove `constness` from `ParamEnv`Deadbeef-77/+1
2023-07-25inline format!() args from rustc_codegen_llvm to the end (4)Matthias Krüger-1/+1
r? @WaffleLapkin
2023-07-25Make everything builtin!Michael Goulet-8/+11
2023-07-25Restore tuple unsizing feature gateMichael Goulet-1/+3
2023-07-23fix some clippy::style findingsMatthias Krüger-1/+1
comparison_to_empty iter_nth_zero for_kv_map manual_next_back redundant_pattern
2023-07-21Revert "Auto merge of #113166 - moulins:ref-niches-initial, r=oli-obk"David Tolnay-470/+113
This reverts commit 557359f92512ca88b62a602ebda291f17a953002, reversing changes made to 1e6c09a803fd543a98bfbe1624d697a55300a786.
2023-07-21Track (partial) niche information in `NaiveLayout`Moulins-33/+115
Still more complexity, but this allows computing exact `NaiveLayout`s for null-optimized enums, and thus allows calls like `transmute::<Option<&T>, &U>()` to work in generic contexts.
2023-07-21Move `naive_layout_of` query provider in separate sibling moduleMoulins-230/+253
2023-07-21Add doc-comments for `NaiveLayout`Moulins-1/+1
2023-07-21Track ABI info. in `NaiveLayout`, and use it for `PointerLike` checksMoulins-55/+77
THis significantly complicates `NaiveLayout` logic, but is necessary to ensure that bounds like `NonNull<T>: PointerLike` hold in generic contexts. Also implement exact layout computation for structs.
2023-07-21Track exactness in `NaiveLayout` and use it for `SizeSkeleton` checksMoulins-32/+39
2023-07-21restrict the valid range of references if `-Z reference-niches` is setMoulins-11/+33
Note that this doesn't actually work at all, as many places in rustc assume that references only have the null niche.
2023-07-21add crate-local `-Z reference_niches` unstable flag (does nothing for now)Moulins-2/+9
2023-07-21properly handle arrays and wide pointers in `naive_layout_of`Moulins-80/+115
2023-07-21add `naive_layout_of` queryMoulins-19/+178
2023-07-18Rollup merge of #113824 - lcnr:exhaustive-match, r=wesleywiserMatthias Krüger-3/+27
a small `fn needs_drop` refactor I am generally a fan of exhaustively matching on `TyKind` once we care about more than 1 variant
2023-07-18some additional refactorlcnr-3/+3
also, treat placeholders equal to params
2023-07-17Rename arg_iter to iter_instantiatedMichael Goulet-2/+2
2023-07-17exhaustive matches are goodlcnr-1/+25
2023-07-17Auto merge of #113772 - nnethercote:streamline-size-estimates-2, r=wesleywiserbors-17/+0
Streamline size estimates (take 2) This was merged in #113684 but then [something happened](https://github.com/rust-lang/rust/pull/113684#issuecomment-1636811985): > There has been a bors issue that lead to the merge commit of this PR getting purged from master. > You'll have to make a new PR to reapply it. So this is exactly the same changes. `@bors` r=wesleywiser
2023-07-17Remove `instance_def_size_estimate` query.Nicholas Nethercote-17/+0
It doesn't seem worthwhile now that `MonoItem::size_estimate` is called much less often.
2023-07-17Rollup merge of #113539 - agnarrarendelle:master, r=workingjubileeMatthias Krüger-1/+1
fixed typo Hi, I have fixed a few typos in commands. Please review my pr.
2023-07-15Auto merge of #112157 - erikdesjardins:align, r=nikicbors-0/+10
Resurrect: rustc_target: Add alignment to indirectly-passed by-value types, correcting the alignment of byval on x86 in the process. Same as #111551, which I [accidentally closed](https://github.com/rust-lang/rust/pull/111551#issuecomment-1571222612) :/ --- This resurrects PR #103830, which has sat idle for a while. Beyond #103830, this also: - fixes byval alignment for types containing vectors on Darwin (see `tests/codegen/align-byval-vector.rs`) - fixes byval alignment for overaligned types on x86 Windows (see `tests/codegen/align-byval.rs`) - fixes ABI for types with 128bit requested alignment on ARM64 Linux (see `tests/codegen/aarch64-struct-align-128.rs`) r? `@nikic` --- `@pcwalton's` original PR description is reproduced below: Commit 88e4d2c from five years ago removed support for alignment on indirectly-passed arguments because of problems with the `i686-pc-windows-msvc` target. Unfortunately, the `memcpy` optimizations I recently added to LLVM 16 depend on this to forward `memcpy`s. This commit attempts to fix the problems with `byval` parameters on that target and now correctly adds the `align` attribute. The problem is summarized in [this comment] by `@eddyb.` Briefly, 32-bit x86 has special alignment rules for `byval` parameters: for the most part, their alignment is forced to 4. This is not well-documented anywhere but in the Clang source. I looked at the logic in Clang `TargetInfo.cpp` and tried to replicate it here. The relevant methods in that file are `X86_32ABIInfo::getIndirectResult()` and `X86_32ABIInfo::getTypeStackAlignInBytes()`. The `align` parameter attribute for `byval` parameters in LLVM must match the platform ABI, or miscompilations will occur. Note that this doesn't use the approach suggested by eddyb, because I felt it was overkill to store the alignment in `on_stack` when special handling is really only needed for 32-bit x86. As a side effect, this should fix #80127, because it will make the `align` parameter attribute for `byval` parameters match the platform ABI on LLVM x86-64. [this comment]: #80822 (comment)
2023-07-14i686-windows: make requested alignment > 4 special case apply transitivelyErik Desjardins-5/+5
2023-07-14refactor(rustc_middle): Substs -> GenericArgMahdi Dibaiee-143/+141
2023-07-12Re-format let-else per rustfmt updateMark Rousskov-7/+16
2023-07-12fixed typosagnarrarendelle-1/+1
2023-07-10aarch64-linux: properly handle 128bit aligned aggregatesErik Desjardins-0/+5
2023-07-10repr(align) <= 4 should still be byvalErik Desjardins-5/+5
2023-07-10move has_repr to layout, handle repr(transparent) properlyErik Desjardins-0/+5