about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
AgeCommit message (Collapse)AuthorLines
2023-08-08feat: `riscv-interrupt-{m,s}` calling conventionsSeth Pellegrino-0/+2
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-07Auto merge of #113902 - Enselic:lint-recursive-drop, r=oli-obkbors-0/+4
Make `unconditional_recursion` warning detect recursive drops Closes #55388 Also closes #50049 unless we want to keep it for the second example which this PR does not solve, but I think it is better to track that work in #57965. r? `@oli-obk` since you are the mentor for #55388 Unresolved questions: - [x] There are two false positives that must be fixed before merging (see diff). I suspect the best way to solve them is to perform analysis after drop elaboration instead of before, as now, but I have not explored that any further yet. Could that be an option? **Answer:** Yes, that solved the problem. `@rustbot` label +T-compiler +C-enhancement +A-lint
2023-08-06Auto merge of #114502 - cjgillot:steal-ctfe, r=oli-obkbors-1/+8
Steal MIR for CTFE when possible. Some bodies, like constants, have CTFE MIR but no optimized MIR. In that case, have `mir_for_ctfe` steal the MIR instead of cloning it.
2023-08-06Rollup merge of #114505 - ouz-a:cleanup_mir, r=RalfJungMatthias Krüger-2/+2
Add documentation to has_deref Documentation of `has_deref` needed some polish to be more clear about where it should be used and what's it's purpose. cc https://github.com/rust-lang/rust/issues/114401 r? `@RalfJung`
2023-08-06cleanup misinformation regarding has_derefouz-a-2/+2
2023-08-05Steal MIR for CTFE when possible.Camille GILLOT-1/+8
2023-08-05Auto merge of #114459 - cjgillot:simplify-ctfe, r=oli-obkbors-29/+0
Do not run ConstProp on mir_for_ctfe. This pass does not seem to be useful any more. The const-prop lints are now run by `tcx.mir_drops_elaborated_and_const_checked`, and the const-prop opt should never emit any diagnostic.
2023-08-05Do not run ConstProp on mir_for_ctfe.Camille GILLOT-29/+0
2023-08-04Rollup merge of #113534 - oli-obk:simd_shuffle_dehackify, r=workingjubileeMatthias Krüger-1/+1
Forbid old-style `simd_shuffleN` intrinsics Don't merge before https://github.com/rust-lang/packed_simd/pull/350 has made its way to crates.io We used to support specifying the lane length of simd_shuffle ops by attaching the lane length to the name of the intrinsic (like `simd_shuffle16`). After this PR, you cannot do that anymore, and need to instead either rely on inference of the `idx` argument type or specify it as `simd_shuffle::<_, [u32; 16], _>`. r? `@workingjubilee`
2023-08-03Explicitly don't inline user-written rust-call fnsMichael Goulet-1/+8
2023-08-03Only unpack tupled args in inliner if we expect args to be unpackedMichael Goulet-6/+9
2023-08-03Forbid old-style `simd_shuffleN` intrinsicsOli Scherer-1/+1
2023-08-01Use upvar_tys in more places, make it a listMichael Goulet-2/+2
2023-08-01Make coverage counter IDs count up from 0, not 1Zalathar-13/+10
Operand types are now tracked explicitly, so there is no need to reserve ID 0 for the special always-zero counter. As part of the renumbering, this change fixes an off-by-one error in the way counters were counted by the `coverageinfo` query. As a result, functions should now have exactly the number of counters they actually need, instead of always having an extra counter that is never used.
2023-08-01Make coverage expression IDs count up from 0, not down from `u32::MAX`Zalathar-17/+13
Operand types are now tracked explicitly, so there is no need for expression IDs to avoid counter IDs by descending from `u32::MAX`. Instead they can just count up from 0, and can be used directly as indices when necessary.
2023-08-01Replace `ExpressionOperandId` with enum `Operand`Zalathar-67/+44
Because the three kinds of operand are now distinguished explicitly, we no longer need fiddly code to disambiguate counter IDs and expression IDs based on the total number of counters/expressions in a function. This does increase the size of operands from 4 bytes to 8 bytes, but that shouldn't be a big deal since they are mostly stored inside boxed structures, and the current coverage code is not particularly size-optimized anyway.
2023-07-30inline format!() args up to and including rustc_middleMatthias Krüger-1/+1
2023-07-28Replace a lazy `RefCell<Option<T>>` with `OnceCell<T>`Zalathar-4/+3
2023-07-27Rollup merge of #114075 - matthiaskrgr:fmt_args_rustc_3, r=wesleywiserMatthias Krüger-31/+27
inline format!() args from rustc_codegen_llvm to the end (4) r? `@WaffleLapkin`
2023-07-25inline format!() args from rustc_codegen_llvm to the end (4)Matthias Krüger-31/+27
r? @WaffleLapkin
2023-07-25interpret: make read functions generic over operand typeRalf Jung-2/+2
2023-07-22Make `unconditional_recursion` warning detect recursive dropsMartin Nordholts-0/+4
2023-07-21Reuse MIR validator for inliner.Camille GILLOT-117/+17
2023-07-21Auto merge of #113802 - cjgillot:check-debuginfo, r=compiler-errorsbors-1/+14
Substitute types before checking inlining compatibility. Addresses https://github.com/rust-lang/rust/issues/112332 and https://github.com/rust-lang/rust/issues/113781 I don't have a minimal test, but I this seems to remove the ICE locally. This whole pre-inlining validation mirrors the "real" MIR validation pass to verify that inlined MIR will still pass validation. The debuginfo loop is added because MIR validation check projections in debuginfo. Likewise, MIR validation only checks `is_subtype`, so there is no reason for a stronger check. The types were not being substituted in `check_equal`, so we were not bailing out of inlining if the substituted MIR callee body would not pass validation.
2023-07-20Inline should_const_prop.Camille GILLOT-20/+4
2023-07-20Remove visit_terminator.Camille GILLOT-65/+0
2023-07-20Propagate ScalarPair for any type.Camille GILLOT-34/+16
2023-07-20Also propagate ScalarPair operands.Camille GILLOT-84/+59
2023-07-20Always propagate into operands.Camille GILLOT-6/+1
2023-07-19Substitute types before checking compatibility.Camille GILLOT-1/+14
2023-07-19Turn copy into moves during DSE.Camille GILLOT-2/+38
2023-07-14Auto merge of #109025 - cjgillot:refprop-dbg, r=JakobDegenbors-16/+28
Enable MIR reference propagation by default
2023-07-14refactor(rustc_middle): Substs -> GenericArgMahdi Dibaiee-140/+141
2023-07-14Introduce ExtentUnord trait for collections that can safely consume UnordItems.Michael Woerister-1/+1
2023-07-12Re-format let-else per rustfmt updateMark Rousskov-62/+64
2023-07-11miri: protect Move() function arguments during the callRalf Jung-5/+5
2023-07-10Call super for debuginfo.Camille GILLOT-3/+16
2023-07-10Simplify visit_place.Camille GILLOT-14/+13
2023-07-10Perform reference propagation earlier.Camille GILLOT-1/+1
2023-07-10Enable by default.Camille GILLOT-1/+1
2023-07-07Rename `adjustment::PointerCast` and variants using it to `PointerCoercion`Nilstrieb-1/+1
It makes it sound like the `ExprKind` and `Rvalue` are supposed to represent all pointer related casts, when in reality their just used to share a some enum variants. Make it clear there these are only coercion to make it clear why only some pointer related "casts" are in the enum.
2023-07-05Move `TyCtxt::mk_x` to `Ty::new_x` where applicableBoxy-27/+40
2023-07-03Auto merge of #112882 - DrMeepster:new_un_derefer, r=oli-obkbors-20/+7
Rewrite `UnDerefer` Currently, `UnDerefer` is used by drop elaboration to undo the effects of the `Derefer` pass. However, it just recreates the original places with derefs in the middle of the projection. Because `ProjectionElem::Deref` is intended to be removed completely in the future, this will not work forever. This PR introduces a `deref_chain` method that returns the places behind `DerefTemp` locals in a place and rewrites the move path code to use this. In the process, `UnDerefer` was merged into `MovePathLookup`. Now that move paths use the same places as in the MIR, the other uses of `UnDerefer` no longer require it. See #98145 cc `@ouz-a` r? `@oli-obk`
2023-06-29Merge `un_derefer` into `MovePathLookup`DrMeepster-20/+7
2023-06-30Auto merge of #113116 - nnethercote:codegen-opts, r=oli-obkbors-5/+5
A mish-mash of micro-optimizations These were aimed at speeding up LLVM codegen, but ended up affecting other places as well. r? `@bjorn3`
2023-06-29Avoid cloning `LocalDecls`.Nicholas Nethercote-5/+5
`DerefChecker` can just hold a reference instead. This avoids quite a lot of allocations for some benchmarks.
2023-06-28Auto merge of #112307 - lcnr:operand-ref, r=compiler-errorsbors-9/+48
mir opt + codegen: handle subtyping fixes #107205 the same issue was caused in multiple places: - mir opts: both copy and destination propagation - codegen: assigning operands to locals (which also propagates values) I changed codegen to always update the type in the operands used for locals which should guard against any new occurrences of this bug going forward. I don't know how to make mir optimizations more resilient here. Hopefully the added tests will be enough to detect any trivially wrong optimizations going forward.
2023-06-27Auto merge of #113105 - matthiaskrgr:rollup-rci0uym, r=matthiaskrgrbors-4/+5
Rollup of 8 pull requests Successful merges: - #112207 (Add trustzone and virtualization target features for aarch32.) - #112454 (Make compiletest aware of targets without dynamic linking) - #112628 (Allow comparing `Box`es with different allocators) - #112692 (Provide more context for `rustc +nightly -Zunstable-options` on stable) - #112972 (Make `UnwindAction::Continue` explicit in MIR dump) - #113020 (Add tests impl via obj unless denied) - #113084 (Simplify some conditions) - #113103 (Normalize types when applying uninhabited predicate.) r? `@ghost` `@rustbot` modify labels: rollup
2023-06-27Rollup merge of #113084 - WaffleLapkin:less_map_or, r=NilstriebMatthias Krüger-4/+5
Simplify some conditions r? `@Nilstrieb` Some things taken out of my `is_none_or` pr.
2023-06-27Rollup merge of #113079 - Zalathar:as-operand-id, r=oli-obkMatthias Krüger-15/+2
Use `CoverageKind::as_operand_id` instead of manually reimplementing it These two pieces of code are functionally equivalent to the `CoverageKind::as_operand_id` method that already exists, and is already used elsewhere in this file. This slightly reduces the amount of code that manually pattern-matches on `CoverageKind`.