From 7dd59fceef202e6849f575dd057bb90351362eba Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Thu, 20 Apr 2023 12:37:32 -0300 Subject: [PATCH 1/3] Add Drop terminator to SMIR --- compiler/rustc_smir/src/rustc_smir/mod.rs | 6 +++++- compiler/rustc_smir/src/stable_mir/mir/body.rs | 2 +- tests/ui-fulldeps/stable-mir/crate-info.rs | 13 ++++++++++++- 3 files changed, 18 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 09cb6fd22d5e6..57ceb89969dd4 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -162,7 +162,11 @@ fn rustc_terminator_to_terminator( Terminate => Terminator::Abort, Return => Terminator::Return, Unreachable => Terminator::Unreachable, - Drop { .. } => todo!(), + Drop { place, target, unwind } => Terminator::Drop { + place: rustc_place_to_place(place), + target: target.as_usize(), + unwind: rustc_unwind_to_unwind(unwind), + }, Call { func, args, destination, target, unwind, from_hir_call: _, fn_span: _ } => { Terminator::Call { func: rustc_op_to_op(func), diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index bd5e6b68a12fa..b3d0a83573357 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -26,7 +26,7 @@ pub enum Terminator { Drop { place: Place, target: usize, - unwind: Option, + unwind: UnwindAction, }, Call { func: Operand, diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index 95f27efa7715c..f89690e1d1592 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -60,6 +60,15 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { stable_mir::mir::Terminator::Call { .. } => {} other => panic!("{other:?}"), } + + let drop = get_item(tcx, &items, (DefKind::Fn, "drop")).unwrap(); + let body = drop.body(); + assert_eq!(body.blocks.len(), 2); + let block = &body.blocks[0]; + match &block.terminator { + stable_mir::mir::Terminator::Drop { .. } => {} + other => panic!("{other:?}"), + } } // Use internal API to find a function in a crate. @@ -131,7 +140,9 @@ fn generate_input(path: &str) -> std::io::Result<()> { let x_64 = foo::bar(x); let y_64 = foo::bar(y); x_64.wrapping_add(y_64) - }}"# + }} + + pub fn drop(_: String) {{}}"# )?; Ok(()) } From 4b85bea4aeb920ebd2f70eb676ca64d3c7361bac Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 24 Apr 2023 17:53:51 -0300 Subject: [PATCH 2/3] Add Assert terminator to SMIR --- Cargo.lock | 1 + compiler/rustc_smir/Cargo.toml | 1 + compiler/rustc_smir/src/rustc_smir/mod.rs | 118 ++++++++++++++++-- .../rustc_smir/src/stable_mir/mir/body.rs | 67 +++++++++- tests/ui-fulldeps/stable-mir/crate-info.rs | 15 ++- 5 files changed, 191 insertions(+), 11 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7806b5daa63a..c7a91ef71166d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4090,6 +4090,7 @@ dependencies = [ name = "rustc_smir" version = "0.0.0" dependencies = [ + "rustc_hir", "rustc_middle", "rustc_span", "tracing", diff --git a/compiler/rustc_smir/Cargo.toml b/compiler/rustc_smir/Cargo.toml index fb97ee5bebe6e..80360a3c73f8d 100644 --- a/compiler/rustc_smir/Cargo.toml +++ b/compiler/rustc_smir/Cargo.toml @@ -4,6 +4,7 @@ version = "0.0.0" edition = "2021" [dependencies] +rustc_hir = { path = "../rustc_hir" } rustc_middle = { path = "../rustc_middle", optional = true } rustc_span = { path = "../rustc_span", optional = true } tracing = "0.1" diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 57ceb89969dd4..efbb3b321d5a7 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -93,10 +93,10 @@ fn rustc_statement_to_statement( } } -fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Operand { +fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir::mir::Rvalue { use rustc_middle::mir::Rvalue::*; match rvalue { - Use(op) => rustc_op_to_op(op), + Use(op) => stable_mir::mir::Rvalue::Use(rustc_op_to_op(op)), Repeat(_, _) => todo!(), Ref(_, _, _) => todo!(), ThreadLocalRef(_) => todo!(), @@ -104,9 +104,15 @@ fn rustc_rvalue_to_rvalue(rvalue: &rustc_middle::mir::Rvalue<'_>) -> stable_mir: Len(_) => todo!(), Cast(_, _, _) => todo!(), BinaryOp(_, _) => todo!(), - CheckedBinaryOp(_, _) => todo!(), + CheckedBinaryOp(bin_op, ops) => stable_mir::mir::Rvalue::CheckedBinaryOp( + rustc_bin_op_to_bin_op(bin_op), + rustc_op_to_op(&ops.0), + rustc_op_to_op(&ops.1), + ), NullaryOp(_, _) => todo!(), - UnaryOp(_, _) => todo!(), + UnaryOp(un_op, op) => { + stable_mir::mir::Rvalue::UnaryOp(rustc_un_op_to_un_op(un_op), rustc_op_to_op(op)) + } Discriminant(_) => todo!(), Aggregate(_, _) => todo!(), ShallowInitBox(_, _) => todo!(), @@ -124,8 +130,10 @@ fn rustc_op_to_op(op: &rustc_middle::mir::Operand<'_>) -> stable_mir::mir::Opera } fn rustc_place_to_place(place: &rustc_middle::mir::Place<'_>) -> stable_mir::mir::Place { - assert_eq!(&place.projection[..], &[]); - stable_mir::mir::Place { local: place.local.as_usize() } + stable_mir::mir::Place { + local: place.local.as_usize(), + projection: format!("{:?}", place.projection), + } } fn rustc_unwind_to_unwind( @@ -140,6 +148,96 @@ fn rustc_unwind_to_unwind( } } +fn rustc_assert_msg_to_msg<'tcx>( + assert_message: &rustc_middle::mir::AssertMessage<'tcx>, +) -> stable_mir::mir::AssertMessage { + use rustc_middle::mir::AssertKind; + match assert_message { + AssertKind::BoundsCheck { len, index } => stable_mir::mir::AssertMessage::BoundsCheck { + len: rustc_op_to_op(len), + index: rustc_op_to_op(index), + }, + AssertKind::Overflow(bin_op, op1, op2) => stable_mir::mir::AssertMessage::Overflow( + rustc_bin_op_to_bin_op(bin_op), + rustc_op_to_op(op1), + rustc_op_to_op(op2), + ), + AssertKind::OverflowNeg(op) => { + stable_mir::mir::AssertMessage::OverflowNeg(rustc_op_to_op(op)) + } + AssertKind::DivisionByZero(op) => { + stable_mir::mir::AssertMessage::DivisionByZero(rustc_op_to_op(op)) + } + AssertKind::RemainderByZero(op) => { + stable_mir::mir::AssertMessage::RemainderByZero(rustc_op_to_op(op)) + } + AssertKind::ResumedAfterReturn(generator) => { + stable_mir::mir::AssertMessage::ResumedAfterReturn(rustc_generator_to_generator( + generator, + )) + } + AssertKind::ResumedAfterPanic(generator) => { + stable_mir::mir::AssertMessage::ResumedAfterPanic(rustc_generator_to_generator( + generator, + )) + } + AssertKind::MisalignedPointerDereference { required, found } => { + stable_mir::mir::AssertMessage::MisalignedPointerDereference { + required: rustc_op_to_op(required), + found: rustc_op_to_op(found), + } + } + } +} + +fn rustc_bin_op_to_bin_op(bin_op: &rustc_middle::mir::BinOp) -> stable_mir::mir::BinOp { + use rustc_middle::mir::BinOp; + match bin_op { + BinOp::Add => stable_mir::mir::BinOp::Add, + BinOp::Sub => stable_mir::mir::BinOp::Sub, + BinOp::Mul => stable_mir::mir::BinOp::Mul, + BinOp::Div => stable_mir::mir::BinOp::Div, + BinOp::Rem => stable_mir::mir::BinOp::Rem, + BinOp::BitXor => stable_mir::mir::BinOp::BitXor, + BinOp::BitAnd => stable_mir::mir::BinOp::BitAnd, + BinOp::BitOr => stable_mir::mir::BinOp::BitOr, + BinOp::Shl => stable_mir::mir::BinOp::Shl, + BinOp::Shr => stable_mir::mir::BinOp::Shr, + BinOp::Eq => stable_mir::mir::BinOp::Eq, + BinOp::Lt => stable_mir::mir::BinOp::Lt, + BinOp::Le => stable_mir::mir::BinOp::Le, + BinOp::Ne => stable_mir::mir::BinOp::Ne, + BinOp::Ge => stable_mir::mir::BinOp::Ge, + BinOp::Gt => stable_mir::mir::BinOp::Gt, + BinOp::Offset => stable_mir::mir::BinOp::Offset, + } +} + +fn rustc_un_op_to_un_op(unary_op: &rustc_middle::mir::UnOp) -> stable_mir::mir::UnOp { + use rustc_middle::mir::UnOp; + match unary_op { + UnOp::Not => stable_mir::mir::UnOp::Not, + UnOp::Neg => stable_mir::mir::UnOp::Neg, + } +} + +fn rustc_generator_to_generator( + generator: &rustc_hir::GeneratorKind, +) -> stable_mir::mir::GeneratorKind { + use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; + match generator { + GeneratorKind::Async(async_gen) => { + let async_gen = match async_gen { + AsyncGeneratorKind::Block => stable_mir::mir::AsyncGeneratorKind::Block, + AsyncGeneratorKind::Closure => stable_mir::mir::AsyncGeneratorKind::Closure, + AsyncGeneratorKind::Fn => stable_mir::mir::AsyncGeneratorKind::Fn, + }; + stable_mir::mir::GeneratorKind::Async(async_gen) + } + GeneratorKind::Gen => stable_mir::mir::GeneratorKind::Gen, + } +} + fn rustc_terminator_to_terminator( terminator: &rustc_middle::mir::Terminator<'_>, ) -> stable_mir::mir::Terminator { @@ -176,7 +274,13 @@ fn rustc_terminator_to_terminator( unwind: rustc_unwind_to_unwind(unwind), } } - Assert { .. } => todo!(), + Assert { cond, expected, msg, target, unwind } => Terminator::Assert { + cond: rustc_op_to_op(cond), + expected: *expected, + msg: rustc_assert_msg_to_msg(msg), + target: target.as_usize(), + unwind: rustc_unwind_to_unwind(unwind), + }, Yield { .. } => todo!(), GeneratorDrop => todo!(), FalseEdge { .. } => todo!(), diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index b3d0a83573357..699c945738103 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -38,9 +38,9 @@ pub enum Terminator { Assert { cond: Operand, expected: bool, - msg: String, + msg: AssertMessage, target: usize, - cleanup: Option, + unwind: UnwindAction, }, } @@ -52,12 +52,72 @@ pub enum UnwindAction { Cleanup(usize), } +#[derive(Clone, Debug)] +pub enum AssertMessage { + BoundsCheck { len: Operand, index: Operand }, + Overflow(BinOp, Operand, Operand), + OverflowNeg(Operand), + DivisionByZero(Operand), + RemainderByZero(Operand), + ResumedAfterReturn(GeneratorKind), + ResumedAfterPanic(GeneratorKind), + MisalignedPointerDereference { required: Operand, found: Operand }, +} + +#[derive(Clone, Debug)] +pub enum BinOp { + Add, + Sub, + Mul, + Div, + Rem, + BitXor, + BitAnd, + BitOr, + Shl, + Shr, + Eq, + Lt, + Le, + Ne, + Ge, + Gt, + Offset, +} + +#[derive(Clone, Debug)] +pub enum UnOp { + Not, + Neg, +} + +#[derive(Clone, Debug)] +pub enum GeneratorKind { + Async(AsyncGeneratorKind), + Gen, +} + +#[derive(Clone, Debug)] +pub enum AsyncGeneratorKind { + Block, + Closure, + Fn, +} + #[derive(Clone, Debug)] pub enum Statement { - Assign(Place, Operand), + Assign(Place, Rvalue), Nop, } +// FIXME this is incomplete +#[derive(Clone, Debug)] +pub enum Rvalue { + Use(Operand), + CheckedBinaryOp(BinOp, Operand, Operand), + UnaryOp(UnOp, Operand), +} + #[derive(Clone, Debug)] pub enum Operand { Copy(Place), @@ -68,6 +128,7 @@ pub enum Operand { #[derive(Clone, Debug)] pub struct Place { pub local: usize, + pub projection: String, } #[derive(Clone, Debug)] diff --git a/tests/ui-fulldeps/stable-mir/crate-info.rs b/tests/ui-fulldeps/stable-mir/crate-info.rs index f89690e1d1592..1454d6dde6c97 100644 --- a/tests/ui-fulldeps/stable-mir/crate-info.rs +++ b/tests/ui-fulldeps/stable-mir/crate-info.rs @@ -69,6 +69,15 @@ fn test_stable_mir(tcx: TyCtxt<'_>) { stable_mir::mir::Terminator::Drop { .. } => {} other => panic!("{other:?}"), } + + let assert = get_item(tcx, &items, (DefKind::Fn, "assert")).unwrap(); + let body = assert.body(); + assert_eq!(body.blocks.len(), 2); + let block = &body.blocks[0]; + match &block.terminator { + stable_mir::mir::Terminator::Assert { .. } => {} + other => panic!("{other:?}"), + } } // Use internal API to find a function in a crate. @@ -142,7 +151,11 @@ fn generate_input(path: &str) -> std::io::Result<()> { x_64.wrapping_add(y_64) }} - pub fn drop(_: String) {{}}"# + pub fn drop(_: String) {{}} + + pub fn assert(x: i32) -> i32 {{ + x + 1 + }}"# )?; Ok(()) } From 698acc645e08078edfe70ad8651c0874a7933052 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Mon, 24 Apr 2023 18:17:24 -0300 Subject: [PATCH 3/3] Add GeneratorDrop terminator to SMIR --- compiler/rustc_smir/src/rustc_smir/mod.rs | 2 +- compiler/rustc_smir/src/stable_mir/mir/body.rs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index efbb3b321d5a7..241cd182059ba 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -282,7 +282,7 @@ fn rustc_terminator_to_terminator( unwind: rustc_unwind_to_unwind(unwind), }, Yield { .. } => todo!(), - GeneratorDrop => todo!(), + GeneratorDrop => Terminator::GeneratorDrop, FalseEdge { .. } => todo!(), FalseUnwind { .. } => todo!(), InlineAsm { .. } => todo!(), diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 699c945738103..4baf3f1f75eac 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -42,6 +42,7 @@ pub enum Terminator { target: usize, unwind: UnwindAction, }, + GeneratorDrop, } #[derive(Clone, Debug)]