Commit Graph

45 Commits

Author SHA1 Message Date
bors 79611d90b6 Auto merge of #122551 - RayMuir:copy_fmt, r=saethlin
Added "copy" to Debug fmt for copy operands

In MIR's debug mode (--emit mir) the printing for Operands is slightly inconsistent.

The RValues - values on the right side of an Assign - are usually printed with their Operand when they are Places.

Example:
_2 = move _3

But for arguments, the operand is omitted.

_2 = _1

I propose a change be made, to display the place with the operand.

_2 = copy _1

Move and copy have different semantics, meaning this difference is important and helpful to the user. It also adds consistency to the pretty printing.

-- EDIT --

 Consider this example Rust program and its MIR output with the **updated pretty printer.**

This was generated with the arguments --emit mir --crate-type lib -Zmir-opt-level=0 (Otherwise, it's optimised away since it's a junk program).

```rust
fn main(foo: i32) {
    let v = 10;

    if v == 20 {
        foo;
    }
    else {
        v;
    }
}
```

```MIR
// WARNING: This output format is intended for human consumers only
// and is subject to change without notice. Knock yourself out.
fn main(_1: i32) -> () {
    debug foo => _1;
    let mut _0: ();
    let _2: i32;
    let mut _3: bool;
    let mut _4: i32;
    let _5: i32;
    let _6: i32;
    scope 1 {
        debug v => _2;
    }

    bb0: {
        StorageLive(_2);
        _2 = const 10_i32;
        StorageLive(_3);
        StorageLive(_4);
        _4 = copy _2;
        _3 = Eq(move _4, const 20_i32);
        switchInt(move _3) -> [0: bb2, otherwise: bb1];
    }

    bb1: {
        StorageDead(_4);
        StorageLive(_5);
        _5 = copy _1;
        StorageDead(_5);
        _0 = const ();
        goto -> bb3;
    }

    bb2: {
        StorageDead(_4);
        StorageLive(_6);
        _6 = copy _2;
        StorageDead(_6);
        _0 = const ();
        goto -> bb3;
    }

    bb3: {
        StorageDead(_3);
        StorageDead(_2);
        return;
    }
}
```

In this example program, we can see that when we move a place, it is preceded by "move". e.g. ``` _3 = Eq(move _4, const 20_i32);```. However, when we copy a place such as ```_5 = _1;```, it is not preceded by the operand in the original printout. I propose to change the print to include the copy ```_5 = copy _1``` as in this example.

Regarding the arguments part. When I originally submitted this PR, I was under the impression this only affected the print for arguments to a function, but actually, it affects anything that uses a copy. This is preferable anyway with regard to consistency. The PR is about making ```copy``` explicit.
2024-08-19 23:10:46 +00:00
Scott McMurray 99cb0c6bc3 Bless *all* the mir-opt tests 2024-08-18 16:07:33 -07:00
Scott McMurray 249a36ffbd Update mir-opt filechecks 2024-08-18 15:52:23 -07:00
Ralf Jung 79503dd742 stabilize raw_ref_op 2024-08-18 19:46:53 +02:00
Nicholas Nethercote c9c80d2c5f rustfmt `tests/mir-opt`.
The only non-obvious changes:
- `building/storage_live_dead_in_statics.rs` has a `#[rustfmt::skip]`
  attribute to avoid reformating a table of data.
- Two `.mir` files have slight changes involving line numbers.
- In `unusual_item_types.rs` an `EMIT_MIR` annotation is moved to
  outside a function, which is the usual spot, because `tidy` complains
  if such a comment is indented.

The commit also tweaks the comments in `rustfmt.toml`.
2024-06-03 14:17:16 +10:00
Nicholas Nethercote ac24299636 Reformat `mir!` macro invocations to use braces.
The `mir!` macro has multiple parts:
- An optional return type annotation.
- A sequence of zero or more local declarations.
- A mandatory starting anonymous basic block, which is brace-delimited.
- A sequence of zero of more additional named basic blocks.

