@@ -53,7 +53,7 @@ pub struct DataFlowContext<'a, 'tcx: 'a, O> {
53
53
54
54
// mapping from node to cfg node index
55
55
// FIXME (#6298): Shouldn't this go with CFG?
56
- nodeid_to_index : NodeMap < CFGIndex > ,
56
+ nodeid_to_index : NodeMap < Vec < CFGIndex > > ,
57
57
58
58
// Bit sets per cfg node. The following three fields (`gens`, `kills`,
59
59
// and `on_entry`) all have the same structure. For each id in
@@ -88,11 +88,9 @@ struct PropagationContext<'a, 'b: 'a, 'tcx: 'b, O: 'a> {
88
88
changed : bool
89
89
}
90
90
91
- fn to_cfgidx_or_die ( id : ast:: NodeId , index : & NodeMap < CFGIndex > ) -> CFGIndex {
92
- let opt_cfgindex = index. get ( & id) . cloned ( ) ;
93
- opt_cfgindex. unwrap_or_else ( || {
94
- panic ! ( "nodeid_to_index does not have entry for NodeId {}" , id) ;
95
- } )
91
+ fn get_cfg_indices < ' a > ( id : ast:: NodeId , index : & ' a NodeMap < Vec < CFGIndex > > ) -> & ' a [ CFGIndex ] {
92
+ let opt_indices = index. get ( & id) ;
93
+ opt_indices. map ( |v| & v[ ..] ) . unwrap_or ( & [ ] )
96
94
}
97
95
98
96
impl < ' a , ' tcx , O : DataFlowOperator > DataFlowContext < ' a , ' tcx , O > {
@@ -114,9 +112,13 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
114
112
pprust:: NodePat ( pat) => pat. id
115
113
} ;
116
114
117
- if self . has_bitset_for_nodeid ( id) {
118
- assert ! ( self . bits_per_id > 0 ) ;
119
- let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
115
+ if !self . has_bitset_for_nodeid ( id) {
116
+ return Ok ( ( ) ) ;
117
+ }
118
+
119
+ assert ! ( self . bits_per_id > 0 ) ;
120
+ let indices = get_cfg_indices ( id, & self . nodeid_to_index ) ;
121
+ for & cfgidx in indices {
120
122
let ( start, end) = self . compute_id_range ( cfgidx) ;
121
123
let on_entry = & self . on_entry [ start.. end] ;
122
124
let entry_str = bits_to_string ( on_entry) ;
@@ -144,7 +146,7 @@ impl<'a, 'tcx, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, 'tcx, O
144
146
}
145
147
146
148
fn build_nodeid_to_index ( decl : Option < & ast:: FnDecl > ,
147
- cfg : & cfg:: CFG ) -> NodeMap < CFGIndex > {
149
+ cfg : & cfg:: CFG ) -> NodeMap < Vec < CFGIndex > > {
148
150
let mut index = NodeMap ( ) ;
149
151
150
152
// FIXME (#6298): Would it be better to fold formals from decl
@@ -157,28 +159,38 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
157
159
}
158
160
159
161
cfg. graph . each_node ( |node_idx, node| {
160
- if node. data . id != ast:: DUMMY_NODE_ID {
161
- index. insert ( node. data . id , node_idx) ;
162
+ if let cfg:: CFGNodeData :: AST ( id) = node. data {
163
+ match index. entry ( id) . get ( ) {
164
+ Ok ( v) => v. push ( node_idx) ,
165
+ Err ( e) => {
166
+ e. insert ( vec ! [ node_idx] ) ;
167
+ }
168
+ }
162
169
}
163
170
true
164
171
} ) ;
165
172
166
173
return index;
167
174
168
- fn add_entries_from_fn_decl ( index : & mut NodeMap < CFGIndex > ,
175
+ fn add_entries_from_fn_decl ( index : & mut NodeMap < Vec < CFGIndex > > ,
169
176
decl : & ast:: FnDecl ,
170
177
entry : CFGIndex ) {
171
178
//! add mappings from the ast nodes for the formal bindings to
172
179
//! the entry-node in the graph.
173
180
struct Formals < ' a > {
174
181
entry : CFGIndex ,
175
- index : & ' a mut NodeMap < CFGIndex > ,
182
+ index : & ' a mut NodeMap < Vec < CFGIndex > > ,
176
183
}
177
184
let mut formals = Formals { entry : entry, index : index } ;
178
185
visit:: walk_fn_decl ( & mut formals, decl) ;
179
186
impl < ' a , ' v > visit:: Visitor < ' v > for Formals < ' a > {
180
187
fn visit_pat ( & mut self , p : & ast:: Pat ) {
181
- self . index . insert ( p. id , self . entry ) ;
188
+ match self . index . entry ( p. id ) . get ( ) {
189
+ Ok ( v) => v. push ( self . entry ) ,
190
+ Err ( e) => {
191
+ e. insert ( vec ! [ self . entry] ) ;
192
+ }
193
+ }
182
194
visit:: walk_pat ( self , p)
183
195
}
184
196
}
@@ -230,10 +242,12 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
230
242
assert ! ( self . nodeid_to_index. contains_key( & id) ) ;
231
243
assert ! ( self . bits_per_id > 0 ) ;
232
244
233
- let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
234
- let ( start, end) = self . compute_id_range ( cfgidx) ;
235
- let gens = & mut self . gens [ start.. end] ;
236
- set_bit ( gens, bit) ;
245
+ let indices = get_cfg_indices ( id, & self . nodeid_to_index ) ;
246
+ for & cfgidx in indices {
247
+ let ( start, end) = self . compute_id_range ( cfgidx) ;
248
+ let gens = & mut self . gens [ start.. end] ;
249
+ set_bit ( gens, bit) ;
250
+ }
237
251
}
238
252
239
253
pub fn add_kill ( & mut self , id : ast:: NodeId , bit : uint ) {
@@ -243,10 +257,12 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
243
257
assert ! ( self . nodeid_to_index. contains_key( & id) ) ;
244
258
assert ! ( self . bits_per_id > 0 ) ;
245
259
246
- let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
247
- let ( start, end) = self . compute_id_range ( cfgidx) ;
248
- let kills = & mut self . kills [ start.. end] ;
249
- set_bit ( kills, bit) ;
260
+ let indices = get_cfg_indices ( id, & self . nodeid_to_index ) ;
261
+ for & cfgidx in indices {
262
+ let ( start, end) = self . compute_id_range ( cfgidx) ;
263
+ let kills = & mut self . kills [ start.. end] ;
264
+ set_bit ( kills, bit) ;
265
+ }
250
266
}
251
267
252
268
fn apply_gen_kill ( & self , cfgidx : CFGIndex , bits : & mut [ uint ] ) {
@@ -279,16 +295,21 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
279
295
}
280
296
281
297
282
- pub fn each_bit_on_entry < F > ( & self , id : ast:: NodeId , f : F ) -> bool where
298
+ pub fn each_bit_on_entry < F > ( & self , id : ast:: NodeId , mut f : F ) -> bool where
283
299
F : FnMut ( uint ) -> bool ,
284
300
{
285
301
//! Iterates through each bit that is set on entry to `id`.
286
302
//! Only useful after `propagate()` has been called.
287
303
if !self . has_bitset_for_nodeid ( id) {
288
304
return true ;
289
305
}
290
- let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
291
- self . each_bit_for_node ( Entry , cfgidx, f)
306
+ let indices = get_cfg_indices ( id, & self . nodeid_to_index ) ;
307
+ for & cfgidx in indices {
308
+ if !self . each_bit_for_node ( Entry , cfgidx, |i| f ( i) ) {
309
+ return false ;
310
+ }
311
+ }
312
+ return true ;
292
313
}
293
314
294
315
pub fn each_bit_for_node < F > ( & self , e : EntryOrExit , cfgidx : CFGIndex , f : F ) -> bool where
@@ -320,7 +341,7 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
320
341
self . each_bit ( slice, f)
321
342
}
322
343
323
- pub fn each_gen_bit < F > ( & self , id : ast:: NodeId , f : F ) -> bool where
344
+ pub fn each_gen_bit < F > ( & self , id : ast:: NodeId , mut f : F ) -> bool where
324
345
F : FnMut ( uint ) -> bool ,
325
346
{
326
347
//! Iterates through each bit in the gen set for `id`.
@@ -334,12 +355,17 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
334
355
return true ;
335
356
}
336
357
337
- let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
338
- let ( start, end) = self . compute_id_range ( cfgidx) ;
339
- let gens = & self . gens [ start.. end] ;
340
- debug ! ( "{} each_gen_bit(id={}, gens={})" ,
341
- self . analysis_name, id, bits_to_string( gens) ) ;
342
- self . each_bit ( gens, f)
358
+ let indices = get_cfg_indices ( id, & self . nodeid_to_index ) ;
359
+ for & cfgidx in indices {
360
+ let ( start, end) = self . compute_id_range ( cfgidx) ;
361
+ let gens = & self . gens [ start.. end] ;
362
+ debug ! ( "{} each_gen_bit(id={}, gens={})" ,
363
+ self . analysis_name, id, bits_to_string( gens) ) ;
364
+ if !self . each_bit ( gens, |i| f ( i) ) {
365
+ return false ;
366
+ }
367
+ }
368
+ return true ;
343
369
}
344
370
345
371
fn each_bit < F > ( & self , words : & [ uint ] , mut f : F ) -> bool where
@@ -400,13 +426,15 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> {
400
426
401
427
let mut changed = false ;
402
428
for & node_id in & edge. data . exiting_scopes {
403
- let opt_cfg_idx = self . nodeid_to_index . get ( & node_id) . cloned ( ) ;
429
+ let opt_cfg_idx = self . nodeid_to_index . get ( & node_id) ;
404
430
match opt_cfg_idx {
405
- Some ( cfg_idx) => {
406
- let ( start, end) = self . compute_id_range ( cfg_idx) ;
407
- let kills = & self . kills [ start.. end] ;
408
- if bitwise ( & mut orig_kills, kills, & Union ) {
409
- changed = true ;
431
+ Some ( indices) => {
432
+ for & cfg_idx in indices {
433
+ let ( start, end) = self . compute_id_range ( cfg_idx) ;
434
+ let kills = & self . kills [ start.. end] ;
435
+ if bitwise ( & mut orig_kills, kills, & Union ) {
436
+ changed = true ;
437
+ }
410
438
}
411
439
}
412
440
None => {
@@ -482,7 +510,7 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> {
482
510
483
511
cfg. graph . each_node ( |node_index, node| {
484
512
debug ! ( "DataFlowContext::walk_cfg idx={:?} id={} begin in_out={}" ,
485
- node_index, node. data. id, bits_to_string( in_out) ) ;
513
+ node_index, node. data. id( ) , bits_to_string( in_out) ) ;
486
514
487
515
let ( start, end) = self . dfcx . compute_id_range ( node_index) ;
488
516
0 commit comments