@@ -13,31 +13,19 @@ use super::simple_passes::outgoing_edges;
13
13
use super :: { apply_rewrite_rules, id} ;
14
14
use rspirv:: dr:: { Block , Function , Instruction , ModuleHeader , Operand } ;
15
15
use rspirv:: spirv:: { Op , Word } ;
16
- use rustc_data_structures:: fx:: { FxHashMap , FxHashSet , FxIndexMap } ;
16
+ use rustc_data_structures:: fx:: { FxHashMap , FxHashSet } ;
17
17
use rustc_middle:: bug;
18
18
use std:: collections:: hash_map;
19
19
20
- // HACK(eddyb) newtype instead of type alias to avoid mistakes.
21
- #[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
22
- struct LabelId ( Word ) ;
23
-
24
20
pub fn mem2reg (
25
21
header : & mut ModuleHeader ,
26
22
types_global_values : & mut Vec < Instruction > ,
27
23
pointer_to_pointee : & FxHashMap < Word , Word > ,
28
24
constants : & FxHashMap < Word , u32 > ,
29
25
func : & mut Function ,
30
26
) {
31
- // HACK(eddyb) this ad-hoc indexing might be useful elsewhere as well, but
32
- // it's made completely irrelevant by SPIR-T so only applies to legacy code.
33
- let mut blocks: FxIndexMap < _ , _ > = func
34
- . blocks
35
- . iter_mut ( )
36
- . map ( |block| ( LabelId ( block. label_id ( ) . unwrap ( ) ) , block) )
37
- . collect ( ) ;
38
-
39
- let reachable = compute_reachable ( & blocks) ;
40
- let preds = compute_preds ( & blocks, & reachable) ;
27
+ let reachable = compute_reachable ( & func. blocks ) ;
28
+ let preds = compute_preds ( & func. blocks , & reachable) ;
41
29
let idom = compute_idom ( & preds, & reachable) ;
42
30
let dominance_frontier = compute_dominance_frontier ( & preds, & idom) ;
43
31
loop {
@@ -46,27 +34,31 @@ pub fn mem2reg(
46
34
types_global_values,
47
35
pointer_to_pointee,
48
36
constants,
49
- & mut blocks,
37
+ & mut func . blocks ,
50
38
& dominance_frontier,
51
39
) ;
52
40
if !changed {
53
41
break ;
54
42
}
55
43
// mem2reg produces minimal SSA form, not pruned, so DCE the dead ones
56
- super :: dce:: dce_phi ( & mut blocks ) ;
44
+ super :: dce:: dce_phi ( func ) ;
57
45
}
58
46
}
59
47
60
- fn compute_reachable ( blocks : & FxIndexMap < LabelId , & mut Block > ) -> Vec < bool > {
61
- fn recurse ( blocks : & FxIndexMap < LabelId , & mut Block > , reachable : & mut [ bool ] , block : usize ) {
48
+ fn label_to_index ( blocks : & [ Block ] , id : Word ) -> usize {
49
+ blocks
50
+ . iter ( )
51
+ . position ( |b| b. label_id ( ) . unwrap ( ) == id)
52
+ . unwrap ( )
53
+ }
54
+
55
+ fn compute_reachable ( blocks : & [ Block ] ) -> Vec < bool > {
56
+ fn recurse ( blocks : & [ Block ] , reachable : & mut [ bool ] , block : usize ) {
62
57
if !reachable[ block] {
63
58
reachable[ block] = true ;
64
- for dest_id in outgoing_edges ( blocks[ block] ) {
65
- recurse (
66
- blocks,
67
- reachable,
68
- blocks. get_index_of ( & LabelId ( dest_id) ) . unwrap ( ) ,
69
- ) ;
59
+ for dest_id in outgoing_edges ( & blocks[ block] ) {
60
+ let dest_idx = label_to_index ( blocks, dest_id) ;
61
+ recurse ( blocks, reachable, dest_idx) ;
70
62
}
71
63
}
72
64
}
@@ -75,19 +67,17 @@ fn compute_reachable(blocks: &FxIndexMap<LabelId, &mut Block>) -> Vec<bool> {
75
67
reachable
76
68
}
77
69
78
- fn compute_preds (
79
- blocks : & FxIndexMap < LabelId , & mut Block > ,
80
- reachable_blocks : & [ bool ] ,
81
- ) -> Vec < Vec < usize > > {
70
+ fn compute_preds ( blocks : & [ Block ] , reachable_blocks : & [ bool ] ) -> Vec < Vec < usize > > {
82
71
let mut result = vec ! [ vec![ ] ; blocks. len( ) ] ;
83
72
// Do not count unreachable blocks as valid preds of blocks
84
73
for ( source_idx, source) in blocks
85
- . values ( )
74
+ . iter ( )
86
75
. enumerate ( )
87
76
. filter ( |& ( b, _) | reachable_blocks[ b] )
88
77
{
89
78
for dest_id in outgoing_edges ( source) {
90
- result[ blocks. get_index_of ( & LabelId ( dest_id) ) . unwrap ( ) ] . push ( source_idx) ;
79
+ let dest_idx = label_to_index ( blocks, dest_id) ;
80
+ result[ dest_idx] . push ( source_idx) ;
91
81
}
92
82
}
93
83
result
@@ -171,7 +161,7 @@ fn insert_phis_all(
171
161
types_global_values : & mut Vec < Instruction > ,
172
162
pointer_to_pointee : & FxHashMap < Word , Word > ,
173
163
constants : & FxHashMap < Word , u32 > ,
174
- blocks : & mut FxIndexMap < LabelId , & mut Block > ,
164
+ blocks : & mut [ Block ] ,
175
165
dominance_frontier : & [ FxHashSet < usize > ] ,
176
166
) -> bool {
177
167
let var_maps_and_types = blocks[ 0 ]
@@ -208,11 +198,7 @@ fn insert_phis_all(
208
198
rewrite_rules : FxHashMap :: default ( ) ,
209
199
} ;
210
200
renamer. rename ( 0 , None ) ;
211
- // FIXME(eddyb) shouldn't this full rescan of the function be done once?
212
- apply_rewrite_rules (
213
- & renamer. rewrite_rules ,
214
- blocks. values_mut ( ) . map ( |block| & mut * * block) ,
215
- ) ;
201
+ apply_rewrite_rules ( & renamer. rewrite_rules , blocks) ;
216
202
remove_nops ( blocks) ;
217
203
}
218
204
remove_old_variables ( blocks, & var_maps_and_types) ;
@@ -230,7 +216,7 @@ struct VarInfo {
230
216
fn collect_access_chains (
231
217
pointer_to_pointee : & FxHashMap < Word , Word > ,
232
218
constants : & FxHashMap < Word , u32 > ,
233
- blocks : & FxIndexMap < LabelId , & mut Block > ,
219
+ blocks : & [ Block ] ,
234
220
base_var : Word ,
235
221
base_var_ty : Word ,
236
222
) -> Option < FxHashMap < Word , VarInfo > > {
@@ -263,7 +249,7 @@ fn collect_access_chains(
263
249
// Loop in case a previous block references a later AccessChain
264
250
loop {
265
251
let mut changed = false ;
266
- for inst in blocks. values ( ) . flat_map ( |b| & b. instructions ) {
252
+ for inst in blocks. iter ( ) . flat_map ( |b| & b. instructions ) {
267
253
for ( index, op) in inst. operands . iter ( ) . enumerate ( ) {
268
254
if let Operand :: IdRef ( id) = op
269
255
&& variables. contains_key ( id)
@@ -317,10 +303,10 @@ fn collect_access_chains(
317
303
// same var map (e.g. `s.x = s.y;`).
318
304
fn split_copy_memory (
319
305
header : & mut ModuleHeader ,
320
- blocks : & mut FxIndexMap < LabelId , & mut Block > ,
306
+ blocks : & mut [ Block ] ,
321
307
var_map : & FxHashMap < Word , VarInfo > ,
322
308
) {
323
- for block in blocks. values_mut ( ) {
309
+ for block in blocks {
324
310
let mut inst_index = 0 ;
325
311
while inst_index < block. instructions . len ( ) {
326
312
let inst = & block. instructions [ inst_index] ;
@@ -379,7 +365,7 @@ fn has_store(block: &Block, var_map: &FxHashMap<Word, VarInfo>) -> bool {
379
365
}
380
366
381
367
fn insert_phis (
382
- blocks : & FxIndexMap < LabelId , & mut Block > ,
368
+ blocks : & [ Block ] ,
383
369
dominance_frontier : & [ FxHashSet < usize > ] ,
384
370
var_map : & FxHashMap < Word , VarInfo > ,
385
371
) -> FxHashSet < usize > {
@@ -388,7 +374,7 @@ fn insert_phis(
388
374
let mut ever_on_work_list = FxHashSet :: default ( ) ;
389
375
let mut work_list = Vec :: new ( ) ;
390
376
let mut blocks_with_phi = FxHashSet :: default ( ) ;
391
- for ( block_idx, block) in blocks. values ( ) . enumerate ( ) {
377
+ for ( block_idx, block) in blocks. iter ( ) . enumerate ( ) {
392
378
if has_store ( block, var_map) {
393
379
ever_on_work_list. insert ( block_idx) ;
394
380
work_list. push ( block_idx) ;
@@ -433,10 +419,10 @@ fn top_stack_or_undef(
433
419
}
434
420
}
435
421
436
- struct Renamer < ' a , ' b > {
422
+ struct Renamer < ' a > {
437
423
header : & ' a mut ModuleHeader ,
438
424
types_global_values : & ' a mut Vec < Instruction > ,
439
- blocks : & ' a mut FxIndexMap < LabelId , & ' b mut Block > ,
425
+ blocks : & ' a mut [ Block ] ,
440
426
blocks_with_phi : FxHashSet < usize > ,
441
427
base_var_type : Word ,
442
428
var_map : & ' a FxHashMap < Word , VarInfo > ,
@@ -446,7 +432,7 @@ struct Renamer<'a, 'b> {
446
432
rewrite_rules : FxHashMap < Word , Word > ,
447
433
}
448
434
449
- impl Renamer < ' _ , ' _ > {
435
+ impl Renamer < ' _ > {
450
436
// Returns the phi definition.
451
437
fn insert_phi_value ( & mut self , block : usize , from_block : usize ) -> Word {
452
438
let from_block_label = self . blocks [ from_block] . label_id ( ) . unwrap ( ) ;
@@ -568,8 +554,9 @@ impl Renamer<'_, '_> {
568
554
}
569
555
}
570
556
571
- for dest_id in outgoing_edges ( self . blocks [ block] ) . collect :: < Vec < _ > > ( ) {
572
- let dest_idx = self . blocks . get_index_of ( & LabelId ( dest_id) ) . unwrap ( ) ;
557
+ for dest_id in outgoing_edges ( & self . blocks [ block] ) . collect :: < Vec < _ > > ( ) {
558
+ // TODO: Don't do this find
559
+ let dest_idx = label_to_index ( self . blocks , dest_id) ;
573
560
self . rename ( dest_idx, Some ( block) ) ;
574
561
}
575
562
@@ -579,16 +566,16 @@ impl Renamer<'_, '_> {
579
566
}
580
567
}
581
568
582
- fn remove_nops ( blocks : & mut FxIndexMap < LabelId , & mut Block > ) {
583
- for block in blocks. values_mut ( ) {
569
+ fn remove_nops ( blocks : & mut [ Block ] ) {
570
+ for block in blocks {
584
571
block
585
572
. instructions
586
573
. retain ( |inst| inst. class . opcode != Op :: Nop ) ;
587
574
}
588
575
}
589
576
590
577
fn remove_old_variables (
591
- blocks : & mut FxIndexMap < LabelId , & mut Block > ,
578
+ blocks : & mut [ Block ] ,
592
579
var_maps_and_types : & [ ( FxHashMap < u32 , VarInfo > , u32 ) ] ,
593
580
) {
594
581
blocks[ 0 ] . instructions . retain ( |inst| {
@@ -599,7 +586,7 @@ fn remove_old_variables(
599
586
. all ( |( var_map, _) | !var_map. contains_key ( & result_id) )
600
587
}
601
588
} ) ;
602
- for block in blocks. values_mut ( ) {
589
+ for block in blocks {
603
590
block. instructions . retain ( |inst| {
604
591
!matches ! ( inst. class. opcode, Op :: AccessChain | Op :: InBoundsAccessChain )
605
592
|| inst. operands . iter ( ) . all ( |op| {
0 commit comments