about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJakob Degen <jakob.e.degen@gmail.com>2023-01-26 03:29:28 -0800
committerJakob Degen <jakob.e.degen@gmail.com>2023-01-26 03:29:28 -0800
commitd7f59e91e09037c3a0b6721f4f50081ee15e405a (patch)
treed5a998f61b85c64d8267ca5314b4cea0d210ca53
parente187f8871e3d553181c9d2d4ac111197a139ca0d (diff)
downloadrust-d7f59e91e09037c3a0b6721f4f50081ee15e405a.tar.gz
rust-d7f59e91e09037c3a0b6721f4f50081ee15e405a.zip
Custom mir: Add support for some remaining, easy to support constructs
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs14
-rw-r--r--library/core/src/intrinsics/mir.rs10
-rw-r--r--tests/mir-opt/building/custom/arrays.arrays.built.after.mir14
-rw-r--r--tests/mir-opt/building/custom/arrays.rs19
-rw-r--r--tests/mir-opt/building/custom/enums.rs1
-rw-r--r--tests/mir-opt/building/custom/enums.set_discr.built.after.mir5
-rw-r--r--tests/mir-opt/building/custom/operators.f.built.after.mir8
-rw-r--r--tests/mir-opt/building/custom/operators.rs3
8 files changed, 68 insertions, 6 deletions
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 9840b95feef..dbba529aef7 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -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),
         )
     }
diff --git a/library/core/src/intrinsics/mir.rs b/library/core/src/intrinsics/mir.rs
index e3157b66902..3d7ccffa173 100644
--- a/library/core/src/intrinsics/mir.rs
+++ b/library/core/src/intrinsics/mir.rs
@@ -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);
diff --git a/tests/mir-opt/building/custom/arrays.arrays.built.after.mir b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
new file mode 100644
index 00000000000..4c921272885
--- /dev/null
+++ b/tests/mir-opt/building/custom/arrays.arrays.built.after.mir
@@ -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
+    }
+}
diff --git a/tests/mir-opt/building/custom/arrays.rs b/tests/mir-opt/building/custom/arrays.rs
new file mode 100644
index 00000000000..8e0a1fd7a43
--- /dev/null
+++ b/tests/mir-opt/building/custom/arrays.rs
@@ -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);
+}
diff --git a/tests/mir-opt/building/custom/enums.rs b/tests/mir-opt/building/custom/enums.rs
index e5cd4563778..eca5b792ec0 100644
--- a/tests/mir-opt/building/custom/enums.rs
+++ b/tests/mir-opt/building/custom/enums.rs
@@ -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()
     })
diff --git a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir
index 7de9ed0983f..6d07473658a 100644
--- a/tests/mir-opt/building/custom/enums.set_discr.built.after.mir
+++ b/tests/mir-opt/building/custom/enums.set_discr.built.after.mir
@@ -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
     }
 }
diff --git a/tests/mir-opt/building/custom/operators.f.built.after.mir b/tests/mir-opt/building/custom/operators.f.built.after.mir
index a0c5f1b40db..cb43d5e6ed7 100644
--- a/tests/mir-opt/building/custom/operators.f.built.after.mir
+++ b/tests/mir-opt/building/custom/operators.f.built.after.mir
@@ -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
     }
 }
diff --git a/tests/mir-opt/building/custom/operators.rs b/tests/mir-opt/building/custom/operators.rs
index 51f80c66392..db7a48317d9 100644
--- a/tests/mir-opt/building/custom/operators.rs
+++ b/tests/mir-opt/building/custom/operators.rs
@@ -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()
     })