Some `mir!` invocations use braces with a "block" style, like so:
```
mir! {
    let _unit: ();
    {
	let non_copy = S(42);
	let ptr = std::ptr::addr_of_mut!(non_copy);
	// Inside `callee`, the first argument and `*ptr` are basically
	// aliasing places!
	Call(_unit = callee(Move(*ptr), ptr), ReturnTo(after_call), UnwindContinue())
    }
    after_call = {
	Return()
    }
}
```
Some invocations use parens with a "block" style, like so:
```
mir!(
    let x: [i32; 2];
    let one: i32;
    {
	x = [42, 43];
	one = 1;
	x = [one, 2];
	RET = Move(x);
	Return()
    }
)
```
And some invocations uses parens with a "tighter" style, like so:
```
mir!({
    SetDiscriminant(*b, 0);
    Return()
})
```
This last style is generally used for cases where just the mandatory
starting basic block is present. Its braces are placed next to the
parens.

This commit changes all `mir!` invocations to use braces with a "block"
style. Why?

- Consistency is good.

- The contents of the invocation is a block of code, so it's odd to use
  parens. They are more normally used for function-like macros.

- Most importantly, the next commit will enable rustfmt for
  `tests/mir-opt/`. rustfmt is more aggressive about formatting macros
  that use parens than macros that use braces. Without this commit's
  changes, rustfmt would break a couple of `mir!` macro invocations that
  use braces within `tests/mir-opt` by inserting an extraneous comma.
  E.g.:
  ```
  mir!(type RET = (i32, bool);, { // extraneous comma after ';'
      RET.0 = 1;
      RET.1 = true;
      Return()
  })
  ```
  Switching those `mir!` invocations to use braces avoids that problem,
  resulting in this, which is nicer to read as well as being valid
  syntax:
  ```
  mir! {
      type RET = (i32, bool);
      {
	  RET.0 = 1;
	  RET.1 = true;
	  Return()
      }
  }
  ```
2024-06-03 13:24:44 +10:00
bors d2d24e395a Auto merge of #123602 - cjgillot:gvn-borrowed, r=oli-obk
Account for immutably borrowed locals in MIR copy-prop and GVN

For the most part, we consider that immutably borrowed `Freeze` locals still fulfill SSA conditions. As the borrow is immutable, any use of the local will have the value given by the single assignment, and there can be no surprise.

This allows copy-prop to merge a non-borrowed local with a borrowed local. We chose to keep copy-classes heads unborrowed, as those may be easier to optimize in later passes.

This also allows to GVN the value behind an immutable borrow. If a SSA local is borrowed, dereferencing that borrow is equivalent to copying the local's value: re-executing the assignment between the borrow and the dereference would be UB.

r? `@ghost` for perf
2024-05-03 21:50:13 +00:00
Camille GILLOT 73db28757b Use newly exposed Freeze trait. 2024-04-20 19:25:20 +00:00
Camille GILLOT 73db12a223 Merge borrowed locals too. 2024-04-20 19:20:38 +00:00
Camille GILLOT 5d144e301c Add tests. 2024-04-20 19:10:23 +00:00
Ralf Jung 75d0fdd967 mir-opt tests: rename unit-test -> test-mir-pass 2024-04-20 13:19:34 +02:00
Matthew Jasper a277c901d9 Remove MIR unsafe check
This also remove safety information from MIR.
2024-04-03 08:50:12 +00:00
许杰友 Jieyou Xu (Joe) 6e48b96692
[AUTO_GENERATED] Migrate compiletest to use `ui_test`-style `//@` directives 2024-02-22 16:04:04 +00:00
Nadrieril faaf81bbbc Start blocks eagerly 2024-02-12 17:37:05 +01:00
Tomasz Miąsko a084e063e6 Fix validation and linting of injected MIR
Reevaluate `body.should_skip()` after updating the MIR phase to ensure
that injected MIR is processed correctly.

Update a few custom MIR tests that were ill-formed for the injected
phase.
2024-01-04 23:06:42 +01:00
Ralf Jung 0f9baa8a31 custom mir: make it clear what the return block is 2023-12-26 20:15:26 +01:00
Tomasz Miąsko 78da577650 Custom MIR: Support cleanup blocks
Cleanup blocks are declared with `bb (cleanup) = { ... }`.

`Call` and `Drop` terminators take an additional argument describing the
unwind action, which is one of the following:

