about summary refs log tree commit diff
path: root/compiler/rustc_mir_transform/src
AgeCommit message (Collapse)AuthorLines
2023-09-04interpret: make MemPlace, Place, Operand types private to the interpreterRalf Jung-20/+24
2023-09-03Use relative positions inside a SourceFile.Camille GILLOT-19/+14
2023-09-02Take `&mut Results` in `ResultsVisitor`Jason Newcomb-5/+5
2023-08-30Auto merge of #115194 - tmiasko:inline-always-encode-mir, r=compiler-errorsbors-8/+5
Fix inlining with -Zalways-encode-mir Only inline functions that are considered eligible for inlining by the reachability pass. This constraint was previously indirectly enforced by only exporting MIR of eligible functions, but that approach doesn't work with -Zalways-encode-mir enabled.
2023-08-30move marking-locals-live out of push_stack_frame, so it happens with ↵Ralf Jung-0/+20
argument passing this entirely avoids even creating unsized locals in Immediate::Uninitialized state
2023-08-30Rollup merge of #115272 - RalfJung:miri-error-print, r=saethlinMatthias Krüger-1/+2
miri/diagnostics: don't forget to print_backtrace when ICEing on unexpected errors This should fix the missing output encountered [here](https://github.com/rust-lang/rust/issues/115145#issuecomment-1694334410). r? `@saethlin`
2023-08-27Fix inlining with -Zalways-encode-mirTomasz Miąsko-8/+5
Only inline functions that are considered eligible for inlining by the reachability pass. This constraint was previously indirectly enforced by only exporting MIR of eligible functions, but that approach doesn't work with -Zalways-encode-mir enabled.
2023-08-27miri/diagnostics: don't forget to print_backtrace when ICEing on unexpected ↵Ralf Jung-1/+2
errors then also use the new helper in a few other places
2023-08-25Auto merge of #115138 - cjgillot:dse-move-packed, r=compiler-errorsbors-0/+6
Do not convert copies of packed projections to moves. This code path was introduced in https://github.com/rust-lang/rust/pull/113758 After seeing https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/Packed.20fields.20and.20in-place.20function.20argument.2Freturn.20passing, this may be UB, so should be disallowed. This should not appear in normally-built MIR, which introduces temporary copies for packed projections.
2023-08-24Only check packed ADT.Camille GILLOT-4/+6
2023-08-24when terminating during unwinding, show the reason whyRalf Jung-25/+33
2023-08-23Do not convert copies of packed projections to moves.Camille GILLOT-0/+4
2023-08-22Auto merge of #115005 - compiler-errors:passes, r=cjgillotbors-1/+5
Don't do intra-pass validation on MIR shims Fixes #114375 In the test that was committed, we end up generating the drop shim for `struct Foo` that looks like: ``` fn std::ptr::drop_in_place(_1: *mut Foo) -> () { let mut _0: (); bb0: { goto -> bb5; } bb1: { return; } bb2 (cleanup): { resume; } bb3: { goto -> bb1; } bb4 (cleanup): { drop(((*_1).0: foo::WrapperWithDrop<()>)) -> [return: bb2, unwind terminate]; } bb5: { drop(((*_1).0: foo::WrapperWithDrop<()>)) -> [return: bb3, unwind: bb2]; } } ``` In `bb4` and `bb5`, we assert that `(*_1).0` has type `WrapperWithDrop<()>`. However, In a user-facing param env, the type is actually `WrapperWithDrop<Tait>`. These types are not equal in a user-facing param-env (and can't be made equal even if we use `DefiningAnchor::Bubble`, since it's a non-local TAIT).
2023-08-20Auto merge of #114993 - RalfJung:panic-nounwind, r=fee1-deadbors-32/+43
interpret/miri: call the panic_nounwind machinery the same way codegen does
2023-08-20interpret: have assert_* intrinsics call the panic machinery instead of a ↵Ralf Jung-0/+11
direct abort
2023-08-20give some unwind-related terminators a more clear nameRalf Jung-32/+32
2023-08-20Auto merge of #114791 - Zalathar:bcb-counter, r=cjgillotbors-87/+146
coverage: Give the instrumentor its own counter type, separate from MIR Within the MIR representation of coverage data, `CoverageKind` is an important part of `StatementKind::Coverage`, but the `InstrumentCoverage` pass also uses it heavily as an internal data structure. This means that any change to `CoverageKind` also needs to update all of the internal parts of `InstrumentCoverage` that manipulate it directly, making the MIR representation difficult to modify. --- This change fixes that by giving the instrumentor its own `BcbCounter` type for internal use, which is then converted to a `CoverageKind` when injecting coverage information into MIR. The main change is mostly mechanical, because the initial `BcbCounter` is drop-in compatible with `CoverageKind`, minus the unnecessary `CoverageKind::Unreachable` variant. I've then removed the `function_source_hash` field from `BcbCounter::Counter`, as a small example of how the two types can now usefully differ from each other. Every counter in a MIR-level function should have the same source hash, so we can supply the hash during the conversion to `CoverageKind::Counter` instead. --- *Background:* BCB stands for “basic coverage block”, which is a node in the simplified control-flow graph used by coverage instrumentation. The instrumentor pass uses the function's actual MIR control-flow graph to build a simplified BCB graph, then assigns coverage counters and counter expressions to various nodes/edges in that simplified graph, and then finally injects corresponding coverage information into the underlying MIR.
2023-08-20Auto merge of #113124 - nbdd0121:eh_frame, r=cjgillotbors-4/+46
Add MIR validation for unwind out from nounwind functions + fixes to make validation pass `@Nilstrieb` This is the MIR validation you asked in https://github.com/rust-lang/rust/pull/112403#discussion_r1222739722. Two passes need to be fixed to get the validation to pass: * `RemoveNoopLandingPads` currently unconditionally introduce a resume block (even there is none to begin with!), changed to not do that * Generator state transform introduces a `assert` which may unwind, and its drop elaboration also introduces many new `UnwindAction`s, so in this case run the AbortUnwindingCalls after the transformation. I believe this PR should also fix Rust-for-Linux/linux#1016, cc `@ojeda` r? `@Nilstrieb`
2023-08-20coverage: Don't store `function_source_hash` in `BcbCounter::Counter`Zalathar-12/+9
This shows one small benefit of separating `BcbCounter` from `CoverageKind`. The function source hash will be the same for all counters within a function, so instead of passing it through `CoverageCounters` and storing it in every counter, we can just supply it during the final conversion to `CoverageKind`.
2023-08-20coverage: Give the instrumentor its own counter type, separate from MIRZalathar-70/+129
This splits off `BcbCounter` from MIR's `CoverageKind`, allowing the two types to evolve in different directions as necessary.
2023-08-20coverage: Move a debug print into `make_code_region`Zalathar-8/+11
2023-08-20coverage: Remove a useless `let () =`Zalathar-1/+1
2023-08-19Don't do intra-pass validation on MIR shimsMichael Goulet-1/+5
2023-08-19use static arrays instead of vectorsMatthias Krüger-2/+2
2023-08-18Change generator_drop's instance to that of generator for dump_mirGary Guo-1/+8
Otherwise the file name generated for generator_drop will become core.ptr-drop_in_place.[generator@<FILEPATH>_<NUMBERS>].generator_drop.0.mir instead of main-{closure#0}.generator_drop.0.mir which breaks a mir-opt test.
2023-08-18Perform MIR validation on drop glue of generatorGary Guo-1/+10
2023-08-18Run `AbortUnwindingCalls` after generator transformGary Guo-0/+16
2023-08-18Do not create new resume block if there isn't one alreadyGary Guo-3/+13
2023-08-18Auto merge of #114948 - compiler-errors:normalize-before-freeze, r=lcnrbors-1/+6
Normalize before checking if local is freeze in `deduced_param_attrs` Not normalizing the local type eagerly results in possibly exponential amounts of normalization happening downstream in `is_freeze_raw`. Fixes #113372
2023-08-17Normalize before checking if local is freeze in deduced_param_attrsMichael Goulet-1/+6
2023-08-17Revert "Implement references VarDebugInfo."Camille GILLOT-8/+0
This reverts commit 2ec007191348ef7cc13eb55e44e007b02cf75cf3.
2023-08-16Do not pre-compute reachable blocks.Camille GILLOT-20/+0
2023-08-16Update doc comment.Camille GILLOT-1/+1
2023-08-16Make dataflow const-prop handle_switch_int monotonic.Camille GILLOT-8/+11
2023-08-16Make TerminatorEdge plural.Camille GILLOT-3/+3
2023-08-16Rename MaybeUnreachable.Camille GILLOT-2/+2
2023-08-16Use TerminatorEdge for dataflow-const-prop.Camille GILLOT-45/+18
2023-08-16Only run MaybeInitializedPlaces once for drop elaboration.Camille GILLOT-53/+28
2023-08-13Store BCB counters externally, not directly in the BCB graphZalathar-158/+157
Storing coverage counter information in `CoverageCounters` has a few advantages over storing it directly inside BCB graph nodes: - The graph doesn't need to be mutable when making the counters, making it easier to see that the graph itself is not modified during this step. - All of the counter data is clearly visible in one place. - It becomes possible to use a representation that doesn't correspond 1:1 to graph nodes, e.g. storing all the edge counters in a single hashmap instead of several.
2023-08-13Accumulate intermediate expressions into `CoverageCounters`Zalathar-95/+63
This avoids the need to pass around a separate vector to accumulate into, and avoids the need to create a fake empty vector when failure occurs.
2023-08-13Rename helper struct `BcbCounters` to `MakeBcbCounters`Zalathar-4/+3
This avoids confusion with data structures that actually hold BCB counter information.
2023-08-09Rollup merge of #111891 - rustbox:feat/riscv-isr-cconv, r=jackh726Matthias Krüger-0/+2
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]: 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-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-08Added comment on reason for method being publiccedihegi-0/+2
2023-08-08Allow reimplementation of drops_elaborated querycedihegi-2/+2
Make module inner and function run_analysis_to_runtime_passes in rustc_mir_transform public to allow re-implementing the query from the rust compiler interface.
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