7
7
//!
8
8
//! For now, we are developing everything inside `rustc`, thus, we keep this module private.
9
9
10
- use crate :: stable_mir:: { self } ;
10
+ use crate :: {
11
+ rustc_internal:: { crate_item, item_def_id} ,
12
+ stable_mir:: { self } ,
13
+ } ;
11
14
use rustc_middle:: ty:: { tls:: with, TyCtxt } ;
12
15
use rustc_span:: def_id:: { CrateNum , LOCAL_CRATE } ;
13
16
use tracing:: debug;
@@ -34,9 +37,7 @@ pub fn find_crate(name: &str) -> Option<stable_mir::Crate> {
34
37
35
38
/// Retrieve all items of the local crate that have a MIR associated with them.
36
39
pub 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 ( ) )
40
41
}
41
42
42
43
/// 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 {
46
47
debug ! ( ?crate_name, ?crate_num, "smir_crate" ) ;
47
48
stable_mir:: Crate { id : crate_num. into ( ) , name : crate_name, is_local }
48
49
}
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