Commit graph

1214 commits

Author SHA1 Message Date
bors
a991861ec9 Auto merge of #115507 - cjgillot:relative-source-file, r=oli-obk
Use relative positions inside a SourceFile.

This allows to remove the normalization of start positions for hashing, and simplify allocation of global address space.

cc `@Zoxc`
2023-09-05 21:03:56 +00:00
Camille GILLOT
26c48e6f95 Refactor how MIR represents composite debuginfo. 2023-09-05 17:20:07 +00:00
Matthias Krüger
09974dfc69
Rollup merge of #115536 - RalfJung:interpreter-privacy, r=oli-obk
interpret: make MemPlace, Place, Operand types private to the interpreter

Outside the interpreter, only the typed versions should be used.
2023-09-05 15:16:50 +02:00
bors
8cfaf70c32 Auto merge of #115553 - matthiaskrgr:rollup-c0045hz, r=matthiaskrgr
Rollup of 5 pull requests

Successful merges:

 - #115353 (Emit error instead of ICE when optimized MIR is missing)
 - #115488 (Take `&mut Results` in `ResultsVisitor`)
 - #115492 (Allow `large_assignments` for Box/Arc/Rc initialization)
 - #115519 (Don't ICE on associated type projection without feature gate in new solver)
 - #115534 (Expose more information with DefId in smir)

r? `@ghost`
`@rustbot` modify labels: rollup
2023-09-05 05:34:18 +00:00
Ralf Jung
7093903ba7 read_via_copy: don't prematurely optimize away the read 2023-09-04 18:27:34 +02:00
Ralf Jung
fa5f13775a interpret: make MemPlace, Place, Operand types private to the interpreter 2023-09-04 17:53:38 +02:00
Camille GILLOT
258ace613d Use relative positions inside a SourceFile. 2023-09-03 12:56:10 +00:00
Jason Newcomb
f686bd8949 Take &mut Results in ResultsVisitor 2023-09-02 19:35:51 -04:00
bors
b1b244da65 Auto merge of #115194 - tmiasko:inline-always-encode-mir, r=compiler-errors
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-30 22:51:12 +00:00
Ralf Jung
a09df43d9f move marking-locals-live out of push_stack_frame, so it happens with argument passing
this entirely avoids even creating unsized locals in Immediate::Uninitialized state
2023-08-30 13:46:54 +02:00
Matthias Krüger
23f86255ef
Rollup merge of #115272 - RalfJung:miri-error-print, r=saethlin
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-30 07:18:11 +02:00
Tomasz Miąsko
fe3cd2d194 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-27 23:52:27 +02:00
Ralf Jung
beeb2b13cc miri/diagnostics: don't forget to print_backtrace when ICEing on unexpected errors
then also use the new helper in a few other places
2023-08-27 15:42:25 +02:00
bors
25ed43ddf3 Auto merge of #115138 - cjgillot:dse-move-packed, r=compiler-errors
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-25 13:27:21 +00:00
Camille GILLOT
15a68610dd Only check packed ADT. 2023-08-24 15:42:55 +00:00
Ralf Jung
4c53783f3c when terminating during unwinding, show the reason why 2023-08-24 13:28:26 +02:00
Camille GILLOT
1c5f1762b7 Do not convert copies of packed projections to moves. 2023-08-23 16:09:57 +00:00
bors
c469197b19 Auto merge of #115005 - compiler-errors:passes, r=cjgillot
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-22 22:04:49 +00:00
bors
5c6a7e71cd Auto merge of #114993 - RalfJung:panic-nounwind, r=fee1-dead
interpret/miri: call the panic_nounwind machinery the same way codegen does
2023-08-20 22:01:18 +00:00
Ralf Jung
ac3bca24b7 interpret: have assert_* intrinsics call the panic machinery instead of a direct abort 2023-08-20 15:52:40 +02:00
Ralf Jung
818ec8e23a give some unwind-related terminators a more clear name 2023-08-20 15:52:38 +02:00
bors
0510a1526d Auto merge of #114791 - Zalathar:bcb-counter, r=cjgillot
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-20 13:37:47 +00:00
bors
ff55fa3026 Auto merge of #113124 - nbdd0121:eh_frame, r=cjgillot
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-20 09:58:52 +00:00
Zalathar
72f4c78dc6 coverage: Don't store function_source_hash in BcbCounter::Counter
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-20 12:02:40 +10:00
Zalathar
fbab055e77 coverage: Give the instrumentor its own counter type, separate from MIR
This splits off `BcbCounter` from MIR's `CoverageKind`, allowing the two types
to evolve in different directions as necessary.
2023-08-20 12:02:40 +10:00
Zalathar
629437eec7 coverage: Move a debug print into make_code_region 2023-08-20 12:02:40 +10:00
Zalathar
cad50f40e5 coverage: Remove a useless let () = 2023-08-20 12:02:40 +10:00
Michael Goulet
acd3542b8d Don't do intra-pass validation on MIR shims 2023-08-19 18:47:08 +00:00
Matthias Krüger
4cd3b0b71c use static arrays instead of vectors 2023-08-19 18:49:58 +02:00
Gary Guo
0a7202d476 Change generator_drop's instance to that of generator for dump_mir
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-18 16:40:18 +01:00
Gary Guo
907e431f93 Perform MIR validation on drop glue of generator 2023-08-18 13:51:42 +01:00
Gary Guo
cec8e09edf Run AbortUnwindingCalls after generator transform 2023-08-18 13:51:42 +01:00
Gary Guo
cfbf1bf7cd Do not create new resume block if there isn't one already 2023-08-18 13:51:42 +01:00
bors
0f7f6b7061 Auto merge of #114948 - compiler-errors:normalize-before-freeze, r=lcnr
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-18 08:15:57 +00:00
Michael Goulet
20c648c582 Normalize before checking if local is freeze in deduced_param_attrs 2023-08-17 14:33:24 -07:00
Camille GILLOT
933b618360 Revert "Implement references VarDebugInfo."
This reverts commit 2ec0071913.
2023-08-17 17:02:04 +00:00
Camille GILLOT
5b2524eb03 Do not pre-compute reachable blocks. 2023-08-16 19:40:46 +00:00
Camille GILLOT
94c5ea350f Update doc comment. 2023-08-16 18:15:49 +00:00
Camille GILLOT
b8fed2f21c Make dataflow const-prop handle_switch_int monotonic. 2023-08-16 18:12:18 +00:00
Camille GILLOT
388f6a6413 Make TerminatorEdge plural. 2023-08-16 18:12:18 +00:00
Camille GILLOT
6cf15d4cb5 Rename MaybeUnreachable. 2023-08-16 18:12:18 +00:00
Camille GILLOT
f19cd3f2e1 Use TerminatorEdge for dataflow-const-prop. 2023-08-16 18:12:18 +00:00
Camille GILLOT
3acfa092db Only run MaybeInitializedPlaces once for drop elaboration. 2023-08-16 18:12:18 +00:00
Zalathar
5ca30c4646 Store BCB counters externally, not directly in the BCB graph
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-13 12:18:06 +10:00
Zalathar
5302c9d451 Accumulate intermediate expressions into CoverageCounters
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-13 12:18:06 +10:00
Zalathar
c74db79c3b Rename helper struct BcbCounters to MakeBcbCounters
This avoids confusion with data structures that actually hold BCB counter
information.
2023-08-13 12:18:06 +10: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
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
cedihegi
0166092f87 Added comment on reason for method being public 2023-08-08 17:36:30 +02:00
cedihegi
15d408c6b0 Allow reimplementation of drops_elaborated query
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-08 16:30:43 +02:00