emit basic smir
This commit is contained in:
parent
ee5ef3aac9
commit
ae179a04b6
@ -44,6 +44,7 @@ rustc_query_system = { path = "../rustc_query_system" }
|
|||||||
rustc_resolve = { path = "../rustc_resolve" }
|
rustc_resolve = { path = "../rustc_resolve" }
|
||||||
rustc_session = { path = "../rustc_session" }
|
rustc_session = { path = "../rustc_session" }
|
||||||
rustc_span = { path = "../rustc_span" }
|
rustc_span = { path = "../rustc_span" }
|
||||||
|
rustc_smir ={ path = "../rustc_smir" }
|
||||||
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
|
rustc_symbol_mangling = { path = "../rustc_symbol_mangling" }
|
||||||
rustc_target = { path = "../rustc_target" }
|
rustc_target = { path = "../rustc_target" }
|
||||||
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
rustc_trait_selection = { path = "../rustc_trait_selection" }
|
||||||
|
@ -9,6 +9,7 @@ use rustc_middle::mir::{write_mir_graphviz, write_mir_pretty};
|
|||||||
use rustc_middle::ty::{self, TyCtxt};
|
use rustc_middle::ty::{self, TyCtxt};
|
||||||
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
|
use rustc_session::config::{OutFileName, PpHirMode, PpMode, PpSourceMode};
|
||||||
use rustc_session::Session;
|
use rustc_session::Session;
|
||||||
|
use rustc_smir::rustc_internal::pretty::write_smir_pretty;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::FileName;
|
use rustc_span::FileName;
|
||||||
|
|
||||||
@ -325,6 +326,11 @@ pub fn print<'tcx>(sess: &Session, ppm: PpMode, ex: PrintExtra<'tcx>) {
|
|||||||
write_mir_graphviz(ex.tcx(), None, &mut out).unwrap();
|
write_mir_graphviz(ex.tcx(), None, &mut out).unwrap();
|
||||||
String::from_utf8(out).unwrap()
|
String::from_utf8(out).unwrap()
|
||||||
}
|
}
|
||||||
|
Smir => {
|
||||||
|
let mut out = Vec::new();
|
||||||
|
write_smir_pretty(ex.tcx(), &mut out).unwrap();
|
||||||
|
String::from_utf8(out).unwrap()
|
||||||
|
}
|
||||||
ThirTree => {
|
ThirTree => {
|
||||||
let tcx = ex.tcx();
|
let tcx = ex.tcx();
|
||||||
let mut out = String::new();
|
let mut out = String::new();
|
||||||
|
@ -2926,6 +2926,7 @@ fn parse_pretty(handler: &EarlyErrorHandler, unstable_opts: &UnstableOptions) ->
|
|||||||
"thir-tree" => ThirTree,
|
"thir-tree" => ThirTree,
|
||||||
"thir-flat" => ThirFlat,
|
"thir-flat" => ThirFlat,
|
||||||
"mir" => Mir,
|
"mir" => Mir,
|
||||||
|
"smir" => Smir,
|
||||||
"mir-cfg" => MirCFG,
|
"mir-cfg" => MirCFG,
|
||||||
name => handler.early_error(format!(
|
name => handler.early_error(format!(
|
||||||
"argument to `unpretty` must be one of `normal`, `identified`, \
|
"argument to `unpretty` must be one of `normal`, `identified`, \
|
||||||
@ -3106,6 +3107,8 @@ pub enum PpMode {
|
|||||||
Mir,
|
Mir,
|
||||||
/// `-Zunpretty=mir-cfg`
|
/// `-Zunpretty=mir-cfg`
|
||||||
MirCFG,
|
MirCFG,
|
||||||
|
/// `-Zunpretty=smir`
|
||||||
|
Smir,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PpMode {
|
impl PpMode {
|
||||||
@ -3122,7 +3125,8 @@ impl PpMode {
|
|||||||
| ThirTree
|
| ThirTree
|
||||||
| ThirFlat
|
| ThirFlat
|
||||||
| Mir
|
| Mir
|
||||||
| MirCFG => true,
|
| MirCFG
|
||||||
|
| Smir => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn needs_hir(&self) -> bool {
|
pub fn needs_hir(&self) -> bool {
|
||||||
@ -3130,13 +3134,13 @@ impl PpMode {
|
|||||||
match *self {
|
match *self {
|
||||||
Source(_) | AstTree | AstTreeExpanded => false,
|
Source(_) | AstTree | AstTreeExpanded => false,
|
||||||
|
|
||||||
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG => true,
|
Hir(_) | HirTree | ThirTree | ThirFlat | Mir | MirCFG | Smir => true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn needs_analysis(&self) -> bool {
|
pub fn needs_analysis(&self) -> bool {
|
||||||
use PpMode::*;
|
use PpMode::*;
|
||||||
matches!(*self, Hir(PpHirMode::Typed) | Mir | MirCFG | ThirTree | ThirFlat)
|
matches!(*self, Hir(PpHirMode::Typed) | Mir | Smir | MirCFG | ThirTree | ThirFlat)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ use std::hash::Hash;
|
|||||||
use std::ops::Index;
|
use std::ops::Index;
|
||||||
|
|
||||||
mod internal;
|
mod internal;
|
||||||
|
pub mod pretty;
|
||||||
|
|
||||||
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
|
pub fn stable<'tcx, S: Stable<'tcx>>(item: S) -> S::T {
|
||||||
with_tables(|tables| item.stable(tables))
|
with_tables(|tables| item.stable(tables))
|
||||||
@ -299,4 +300,10 @@ impl<K: PartialEq + Hash + Eq, V: Copy + Debug + PartialEq + IndexedVal> Index<V
|
|||||||
pub trait RustcInternal<'tcx> {
|
pub trait RustcInternal<'tcx> {
|
||||||
type T;
|
type T;
|
||||||
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
|
fn internal(&self, tables: &mut Tables<'tcx>) -> Self::T;
|
||||||
|
|
||||||
|
/// Use this when you want to convert to a rustc counterpart in user-code.
|
||||||
|
/// Do not use this within the smir crates themselves.
|
||||||
|
fn internal_via_tls(&self) -> Self::T {
|
||||||
|
with_tables(|tables| self.internal(tables))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
133
compiler/rustc_smir/src/rustc_internal/pretty.rs
Normal file
133
compiler/rustc_smir/src/rustc_internal/pretty.rs
Normal file
@ -0,0 +1,133 @@
|
|||||||
|
use std::io;
|
||||||
|
|
||||||
|
use rustc_middle::ty::TyCtxt;
|
||||||
|
use stable_mir::{
|
||||||
|
ty::{RigidTy, TyKind},
|
||||||
|
CrateItem, mir::Mutability,
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
use super::{run, RustcInternal};
|
||||||
|
|
||||||
|
pub fn write_smir_pretty<'tcx>(tcx: TyCtxt<'tcx>, w: &mut dyn io::Write) -> io::Result<()> {
|
||||||
|
run(tcx, || {
|
||||||
|
let items = stable_mir::all_local_items();
|
||||||
|
items.iter().for_each(|item| {
|
||||||
|
// Because we can't return a Result from a closure, we have to unwrap here.
|
||||||
|
writeln!(w, "{}", function_name(*item,tcx)).unwrap();
|
||||||
|
writeln!(w, "{}", function_body(*item,tcx)).unwrap();
|
||||||
|
})
|
||||||
|
});
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_name(item: CrateItem,tcx: TyCtxt<'_>) -> String {
|
||||||
|
let mut name = String::new();
|
||||||
|
let body = item.body();
|
||||||
|
name.push_str("fn ");
|
||||||
|
name.push_str(item.name().as_str());
|
||||||
|
if body.arg_locals().is_empty() {
|
||||||
|
name.push_str("()");
|
||||||
|
}else{
|
||||||
|
name.push_str("(");
|
||||||
|
}
|
||||||
|
body.arg_locals().iter().for_each(|local| {
|
||||||
|
name.push_str(format!("_{}: ",local.local).as_str());
|
||||||
|
name.push_str(&pretty_ty(local.ty.kind(), tcx));
|
||||||
|
});
|
||||||
|
if !body.arg_locals().is_empty() {
|
||||||
|
name.push_str(")");
|
||||||
|
}
|
||||||
|
let return_local = body.ret_local();
|
||||||
|
name.push_str(" -> ");
|
||||||
|
name.push_str(&pretty_ty(return_local.ty.kind(), tcx));
|
||||||
|
name.push_str(" {");
|
||||||
|
name
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn function_body(item: CrateItem,_tcx: TyCtxt<'_>) -> String {
|
||||||
|
let mut body_str = String::new();
|
||||||
|
let body = item.body();
|
||||||
|
body.inner_locals().iter().for_each(|local| {
|
||||||
|
body_str.push_str(" ");
|
||||||
|
body_str.push_str(format!("let {}",ret_mutability(&local.mutability)).as_str());
|
||||||
|
body_str.push_str(format!("_{}: ",local.local).as_str());
|
||||||
|
body_str.push_str(format!("{}",pretty_ty(local.ty.kind(), _tcx)).as_str());
|
||||||
|
body_str.push_str(";\n");
|
||||||
|
|
||||||
|
});
|
||||||
|
body_str.push_str("}");
|
||||||
|
body_str
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ret_mutability(mutability: &Mutability) -> String {
|
||||||
|
match mutability {
|
||||||
|
Mutability::Not => "".to_string(),
|
||||||
|
Mutability::Mut => "mut ".to_string(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn pretty_ty<'tcx>(ty: TyKind,tcx: TyCtxt<'tcx>) -> String {
|
||||||
|
let mut pretty = String::new();
|
||||||
|
pretty.push_str("");
|
||||||
|
match ty {
|
||||||
|
TyKind::RigidTy(rigid_ty) => match rigid_ty {
|
||||||
|
RigidTy::Bool => "bool".to_string(),
|
||||||
|
RigidTy::Char => "char".to_string(),
|
||||||
|
RigidTy::Int(i) => match i {
|
||||||
|
stable_mir::ty::IntTy::Isize => "isize".to_string(),
|
||||||
|
stable_mir::ty::IntTy::I8 => "i8".to_string(),
|
||||||
|
stable_mir::ty::IntTy::I16 => "i16".to_string(),
|
||||||
|
stable_mir::ty::IntTy::I32 => "i32".to_string(),
|
||||||
|
stable_mir::ty::IntTy::I64 => "i64".to_string(),
|
||||||
|
stable_mir::ty::IntTy::I128 => "i128".to_string(),
|
||||||
|
},
|
||||||
|
RigidTy::Uint(u) => match u {
|
||||||
|
stable_mir::ty::UintTy::Usize => "usize".to_string(),
|
||||||
|
stable_mir::ty::UintTy::U8 => "u8".to_string(),
|
||||||
|
stable_mir::ty::UintTy::U16 => "u16".to_string(),
|
||||||
|
stable_mir::ty::UintTy::U32 => "u32".to_string(),
|
||||||
|
stable_mir::ty::UintTy::U64 => "u64".to_string(),
|
||||||
|
stable_mir::ty::UintTy::U128 => "u128".to_string(),
|
||||||
|
},
|
||||||
|
RigidTy::Float(f) => match f {
|
||||||
|
stable_mir::ty::FloatTy::F32 => "f32".to_string(),
|
||||||
|
stable_mir::ty::FloatTy::F64 => "f64".to_string(),
|
||||||
|
},
|
||||||
|
RigidTy::Adt(def, _) => format!("{:#?}", tcx.type_of(def.0.internal_via_tls()).instantiate_identity()),
|
||||||
|
RigidTy::Foreign(_) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Str => "str".to_string(),
|
||||||
|
RigidTy::Array(_ty, len) => {
|
||||||
|
format!("[{};{:#?}]", 1,len.internal_via_tls())},
|
||||||
|
RigidTy::Slice(ty) => pretty_ty(ty.kind(),tcx),
|
||||||
|
RigidTy::RawPtr(_, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Ref(_, ty, _) => pretty_ty(ty.kind(),tcx),
|
||||||
|
RigidTy::FnDef(_, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::FnPtr(_) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Closure(_, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Coroutine(_, _, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Dynamic(_, _, _) => format!("{:#?}", rigid_ty),
|
||||||
|
RigidTy::Never => "!".to_string(),
|
||||||
|
RigidTy::Tuple(tuple) => {
|
||||||
|
if tuple.is_empty(){
|
||||||
|
"()".to_string()
|
||||||
|
}else {
|
||||||
|
let mut tuple_str = String::new();
|
||||||
|
tuple_str.push_str("(");
|
||||||
|
tuple.iter().enumerate().for_each(|(i,ty)| {
|
||||||
|
tuple_str.push_str(&pretty_ty(ty.kind(),tcx));
|
||||||
|
if i != tuple.len() - 1 {
|
||||||
|
tuple_str.push_str(", ");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
tuple_str.push_str(")");
|
||||||
|
tuple_str
|
||||||
|
}
|
||||||
|
},
|
||||||
|
},
|
||||||
|
TyKind::Alias(_, _) => format!("{:#?}", ty),
|
||||||
|
TyKind::Param(_) => format!("{:#?}", ty),
|
||||||
|
TyKind::Bound(_, _) => format!("{:#?}", ty),
|
||||||
|
}
|
||||||
|
}
|
@ -400,10 +400,12 @@ impl<'tcx> Stable<'tcx> for mir::Body<'tcx> {
|
|||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
self.local_decls
|
self.local_decls
|
||||||
.iter()
|
.iter_enumerated()
|
||||||
.map(|decl| stable_mir::mir::LocalDecl {
|
.map(|(local, decl)| stable_mir::mir::LocalDecl {
|
||||||
ty: decl.ty.stable(tables),
|
ty: decl.ty.stable(tables),
|
||||||
span: decl.source_info.span.stable(tables),
|
span: decl.source_info.span.stable(tables),
|
||||||
|
local: local.as_usize(),
|
||||||
|
mutability: decl.mutability.stable(tables),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
self.arg_count,
|
self.arg_count,
|
||||||
|
@ -64,6 +64,8 @@ type LocalDecls = Vec<LocalDecl>;
|
|||||||
pub struct LocalDecl {
|
pub struct LocalDecl {
|
||||||
pub ty: Ty,
|
pub ty: Ty,
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
|
pub local: Local,
|
||||||
|
pub mutability: Mutability,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user