From 206bfc47ea8d159b52de8cc09f40452b064ab2f8 Mon Sep 17 00:00:00 2001 From: ouz-a Date: Tue, 1 Aug 2023 12:57:13 +0300 Subject: [PATCH 1/2] Cover statements for stable_mir --- compiler/rustc_smir/src/rustc_smir/mod.rs | 190 ++++++++++++++++-- .../rustc_smir/src/stable_mir/mir/body.rs | 91 ++++++++- 2 files changed, 267 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 365ef36824802..845b120e202ed 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -8,11 +8,13 @@ //! For now, we are developing everything inside `rustc`, thus, we keep this module private. use crate::rustc_internal::{self, opaque}; +use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection}; use crate::stable_mir::ty::{FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy}; use crate::stable_mir::{self, Context}; use rustc_hir as hir; -use rustc_middle::mir; -use rustc_middle::ty::{self, Ty, TyCtxt}; +use rustc_middle::mir::coverage::CodeRegion; +use rustc_middle::mir::{self}; +use rustc_middle::ty::{self, Ty, TyCtxt, Variance}; use rustc_span::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc_target::abi::FieldIdx; use tracing::debug; @@ -110,17 +112,43 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { Assign(assign) => { stable_mir::mir::Statement::Assign(assign.0.stable(tables), assign.1.stable(tables)) } - FakeRead(_) => todo!(), - SetDiscriminant { .. } => todo!(), - Deinit(_) => todo!(), - StorageLive(_) => todo!(), - StorageDead(_) => todo!(), - Retag(_, _) => todo!(), - PlaceMention(_) => todo!(), - AscribeUserType(_, _) => todo!(), - Coverage(_) => todo!(), - Intrinsic(_) => todo!(), - ConstEvalCounter => todo!(), + FakeRead(fake_read_place) => stable_mir::mir::Statement::FakeRead( + fake_read_place.0.stable(tables), + fake_read_place.1.stable(tables), + ), + SetDiscriminant { place: plc, variant_index: idx } => { + stable_mir::mir::Statement::SetDiscriminant { + place: plc.as_ref().stable(tables), + variant_index: idx.stable(tables), + } + } + Deinit(place) => stable_mir::mir::Statement::Deinit(place.stable(tables)), + StorageLive(place) => stable_mir::mir::Statement::StorageLive(place.stable(tables)), + StorageDead(place) => stable_mir::mir::Statement::StorageDead(place.stable(tables)), + Retag(retag, place) => { + stable_mir::mir::Statement::Retag(retag.stable(tables), place.stable(tables)) + } + PlaceMention(place) => stable_mir::mir::Statement::PlaceMention(place.stable(tables)), + AscribeUserType(place_projection, variance) => { + stable_mir::mir::Statement::AscribeUserType( + ( + place_projection.as_ref().0.stable(tables), + UserTypeProjection { + base: place_projection.as_ref().1.base.stable(tables), + projection: format!("{:?}", place_projection.as_ref().1.projs), + }, + ), + variance.stable(tables), + ) + } + Coverage(coverage) => stable_mir::mir::Statement::Coverage(stable_mir::mir::Coverage { + kind: coverage.kind.stable(tables), + code_region: coverage.code_region.as_ref().map(|reg| reg.stable(tables)), + }), + Intrinsic(intrinstic) => { + stable_mir::mir::Statement::Intrinsic(intrinstic.stable(tables)) + } + ConstEvalCounter => stable_mir::mir::Statement::ConstEvalCounter, Nop => stable_mir::mir::Statement::Nop, } } @@ -364,6 +392,24 @@ impl<'tcx> Stable<'tcx> for rustc_hir::Unsafety { } } +impl<'tcx> Stable<'tcx> for mir::FakeReadCause { + type T = stable_mir::mir::FakeReadCause; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use mir::FakeReadCause::*; + match self { + ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard, + ForMatchedPlace(local_def_id) => stable_mir::mir::FakeReadCause::ForMatchedPlace( + local_def_id.map(|id| id.to_def_id().index.index()), + ), + ForGuardBinding => stable_mir::mir::FakeReadCause::ForGuardBinding, + ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet( + local_def_id.map(|id| id.to_def_id().index.index()), + ), + ForIndex => stable_mir::mir::FakeReadCause::ForIndex, + } + } +} + impl<'tcx> Stable<'tcx> for FieldIdx { type T = usize; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { @@ -393,6 +439,104 @@ impl<'tcx> Stable<'tcx> for mir::Place<'tcx> { } } +impl<'tcx> Stable<'tcx> for mir::coverage::CoverageKind { + type T = stable_mir::mir::CoverageKind; + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::coverage::CoverageKind; + match self { + CoverageKind::Counter { function_source_hash, id } => { + stable_mir::mir::CoverageKind::Counter { + function_source_hash: *function_source_hash as usize, + id: id.as_usize(), + } + } + CoverageKind::Expression { id, lhs, op, rhs } => { + stable_mir::mir::CoverageKind::Expression { + id: id.as_usize(), + lhs: lhs.as_usize(), + op: op.stable(tables), + rhs: rhs.as_usize(), + } + } + CoverageKind::Unreachable => stable_mir::mir::CoverageKind::Unreachable, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::coverage::Op { + type T = stable_mir::mir::Op; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::coverage::Op::*; + match self { + Subtract => stable_mir::mir::Op::Subtract, + Add => stable_mir::mir::Op::Add, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::Local { + type T = usize; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + self.as_usize() + } +} + +impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx { + type T = usize; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + self.as_usize() + } +} + +impl<'tcx> Stable<'tcx> for Variance { + type T = stable_mir::mir::Variance; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + Variance::Bivariant => stable_mir::mir::Variance::Bivariant, + Variance::Contravariant => stable_mir::mir::Variance::Contravariant, + Variance::Covariant => stable_mir::mir::Variance::Covariant, + Variance::Invariant => stable_mir::mir::Variance::Invariant, + } + } +} + +impl<'tcx> Stable<'tcx> for mir::RetagKind { + type T = stable_mir::mir::RetagKind; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::RetagKind; + match self { + RetagKind::FnEntry => stable_mir::mir::RetagKind::FnEntry, + RetagKind::TwoPhase => stable_mir::mir::RetagKind::TwoPhase, + RetagKind::Raw => stable_mir::mir::RetagKind::Raw, + RetagKind::Default => stable_mir::mir::RetagKind::Default, + } + } +} + +impl<'tcx> Stable<'tcx> for rustc_middle::ty::UserTypeAnnotationIndex { + type T = usize; + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + self.as_usize() + } +} + +impl<'tcx> Stable<'tcx> for CodeRegion { + type T = stable_mir::mir::CodeRegion; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + match self { + _ => stable_mir::mir::CodeRegion { + file_name: self.file_name.as_u32() as usize, + start_line: self.start_line as usize, + start_col: self.start_col as usize, + end_line: self.end_line as usize, + end_col: self.end_col as usize, + }, + } + } +} + impl<'tcx> Stable<'tcx> for mir::UnwindAction { type T = stable_mir::mir::UnwindAction; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { @@ -406,6 +550,26 @@ impl<'tcx> Stable<'tcx> for mir::UnwindAction { } } +impl<'tcx> Stable<'tcx> for mir::NonDivergingIntrinsic<'tcx> { + type T = stable_mir::mir::NonDivergingIntrinsic; + + fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { + use rustc_middle::mir::NonDivergingIntrinsic; + match self { + NonDivergingIntrinsic::Assume(op) => { + stable_mir::mir::NonDivergingIntrinsic::Assume(op.stable(tables)) + } + NonDivergingIntrinsic::CopyNonOverlapping(copy_non_overlapping) => { + stable_mir::mir::NonDivergingIntrinsic::CopyNonOverlapping(CopyNonOverlapping { + src: copy_non_overlapping.src.stable(tables), + dst: copy_non_overlapping.dst.stable(tables), + count: copy_non_overlapping.count.stable(tables), + }) + } + } + } +} + impl<'tcx> Stable<'tcx> for mir::AssertMessage<'tcx> { type T = stable_mir::mir::AssertMessage; fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T { diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index e08359067dfc3..90f46e5d95be2 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -133,9 +133,90 @@ pub enum AsyncGeneratorKind { Fn, } +// FIXME: We are using `usize` for now but we should be using DefIds and find what +// what those are refering to and then use appropirate ty_defs for them (i.e AdtDef) +/// The FakeReadCause describes the type of pattern why a FakeRead statement exists. +#[derive(Clone, Debug)] +pub enum FakeReadCause { + ForMatchGuard, + ForMatchedPlace(Option), + ForGuardBinding, + ForLet(Option), + ForIndex, +} + +/// Describes what kind of retag is to be performed +#[derive(Clone, Debug)] +pub enum RetagKind { + FnEntry, + TwoPhase, + Raw, + Default, +} + +#[derive(Clone, Debug)] +pub enum Variance { + Covariant, + Invariant, + Contravariant, + Bivariant, +} + +#[derive(Clone, Debug)] +pub enum Op { + Subtract, + Add, +} + +#[derive(Clone, Debug)] +pub enum CoverageKind { + Counter { function_source_hash: usize, id: usize }, + Expression { id: usize, lhs: usize, op: Op, rhs: usize }, + Unreachable, +} + +#[derive(Clone, Copy, Debug)] +pub struct CodeRegion { + pub file_name: usize, + pub start_line: usize, + pub start_col: usize, + pub end_line: usize, + pub end_col: usize, +} + +#[derive(Clone, Debug)] +pub struct Coverage { + pub kind: CoverageKind, + pub code_region: Option, +} + +#[derive(Clone, Debug)] +pub struct CopyNonOverlapping { + pub src: Operand, + pub dst: Operand, + pub count: Operand, +} + +#[derive(Clone, Debug)] +pub enum NonDivergingIntrinsic { + Assume(Operand), + CopyNonOverlapping(CopyNonOverlapping), +} + #[derive(Clone, Debug)] pub enum Statement { Assign(Place, Rvalue), + FakeRead(FakeReadCause, Place), + SetDiscriminant { place: Place, variant_index: VariantIdx }, + Deinit(Place), + StorageLive(Local), + StorageDead(Local), + Retag(RetagKind, Place), + PlaceMention(Place), + AscribeUserType((Place, UserTypeProjection), Variance), + Coverage(Coverage), + Intrinsic(NonDivergingIntrinsic), + ConstEvalCounter, Nop, } @@ -271,10 +352,18 @@ pub enum Operand { #[derive(Clone, Debug)] pub struct Place { - pub local: usize, + pub local: Local, + pub projection: String, +} + +#[derive(Clone, Debug)] +pub struct UserTypeProjection { + pub base: UserTypeAnnotationIndex, pub projection: String, } +type Local = usize; + type FieldIdx = usize; /// The source-order index of a variant in a type. From 2ff62fdfcc4635568da7f47a59e0c49793a0436d Mon Sep 17 00:00:00 2001 From: ouz-a Date: Tue, 1 Aug 2023 17:48:20 +0300 Subject: [PATCH 2/2] clean up, use opaque types --- compiler/rustc_smir/src/rustc_smir/mod.rs | 61 +++++++++---------- .../rustc_smir/src/stable_mir/mir/body.rs | 34 +++++++---- 2 files changed, 53 insertions(+), 42 deletions(-) diff --git a/compiler/rustc_smir/src/rustc_smir/mod.rs b/compiler/rustc_smir/src/rustc_smir/mod.rs index 845b120e202ed..c4bdec0ee28b1 100644 --- a/compiler/rustc_smir/src/rustc_smir/mod.rs +++ b/compiler/rustc_smir/src/rustc_smir/mod.rs @@ -8,7 +8,7 @@ //! For now, we are developing everything inside `rustc`, thus, we keep this module private. use crate::rustc_internal::{self, opaque}; -use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection}; +use crate::stable_mir::mir::{CopyNonOverlapping, UserTypeProjection, VariantIdx}; use crate::stable_mir::ty::{FloatTy, IntTy, Movability, RigidTy, TyKind, UintTy}; use crate::stable_mir::{self, Context}; use rustc_hir as hir; @@ -130,16 +130,11 @@ impl<'tcx> Stable<'tcx> for mir::Statement<'tcx> { } PlaceMention(place) => stable_mir::mir::Statement::PlaceMention(place.stable(tables)), AscribeUserType(place_projection, variance) => { - stable_mir::mir::Statement::AscribeUserType( - ( - place_projection.as_ref().0.stable(tables), - UserTypeProjection { - base: place_projection.as_ref().1.base.stable(tables), - projection: format!("{:?}", place_projection.as_ref().1.projs), - }, - ), - variance.stable(tables), - ) + stable_mir::mir::Statement::AscribeUserType { + place: place_projection.as_ref().0.stable(tables), + projections: place_projection.as_ref().1.stable(tables), + variance: variance.stable(tables), + } } Coverage(coverage) => stable_mir::mir::Statement::Coverage(stable_mir::mir::Coverage { kind: coverage.kind.stable(tables), @@ -398,13 +393,11 @@ impl<'tcx> Stable<'tcx> for mir::FakeReadCause { use mir::FakeReadCause::*; match self { ForMatchGuard => stable_mir::mir::FakeReadCause::ForMatchGuard, - ForMatchedPlace(local_def_id) => stable_mir::mir::FakeReadCause::ForMatchedPlace( - local_def_id.map(|id| id.to_def_id().index.index()), - ), + ForMatchedPlace(local_def_id) => { + stable_mir::mir::FakeReadCause::ForMatchedPlace(opaque(local_def_id)) + } ForGuardBinding => stable_mir::mir::FakeReadCause::ForGuardBinding, - ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet( - local_def_id.map(|id| id.to_def_id().index.index()), - ), + ForLet(local_def_id) => stable_mir::mir::FakeReadCause::ForLet(opaque(local_def_id)), ForIndex => stable_mir::mir::FakeReadCause::ForIndex, } } @@ -447,15 +440,15 @@ impl<'tcx> Stable<'tcx> for mir::coverage::CoverageKind { CoverageKind::Counter { function_source_hash, id } => { stable_mir::mir::CoverageKind::Counter { function_source_hash: *function_source_hash as usize, - id: id.as_usize(), + id: opaque(id), } } CoverageKind::Expression { id, lhs, op, rhs } => { stable_mir::mir::CoverageKind::Expression { - id: id.as_usize(), - lhs: lhs.as_usize(), + id: opaque(id), + lhs: opaque(lhs), op: op.stable(tables), - rhs: rhs.as_usize(), + rhs: opaque(rhs), } } CoverageKind::Unreachable => stable_mir::mir::CoverageKind::Unreachable, @@ -463,6 +456,14 @@ impl<'tcx> Stable<'tcx> for mir::coverage::CoverageKind { } } +impl<'tcx> Stable<'tcx> for mir::UserTypeProjection { + type T = stable_mir::mir::UserTypeProjection; + + fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { + UserTypeProjection { base: self.base.as_usize(), projection: format!("{:?}", self.projs) } + } +} + impl<'tcx> Stable<'tcx> for mir::coverage::Op { type T = stable_mir::mir::Op; @@ -476,14 +477,14 @@ impl<'tcx> Stable<'tcx> for mir::coverage::Op { } impl<'tcx> Stable<'tcx> for mir::Local { - type T = usize; + type T = stable_mir::mir::Local; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { self.as_usize() } } impl<'tcx> Stable<'tcx> for rustc_target::abi::VariantIdx { - type T = usize; + type T = VariantIdx; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { self.as_usize() } @@ -525,14 +526,12 @@ impl<'tcx> Stable<'tcx> for CodeRegion { type T = stable_mir::mir::CodeRegion; fn stable(&self, _: &mut Tables<'tcx>) -> Self::T { - match self { - _ => stable_mir::mir::CodeRegion { - file_name: self.file_name.as_u32() as usize, - start_line: self.start_line as usize, - start_col: self.start_col as usize, - end_line: self.end_line as usize, - end_col: self.end_col as usize, - }, + stable_mir::mir::CodeRegion { + file_name: self.file_name.as_str().to_string(), + start_line: self.start_line as usize, + start_col: self.start_col as usize, + end_line: self.end_line as usize, + end_col: self.end_col as usize, } } } diff --git a/compiler/rustc_smir/src/stable_mir/mir/body.rs b/compiler/rustc_smir/src/stable_mir/mir/body.rs index 90f46e5d95be2..c16bd6cbd70e2 100644 --- a/compiler/rustc_smir/src/stable_mir/mir/body.rs +++ b/compiler/rustc_smir/src/stable_mir/mir/body.rs @@ -1,3 +1,4 @@ +use crate::rustc_internal::Opaque; use crate::stable_mir::ty::{ AdtDef, ClosureDef, Const, GeneratorDef, GenericArgs, Movability, Region, }; @@ -133,15 +134,18 @@ pub enum AsyncGeneratorKind { Fn, } -// FIXME: We are using `usize` for now but we should be using DefIds and find what -// what those are refering to and then use appropirate ty_defs for them (i.e AdtDef) +pub(crate) type LocalDefId = Opaque; +pub(crate) type CounterValueReference = Opaque; +pub(crate) type InjectedExpressionId = Opaque; +pub(crate) type ExpressionOperandId = Opaque; + /// The FakeReadCause describes the type of pattern why a FakeRead statement exists. #[derive(Clone, Debug)] pub enum FakeReadCause { ForMatchGuard, - ForMatchedPlace(Option), + ForMatchedPlace(LocalDefId), ForGuardBinding, - ForLet(Option), + ForLet(LocalDefId), ForIndex, } @@ -170,14 +174,22 @@ pub enum Op { #[derive(Clone, Debug)] pub enum CoverageKind { - Counter { function_source_hash: usize, id: usize }, - Expression { id: usize, lhs: usize, op: Op, rhs: usize }, + Counter { + function_source_hash: usize, + id: CounterValueReference, + }, + Expression { + id: InjectedExpressionId, + lhs: ExpressionOperandId, + op: Op, + rhs: ExpressionOperandId, + }, Unreachable, } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Debug)] pub struct CodeRegion { - pub file_name: usize, + pub file_name: String, pub start_line: usize, pub start_col: usize, pub end_line: usize, @@ -213,7 +225,7 @@ pub enum Statement { StorageDead(Local), Retag(RetagKind, Place), PlaceMention(Place), - AscribeUserType((Place, UserTypeProjection), Variance), + AscribeUserType { place: Place, projections: UserTypeProjection, variance: Variance }, Coverage(Coverage), Intrinsic(NonDivergingIntrinsic), ConstEvalCounter, @@ -362,12 +374,12 @@ pub struct UserTypeProjection { pub projection: String, } -type Local = usize; +pub type Local = usize; type FieldIdx = usize; /// The source-order index of a variant in a type. -type VariantIdx = usize; +pub type VariantIdx = usize; type UserTypeAnnotationIndex = usize;