* `UnwindContinue()`
* `UnwindUnreachable()`
* `UnwindTerminate(reason)`, where reason is `ReasonAbi` or `ReasonInCleanup`
* `UnwindCleanup(block)`

Also support unwind resume and unwind terminate terminators:

* `UnwindResume()`
* `UnwindTerminate(reason)`
2023-11-14 08:23:58 +01:00
Camille GILLOT 4ff03cd1a4 Allow to run filecheck in mir-opt tests. 2023-10-19 15:51:52 +00:00
Camille GILLOT 37f080edbc Also consider call and yield as MIR SSA. 2023-10-08 16:05:26 +00:00
Ralf Jung 7a6346660e custom_mir: change Call() terminator syntax to something more readable 2023-08-19 22:41:33 +02:00
Camille GILLOT 4de2d8fb66 Perform reference propagation earlier. 2023-07-10 16:01:18 +00:00
Nilstrieb 2beabbbf6f Rename `adjustment::PointerCast` and variants using it to `PointerCoercion`
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-07 18:17:16 +02:00
Gary Guo 19ce326a08 Bless tests 2023-06-23 18:36:25 +01:00
Ben Kimock 0a1fa411ed Remove comments from mir-opt MIR dumps 2023-06-15 15:19:11 -04:00
Pietro Albini 4668123945
bless mir-opt
To reproduce the changes in this commit locally:

- Run `./x test tidy` and remove all the output files not associated
  with a test file anymore, as reported by tidy.
- Run `./x test tests/mir-opt --bless` to generate the new outputs.
2023-06-12 09:34:17 +02:00
Pietro Albini 070cc836e9
properly mark tests that require panic=abort 2023-06-12 09:34:15 +02:00
Camille GILLOT f40f235879 Merge return place with other locals in CopyProp. 2023-05-14 12:06:34 +00:00
Camille GILLOT 6ad0497cc0 Use visit_assign to detect SSA locals. 2023-05-10 15:26:51 +00:00
Camille GILLOT 3c43b61b87 Do not consider borrowed Freeze locals as SSA. 2023-05-09 17:59:35 +00:00
Gary Guo 04126398c2 Ignore many tests on wasm32 2023-04-06 10:08:07 +01:00
Camille GILLOT 209eb8ae83 Do not grow `assignment_order` needlessly. 2023-02-27 20:02:18 +00:00
Camille GILLOT 2a32a2b64f Special case deref projections in SsaVisitor. 2023-02-27 20:02:18 +00:00
bors 639377ed73 Auto merge of #107449 - saethlin:enable-copyprop, r=oli-obk
Enable CopyProp

r? `@tmiasko`

`@rustbot` label +A-mir-opt
2023-02-16 03:44:37 +00:00
Ben Kimock 614df3fd5e Clearly document intentional UB in mir-opt tests
Co-authored-by: Jakob Degen <jakob.e.degen@gmail.com>
2023-02-13 13:50:50 -05:00
Ben Kimock d8d18aae03 Fix UB in the test case 2023-02-12 14:42:16 -05:00
Ben Kimock 640ede7b0a Enable CopyProp by default, tune the impl a bit 2023-02-12 13:23:53 -05:00
Camille GILLOT 5c1cb5bbc6 Turn projections into copies in CopyProp. 2023-02-04 23:33:33 +00:00
Camille GILLOT 10ec94930b Bless tests. 2023-02-02 23:26:26 +00:00
Camille GILLOT e8ac0404bd Remove assignment. 2023-01-31 18:07:57 +00:00
Camille GILLOT 3c10cf088a Remove both StorageLive and StorageDead in CopyProp. 2023-01-31 17:50:04 +00:00
Camille GILLOT 05ee406cc8 Add test. 2023-01-31 17:49:57 +00:00
Camille GILLOT d29dc057ba Do not merge locals that have their address taken. 2023-01-27 18:22:45 +00:00
Camille GILLOT 8f1dbe54ea Discard raw pointers from SSA locals. 2023-01-27 18:22:45 +00:00
Camille GILLOT d45815eb4a Only consider a local to be SSA if assignment dominates all uses. 2023-01-27 18:22:45 +00:00
Camille GILLOT 38b55dc684 Add tests. 2023-01-27 18:22:45 +00:00