77//!
88//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
99
10- use crate :: stable_mir:: { self } ;
10+ use crate :: {
11+ rustc_internal:: { crate_item, item_def_id} ,
12+ stable_mir:: { self } ,
13+ } ;
1114use rustc_middle:: ty:: { tls:: with, TyCtxt } ;
1215use rustc_span:: def_id:: { CrateNum , LOCAL_CRATE } ;
1316use tracing:: debug;
@@ -34,9 +37,7 @@ pub fn find_crate(name: &str) -> Option<stable_mir::Crate> {
3437
3538/// Retrieve all items of the local crate that have a MIR associated with them.
3639pub fn all_local_items ( ) -> stable_mir:: CrateItems {
37- with ( |tcx| {
38- tcx. mir_keys ( ( ) ) . iter ( ) . map ( |item| stable_mir:: CrateItem ( item. to_def_id ( ) ) ) . collect ( )
39- } )
40+ with ( |tcx| tcx. mir_keys ( ( ) ) . iter ( ) . map ( |item| crate_item ( item. to_def_id ( ) ) ) . collect ( ) )
4041}
4142
4243/// Build a stable mir crate from a given crate number.
@@ -46,3 +47,112 @@ fn smir_crate(tcx: TyCtxt<'_>, crate_num: CrateNum) -> stable_mir::Crate {
4647 debug ! ( ?crate_name, ?crate_num, "smir_crate" ) ;
4748 stable_mir:: Crate { id : crate_num. into ( ) , name : crate_name, is_local }
4849}
50+
51+ pub fn mir_body ( item : & stable_mir:: CrateItem ) -> stable_mir:: mir:: Body {
52+ with ( |tcx| {
53+ let def_id = item_def_id ( item) ;
54+ let mir = tcx. optimized_mir ( def_id) ;
55+ stable_mir:: mir:: Body {
56+ blocks : mir
57+ . basic_blocks
58+ . iter ( )
59+ . map ( |block| stable_mir:: mir:: BasicBlock {
60+ terminator : rustc_terminator_to_terminator ( block. terminator ( ) ) ,
61+ statements : block. statements . iter ( ) . map ( rustc_statement_to_statement) . collect ( ) ,
62+ } )
63+ . collect ( ) ,
64+ }
65+ } )
66+ }
67+
68+ fn rustc_statement_to_statement (
69+ s : & rustc_middle:: mir:: Statement < ' _ > ,
70+ ) -> stable_mir:: mir:: Statement {
71+ use rustc_middle:: mir:: StatementKind :: * ;
72+ match & s. kind {
73+ Assign ( assign) => stable_mir:: mir:: Statement :: Assign (
74+ rustc_place_to_place ( & assign. 0 ) ,
75+ rustc_rvalue_to_rvalue ( & assign. 1 ) ,
76+ ) ,
77+ FakeRead ( _) => todo ! ( ) ,
78+ SetDiscriminant { .. } => todo ! ( ) ,
79+ Deinit ( _) => todo ! ( ) ,
80+ StorageLive ( _) => todo ! ( ) ,
81+ StorageDead ( _) => todo ! ( ) ,
82+ Retag ( _, _) => todo ! ( ) ,
83+ PlaceMention ( _) => todo ! ( ) ,
84+ AscribeUserType ( _, _) => todo ! ( ) ,
85+ Coverage ( _) => todo ! ( ) ,
86+ Intrinsic ( _) => todo ! ( ) ,
87+ ConstEvalCounter => todo ! ( ) ,
88+ Nop => stable_mir:: mir:: Statement :: Nop ,
89+ }
90+ }
91+
92+ fn rustc_rvalue_to_rvalue ( rvalue : & rustc_middle:: mir:: Rvalue < ' _ > ) -> stable_mir:: mir:: Operand {
93+ use rustc_middle:: mir:: Rvalue :: * ;
94+ match rvalue {
95+ Use ( op) => rustc_op_to_op ( op) ,
96+ Repeat ( _, _) => todo ! ( ) ,
97+ Ref ( _, _, _) => todo ! ( ) ,
98+ ThreadLocalRef ( _) => todo ! ( ) ,
99+ AddressOf ( _, _) => todo ! ( ) ,
100+ Len ( _) => todo ! ( ) ,
101+ Cast ( _, _, _) => todo ! ( ) ,
102+ BinaryOp ( _, _) => todo ! ( ) ,
103+ CheckedBinaryOp ( _, _) => todo ! ( ) ,
104+ NullaryOp ( _, _) => todo ! ( ) ,
105+ UnaryOp ( _, _) => todo ! ( ) ,
106+ Discriminant ( _) => todo ! ( ) ,
107+ Aggregate ( _, _) => todo ! ( ) ,
108+ ShallowInitBox ( _, _) => todo ! ( ) ,
109+ CopyForDeref ( _) => todo ! ( ) ,
110+ }
111+ }
112+
113+ fn rustc_op_to_op ( op : & rustc_middle:: mir:: Operand < ' _ > ) -> stable_mir:: mir:: Operand {
114+ use rustc_middle:: mir:: Operand :: * ;
115+ match op {
116+ Copy ( place) => stable_mir:: mir:: Operand :: Copy ( rustc_place_to_place ( place) ) ,
117+ Move ( place) => stable_mir:: mir:: Operand :: Move ( rustc_place_to_place ( place) ) ,
118+ Constant ( c) => stable_mir:: mir:: Operand :: Constant ( c. to_string ( ) ) ,
119+ }
120+ }
121+
122+ fn rustc_place_to_place ( place : & rustc_middle:: mir:: Place < ' _ > ) -> stable_mir:: mir:: Place {
123+ assert_eq ! ( & place. projection[ ..] , & [ ] ) ;
124+ stable_mir:: mir:: Place { local : place. local . as_usize ( ) }
125+ }
126+
127+ fn rustc_terminator_to_terminator (
128+ terminator : & rustc_middle:: mir:: Terminator < ' _ > ,
129+ ) -> stable_mir:: mir:: Terminator {
130+ use rustc_middle:: mir:: TerminatorKind :: * ;
131+ use stable_mir:: mir:: Terminator ;
132+ match & terminator. kind {
133+ Goto { target } => Terminator :: Goto { target : target. as_usize ( ) } ,
134+ SwitchInt { discr, targets } => Terminator :: SwitchInt {
135+ discr : rustc_op_to_op ( discr) ,
136+ targets : targets
137+ . iter ( )
138+ . map ( |( value, target) | stable_mir:: mir:: SwitchTarget {
139+ value,
140+ target : target. as_usize ( ) ,
141+ } )
142+ . collect ( ) ,
143+ otherwise : targets. otherwise ( ) . as_usize ( ) ,
144+ } ,
145+ Resume => Terminator :: Resume ,
146+ Abort => Terminator :: Abort ,
147+ Return => Terminator :: Return ,
148+ Unreachable => Terminator :: Unreachable ,
149+ Drop { .. } => todo ! ( ) ,
150+ Call { .. } => todo ! ( ) ,
151+ Assert { .. } => todo ! ( ) ,
152+ Yield { .. } => todo ! ( ) ,
153+ GeneratorDrop => todo ! ( ) ,
154+ FalseEdge { .. } => todo ! ( ) ,
155+ FalseUnwind { .. } => todo ! ( ) ,
156+ InlineAsm { .. } => todo ! ( ) ,
157+ }
158+ }
0 commit comments