7
7
// option. This file may not be copied, modified, or distributed
8
8
// except according to those terms.
9
9
10
- //! This module converts MIR into Yorick TIR (Tracing IR). TIR is more suitable for the run-time
11
- //! tracer: TIR (unlike MIR) is in SSA form (but it does preserve MIR's block structure) .
10
+ //! This module converts MIR into Yorick TIR (Tracing IR).
11
+ //! Note that we preserve the MIR block structure when lowering to TIR .
12
12
//!
13
13
//! Serialisation itself is performed by an external library: ykpack.
14
14
@@ -30,8 +30,7 @@ use std::error::Error;
30
30
use std:: cell:: { Cell , RefCell } ;
31
31
use std:: mem:: size_of;
32
32
use rustc_data_structures:: bit_set:: BitSet ;
33
- use rustc_data_structures:: indexed_vec:: { IndexVec , Idx } ;
34
- use rustc_data_structures:: graph:: dominators:: DominatorFrontiers ;
33
+ use rustc_data_structures:: indexed_vec:: IndexVec ;
35
34
use ykpack;
36
35
use ykpack:: LocalIndex as TirLocal ;
37
36
use rustc_data_structures:: fx:: FxHashSet ;
@@ -48,7 +47,7 @@ pub enum TirMode {
48
47
TextDump ( PathBuf ) ,
49
48
}
50
49
51
- /// A conversion context holds the state needed to perform the conversion to (pre-SSA) TIR.
50
+ /// A conversion context holds the state needed to perform the TIR lowering .
52
51
struct ConvCx < ' a , ' tcx , ' gcx > {
53
52
/// The compiler's god struct. Needed for queries etc.
54
53
tcx : & ' a TyCtxt < ' a , ' tcx , ' gcx > ,
@@ -106,11 +105,6 @@ impl<'a, 'tcx, 'gcx> ConvCx<'a, 'tcx, 'gcx> {
106
105
} )
107
106
}
108
107
109
- /// Finalise the conversion context, returning the definition sites and block defines mappings.
110
- fn done ( self ) -> ( Vec < BitSet < BasicBlock > > , IndexVec < BasicBlock , FxHashSet < TirLocal > > ) {
111
- ( self . def_sites . into_inner ( ) , self . block_defines . into_inner ( ) )
112
- }
113
-
114
108
/// Add `bb` as a definition site of the TIR variable `var`.
115
109
fn push_def_site ( & self , bb : BasicBlock , var : TirLocal ) {
116
110
let mut sites = self . def_sites . borrow_mut ( ) ;
@@ -165,12 +159,12 @@ fn do_generate_tir<'a, 'tcx, 'gcx>(
165
159
// same between builds for the reproducible build tests to pass.
166
160
let mut tir_path = exe_path. clone ( ) ;
167
161
tir_path. set_extension ( TMP_EXT ) ;
168
- let mut file = File :: create ( & tir_path) ?;
162
+ let file = File :: create ( & tir_path) ?;
169
163
( tir_path, Some ( file) , None )
170
164
} ,
171
165
TirMode :: TextDump ( dump_path) => {
172
166
// In text dump mode we just write lines to a file and we don't need an encoder.
173
- let mut file = File :: create ( & dump_path) ?;
167
+ let file = File :: create ( & dump_path) ?;
174
168
( dump_path. clone ( ) , None , Some ( file) )
175
169
} ,
176
170
} ;
@@ -187,19 +181,9 @@ fn do_generate_tir<'a, 'tcx, 'gcx>(
187
181
188
182
for def_id in sorted_def_ids {
189
183
if tcx. is_mir_available ( * def_id) {
190
- info ! ( "generating TIR for {:?}" , def_id) ;
191
-
192
184
let mir = tcx. optimized_mir ( * def_id) ;
193
185
let ccx = ConvCx :: new ( tcx, mir) ;
194
-
195
- let mut pack = ( & ccx, def_id, tcx. optimized_mir ( * def_id) ) . to_pack ( ) ;
196
- {
197
- let ykpack:: Pack :: Mir ( ykpack:: Mir { ref mut blocks, ..} ) = pack;
198
- let ( def_sites, block_defines) = ccx. done ( ) ;
199
- insert_phis ( blocks, mir, def_sites, block_defines) ;
200
- }
201
-
202
- // FIXME - rename variables with fresh SSA names.
186
+ let pack = ( & ccx, def_id, tcx. optimized_mir ( * def_id) ) . to_pack ( ) ;
203
187
204
188
if let Some ( ref mut e) = enc {
205
189
e. serialise ( pack) ?;
@@ -218,51 +202,6 @@ fn do_generate_tir<'a, 'tcx, 'gcx>(
218
202
Ok ( tir_path)
219
203
}
220
204
221
- /// Insert PHI nodes into the initial pre-SSA TIR pack.
222
- ///
223
- /// Algorithm reference:
224
- /// Bottom of p406 of 'Modern Compiler Implementation in Java (2nd ed.)' by Andrew Appel.
225
- fn insert_phis ( blocks : & mut Vec < ykpack:: BasicBlock > , mir : & Mir ,
226
- mut def_sites : Vec < BitSet < BasicBlock > > ,
227
- a_orig : IndexVec < BasicBlock , FxHashSet < TirLocal > > ) {
228
- let doms = mir. dominators ( ) ;
229
- let df = DominatorFrontiers :: new ( mir, & doms) ;
230
- let num_tir_vars = def_sites. len ( ) ;
231
- let num_tir_blks = a_orig. len ( ) ;
232
-
233
- let mut a_phi: Vec < BitSet < TirLocal > > = Vec :: with_capacity ( num_tir_blks) ;
234
- a_phi. resize ( num_tir_blks, BitSet :: new_empty ( num_tir_vars) ) ;
235
-
236
- // We don't need the elements of `def_sites` again past this point, so we can take them out
237
- // of `def_sites` with a draining iterator and mutate in-place.
238
- for ( a, mut w) in def_sites. drain ( ..) . enumerate ( ) {
239
- while !w. is_empty ( ) {
240
- let n = bitset_pop ( & mut w) ;
241
- for y in df. frontier ( n) . iter ( ) {
242
- let y_usize = y. index ( ) ;
243
- // `def_sites` is guaranteed to only contain indices expressible by `u32`.
244
- let a_u32 = a as u32 ;
245
- if !a_phi[ y_usize] . contains ( a_u32) {
246
- a_phi[ y_usize] . insert ( a_u32) ;
247
- if !a_orig[ y] . contains ( & a_u32) {
248
- // The assertion in `tir_var()` has already checked the cast is safe.
249
- insert_phi ( & mut blocks[ y_usize] , a as u32 , mir. predecessors_for ( y) . len ( ) ) ;
250
- w. insert ( y) ;
251
- }
252
- }
253
- }
254
- }
255
- }
256
- }
257
-
258
- fn insert_phi ( block : & mut ykpack:: BasicBlock , var : TirLocal , arity : usize ) {
259
- let lhs = ykpack:: Place :: Local ( var) ;
260
- let rhs_vars = ( 0 ..arity) . map ( |_| lhs. clone ( ) ) . collect ( ) ;
261
- let rhs = ykpack:: Rvalue :: Phi ( rhs_vars) ;
262
- block. stmts . insert ( 0 , ykpack:: Statement :: Assign ( lhs, rhs) ) ;
263
- }
264
-
265
-
266
205
/// The trait for converting MIR data structures into a bytecode packs.
267
206
trait ToPack < T > {
268
207
fn to_pack ( & mut self ) -> T ;
@@ -415,11 +354,3 @@ impl<'tcx> ToPack<ykpack::Rvalue> for (&ConvCx<'_, 'tcx, '_>, &Rvalue<'tcx>) {
415
354
}
416
355
}
417
356
}
418
-
419
- /// At the time of writing, you can't pop from a `BitSet`.
420
- fn bitset_pop < T > ( s : & mut BitSet < T > ) -> T where T : Eq + Idx + Clone {
421
- let e = s. iter ( ) . next ( ) . unwrap ( ) . clone ( ) ;
422
- let removed = s. remove ( e) ;
423
- debug_assert ! ( removed) ;
424
- e
425
- }
0 commit comments