Rollup merge of #107322 - JakobDegen:custom-mir, r=tmiasko
Custom mir: Add support for some remaining, easy to support constructs Some documentation for previous changes and support for `Deinit`, checked binops, len, and array repetition r? ```@oli-obk``` or ```@tmiasko```
This commit is contained in:
commit
c87996a8ad
@ -18,6 +18,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
@call("mir_storage_dead", args) => {
|
||||
Ok(StatementKind::StorageDead(self.parse_local(args[0])?))
|
||||
},
|
||||
@call("mir_deinit", args) => {
|
||||
Ok(StatementKind::Deinit(Box::new(self.parse_place(args[0])?)))
|
||||
},
|
||||
@call("mir_retag", args) => {
|
||||
Ok(StatementKind::Retag(RetagKind::Default, Box::new(self.parse_place(args[0])?)))
|
||||
},
|
||||
@ -141,6 +144,14 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
fn parse_rvalue(&self, expr_id: ExprId) -> PResult<Rvalue<'tcx>> {
|
||||
parse_by_kind!(self, expr_id, _, "rvalue",
|
||||
@call("mir_discriminant", args) => self.parse_place(args[0]).map(Rvalue::Discriminant),
|
||||
@call("mir_checked", args) => {
|
||||
parse_by_kind!(self, args[0], _, "binary op",
|
||||
ExprKind::Binary { op, lhs, rhs } => Ok(Rvalue::CheckedBinaryOp(
|
||||
*op, Box::new((self.parse_operand(*lhs)?, self.parse_operand(*rhs)?))
|
||||
)),
|
||||
)
|
||||
},
|
||||
@call("mir_len", args) => Ok(Rvalue::Len(self.parse_place(args[0])?)),
|
||||
ExprKind::Borrow { borrow_kind, arg } => Ok(
|
||||
Rvalue::Ref(self.tcx.lifetimes.re_erased, *borrow_kind, self.parse_place(*arg)?)
|
||||
),
|
||||
@ -153,6 +164,9 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
|
||||
ExprKind::Unary { op, arg } => Ok(
|
||||
Rvalue::UnaryOp(*op, self.parse_operand(*arg)?)
|
||||
),
|
||||
ExprKind::Repeat { value, count } => Ok(
|
||||
Rvalue::Repeat(self.parse_operand(*value)?, *count)
|
||||
),
|
||||
_ => self.parse_operand(expr_id).map(Rvalue::Use),
|
||||
)
|
||||
}
|
||||
|
@ -211,13 +211,16 @@
|
||||
//!
|
||||
//! #### Statements
|
||||
//! - Assign statements work via normal Rust assignment.
|
||||
//! - [`Retag`] statements have an associated function.
|
||||
//! - [`Retag`], [`StorageLive`], [`StorageDead`], [`Deinit`] statements have an associated function.
|
||||
//!
|
||||
//! #### Rvalues
|
||||
//!
|
||||
//! - Operands implicitly convert to `Use` rvalues.
|
||||
//! - `&`, `&mut`, `addr_of!`, and `addr_of_mut!` all work to create their associated rvalue.
|
||||
//! - [`Discriminant`] has an associated function.
|
||||
//! - [`Discriminant`] and [`Len`] have associated functions.
|
||||
//! - Unary and binary operations use their normal Rust syntax - `a * b`, `!c`, etc.
|
||||
//! - Checked binary operations are represented by wrapping the associated binop in [`Checked`].
|
||||
//! - Array repetition syntax (`[foo; 10]`) creates the associated rvalue.
|
||||
//!
|
||||
//! #### Terminators
|
||||
//!
|
||||
@ -261,6 +264,9 @@ define!("mir_drop_and_replace", fn DropAndReplace<T>(place: T, value: T, goto: B
|
||||
define!("mir_call", fn Call<T>(place: T, goto: BasicBlock, call: T));
|
||||
define!("mir_storage_live", fn StorageLive<T>(local: T));
|
||||
define!("mir_storage_dead", fn StorageDead<T>(local: T));
|
||||
define!("mir_deinit", fn Deinit<T>(place: T));
|
||||
define!("mir_checked", fn Checked<T>(binop: T) -> (T, bool));
|
||||
define!("mir_len", fn Len<T>(place: T) -> usize);
|
||||
define!("mir_retag", fn Retag<T>(place: T));
|
||||
define!("mir_move", fn Move<T>(place: T) -> T);
|
||||
define!("mir_static", fn Static<T>(s: T) -> &'static T);
|
||||
|
14
tests/mir-opt/building/custom/arrays.arrays.built.after.mir
Normal file
14
tests/mir-opt/building/custom/arrays.arrays.built.after.mir
Normal file
@ -0,0 +1,14 @@
|
||||
// MIR for `arrays` after built
|
||||
|
||||
fn arrays() -> usize {
|
||||
let mut _0: usize; // return place in scope 0 at $DIR/arrays.rs:+0:32: +0:37
|
||||
let mut _1: [i32; C]; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
let mut _2: usize; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
|
||||
bb0: {
|
||||
_1 = [const 5_i32; C]; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
_2 = Len(_1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
_0 = _2; // scope 0 at $DIR/arrays.rs:+4:9: +4:16
|
||||
return; // scope 0 at $DIR/arrays.rs:+5:9: +5:17
|
||||
}
|
||||
}
|
19
tests/mir-opt/building/custom/arrays.rs
Normal file
19
tests/mir-opt/building/custom/arrays.rs
Normal file
@ -0,0 +1,19 @@
|
||||
#![feature(custom_mir, core_intrinsics, inline_const)]
|
||||
|
||||
extern crate core;
|
||||
use core::intrinsics::mir::*;
|
||||
|
||||
// EMIT_MIR arrays.arrays.built.after.mir
|
||||
#[custom_mir(dialect = "built")]
|
||||
fn arrays<const C: usize>() -> usize {
|
||||
mir!({
|
||||
let x = [5_i32; C];
|
||||
let c = Len(x);
|
||||
RET = c;
|
||||
Return()
|
||||
})
|
||||
}
|
||||
|
||||
fn main() {
|
||||
assert_eq!(arrays::<20>(), 20);
|
||||
}
|
@ -86,6 +86,7 @@ fn switch_option_repr(option: Bool) -> bool {
|
||||
#[custom_mir(dialect = "runtime", phase = "initial")]
|
||||
fn set_discr(option: &mut Option<()>) {
|
||||
mir!({
|
||||
Deinit(*option);
|
||||
SetDiscriminant(*option, 0);
|
||||
Return()
|
||||
})
|
||||
|
@ -4,7 +4,8 @@ fn set_discr(_1: &mut Option<()>) -> () {
|
||||
let mut _0: (); // return place in scope 0 at $DIR/enums.rs:+0:39: +0:39
|
||||
|
||||
bb0: {
|
||||
discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+2:9: +2:36
|
||||
return; // scope 0 at $DIR/enums.rs:+3:9: +3:17
|
||||
Deinit((*_1)); // scope 0 at $DIR/enums.rs:+2:9: +2:24
|
||||
discriminant((*_1)) = 0; // scope 0 at $DIR/enums.rs:+3:9: +3:36
|
||||
return; // scope 0 at $DIR/enums.rs:+4:9: +4:17
|
||||
}
|
||||
}
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
fn f(_1: i32, _2: bool) -> i32 {
|
||||
let mut _0: i32; // return place in scope 0 at $DIR/operators.rs:+0:30: +0:33
|
||||
let mut _3: (i32, bool); // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
|
||||
bb0: {
|
||||
_1 = Neg(_1); // scope 0 at $DIR/operators.rs:+2:9: +2:15
|
||||
@ -20,7 +21,10 @@ fn f(_1: i32, _2: bool) -> i32 {
|
||||
_2 = Le(_1, _1); // scope 0 at $DIR/operators.rs:+15:9: +15:19
|
||||
_2 = Ge(_1, _1); // scope 0 at $DIR/operators.rs:+16:9: +16:19
|
||||
_2 = Gt(_1, _1); // scope 0 at $DIR/operators.rs:+17:9: +17:18
|
||||
_0 = _1; // scope 0 at $DIR/operators.rs:+18:9: +18:16
|
||||
return; // scope 0 at $DIR/operators.rs:+19:9: +19:17
|
||||
_3 = CheckedAdd(_1, _1); // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
|
||||
_2 = (_3.1: bool); // scope 0 at $DIR/operators.rs:+19:9: +19:18
|
||||
_1 = (_3.0: i32); // scope 0 at $DIR/operators.rs:+20:9: +20:18
|
||||
_0 = _1; // scope 0 at $DIR/operators.rs:+21:9: +21:16
|
||||
return; // scope 0 at $DIR/operators.rs:+22:9: +22:17
|
||||
}
|
||||
}
|
||||
|
@ -22,6 +22,9 @@ pub fn f(a: i32, b: bool) -> i32 {
|
||||
b = a <= a;
|
||||
b = a >= a;
|
||||
b = a > a;
|
||||
let res = Checked(a + a);
|
||||
b = res.1;
|
||||
a = res.0;
|
||||
RET = a;
|
||||
Return()
|
||||
})
|
||||
|
Loading…
x
Reference in New Issue
Block a user