@@ -48,9 +48,6 @@ pub struct DataFlowContext<'a, O> {
48
48
/// equal to bits_per_id/uint::BITS rounded up.
49
49
words_per_id : uint ,
50
50
51
- // mapping from cfg node index to bitset index.
52
- index_to_bitset : Vec < Option < uint > > ,
53
-
54
51
// mapping from node to cfg node index
55
52
// FIXME (#6298): Shouldn't this go with CFG?
56
53
nodeid_to_index : NodeMap < CFGIndex > ,
@@ -98,58 +95,7 @@ fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
98
95
impl < ' a , O : DataFlowOperator > DataFlowContext < ' a , O > {
99
96
fn has_bitset_for_nodeid ( & self , n : ast:: NodeId ) -> bool {
100
97
assert ! ( n != ast:: DUMMY_NODE_ID ) ;
101
- match self . nodeid_to_index . find ( & n) {
102
- None => false ,
103
- Some ( & cfgidx) => self . has_bitset_for_cfgidx ( cfgidx) ,
104
- }
105
- }
106
- fn has_bitset_for_cfgidx ( & self , cfgidx : CFGIndex ) -> bool {
107
- let node_id = cfgidx. node_id ( ) ;
108
- node_id < self . index_to_bitset . len ( ) &&
109
- self . index_to_bitset . get ( node_id) . is_some ( )
110
- }
111
- fn get_bitset_index ( & self , cfgidx : CFGIndex ) -> uint {
112
- let node_id = cfgidx. node_id ( ) ;
113
- self . index_to_bitset . get ( node_id) . unwrap ( )
114
- }
115
- fn get_or_create_bitset_index ( & mut self , cfgidx : CFGIndex ) -> uint {
116
- assert ! ( self . words_per_id > 0 ) ;
117
- let len = self . gens . len ( ) / self . words_per_id ;
118
- let expanded;
119
- let n;
120
- if self . index_to_bitset . len ( ) <= cfgidx. node_id ( ) {
121
- self . index_to_bitset . grow_set ( cfgidx. node_id ( ) , & None , Some ( len) ) ;
122
- expanded = true ;
123
- n = len;
124
- } else {
125
- let entry = self . index_to_bitset . get_mut ( cfgidx. node_id ( ) ) ;
126
- match * entry {
127
- None => {
128
- * entry = Some ( len) ;
129
- expanded = true ;
130
- n = len;
131
- }
132
- Some ( bitidx) => {
133
- expanded = false ;
134
- n = bitidx;
135
- }
136
- }
137
- }
138
- if expanded {
139
- let entry = if self . oper . initial_value ( ) { uint:: MAX } else { 0 } ;
140
- for _ in range ( 0 , self . words_per_id ) {
141
- self . gens . push ( 0 ) ;
142
- self . kills . push ( 0 ) ;
143
- self . on_entry . push ( entry) ;
144
- }
145
- }
146
-
147
- let start = n * self . words_per_id ;
148
- let end = start + self . words_per_id ;
149
- let len = self . gens . len ( ) ;
150
- assert ! ( start < len) ;
151
- assert ! ( end <= len) ;
152
- n
98
+ self . nodeid_to_index . contains_key ( & n)
153
99
}
154
100
}
155
101
@@ -165,8 +111,9 @@ impl<'a, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, O> {
165
111
} ;
166
112
167
113
if self . has_bitset_for_nodeid ( id) {
114
+ assert ! ( self . bits_per_id > 0 ) ;
168
115
let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
169
- let ( start, end) = self . compute_id_range_frozen ( cfgidx) ;
116
+ let ( start, end) = self . compute_id_range ( cfgidx) ;
170
117
let on_entry = self . on_entry . slice ( start, end) ;
171
118
let entry_str = bits_to_string ( on_entry) ;
172
119
@@ -243,22 +190,26 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
243
190
id_range : IdRange ,
244
191
bits_per_id : uint ) -> DataFlowContext < ' a , O > {
245
192
let words_per_id = ( bits_per_id + uint:: BITS - 1 ) / uint:: BITS ;
193
+ let num_nodes = cfg. graph . all_nodes ( ) . len ( ) ;
246
194
247
195
debug ! ( "DataFlowContext::new(analysis_name: {:s}, id_range={:?}, \
248
- bits_per_id={:?}, words_per_id={:?})",
249
- analysis_name, id_range, bits_per_id, words_per_id) ;
196
+ bits_per_id={:?}, words_per_id={:?}) \
197
+ num_nodes: {}",
198
+ analysis_name, id_range, bits_per_id, words_per_id,
199
+ num_nodes) ;
250
200
251
- let gens = Vec :: new ( ) ;
252
- let kills = Vec :: new ( ) ;
253
- let on_entry = Vec :: new ( ) ;
201
+ let entry = if oper. initial_value ( ) { uint:: MAX } else { 0 } ;
202
+
203
+ let gens = Vec :: from_elem ( num_nodes * words_per_id, 0 ) ;
204
+ let kills = Vec :: from_elem ( num_nodes * words_per_id, 0 ) ;
205
+ let on_entry = Vec :: from_elem ( num_nodes * words_per_id, entry) ;
254
206
255
207
let nodeid_to_index = build_nodeid_to_index ( decl, cfg) ;
256
208
257
209
DataFlowContext {
258
210
tcx : tcx,
259
211
analysis_name : analysis_name,
260
212
words_per_id : words_per_id,
261
- index_to_bitset : Vec :: new ( ) ,
262
213
nodeid_to_index : nodeid_to_index,
263
214
bits_per_id : bits_per_id,
264
215
oper : oper,
@@ -273,6 +224,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
273
224
debug ! ( "{:s} add_gen(id={:?}, bit={:?})" ,
274
225
self . analysis_name, id, bit) ;
275
226
assert ! ( self . nodeid_to_index. contains_key( & id) ) ;
227
+ assert ! ( self . bits_per_id > 0 ) ;
228
+
276
229
let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
277
230
let ( start, end) = self . compute_id_range ( cfgidx) ;
278
231
let gens = self . gens . mut_slice ( start, end) ;
@@ -284,32 +237,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
284
237
debug ! ( "{:s} add_kill(id={:?}, bit={:?})" ,
285
238
self . analysis_name, id, bit) ;
286
239
assert ! ( self . nodeid_to_index. contains_key( & id) ) ;
240
+ assert ! ( self . bits_per_id > 0 ) ;
241
+
287
242
let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
288
243
let ( start, end) = self . compute_id_range ( cfgidx) ;
289
244
let kills = self . kills . mut_slice ( start, end) ;
290
245
set_bit ( kills, bit) ;
291
246
}
292
247
293
- fn apply_gen_kill ( & mut self , cfgidx : CFGIndex , bits : & mut [ uint ] ) {
248
+ fn apply_gen_kill ( & self , cfgidx : CFGIndex , bits : & mut [ uint ] ) {
294
249
//! Applies the gen and kill sets for `cfgidx` to `bits`
295
250
debug ! ( "{:s} apply_gen_kill(cfgidx={}, bits={}) [before]" ,
296
251
self . analysis_name, cfgidx, mut_bits_to_string( bits) ) ;
297
- let ( start, end) = self . compute_id_range ( cfgidx) ;
298
- let gens = self . gens . slice ( start, end) ;
299
- bitwise ( bits, gens, & Union ) ;
300
- let kills = self . kills . slice ( start, end) ;
301
- bitwise ( bits, kills, & Subtract ) ;
302
-
303
- debug ! ( "{:s} apply_gen_kill(cfgidx={}, bits={}) [after]" ,
304
- self . analysis_name, cfgidx, mut_bits_to_string( bits) ) ;
305
- }
252
+ assert ! ( self . bits_per_id > 0 ) ;
306
253
307
- fn apply_gen_kill_frozen ( & self , cfgidx : CFGIndex , bits : & mut [ uint ] ) {
308
- //! Applies the gen and kill sets for `cfgidx` to `bits`
309
- //! Only useful after `propagate()` has been called.
310
- debug ! ( "{:s} apply_gen_kill(cfgidx={}, bits={}) [before]" ,
311
- self . analysis_name, cfgidx, mut_bits_to_string( bits) ) ;
312
- let ( start, end) = self . compute_id_range_frozen ( cfgidx) ;
254
+ let ( start, end) = self . compute_id_range ( cfgidx) ;
313
255
let gens = self . gens . slice ( start, end) ;
314
256
bitwise ( bits, gens, & Union ) ;
315
257
let kills = self . kills . slice ( start, end) ;
@@ -319,15 +261,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
319
261
self . analysis_name, cfgidx, mut_bits_to_string( bits) ) ;
320
262
}
321
263
322
- fn compute_id_range_frozen ( & self , cfgidx : CFGIndex ) -> ( uint , uint ) {
323
- let n = self . get_bitset_index ( cfgidx) ;
324
- let start = n * self . words_per_id ;
325
- let end = start + self . words_per_id ;
326
- ( start, end)
327
- }
328
-
329
- fn compute_id_range ( & mut self , cfgidx : CFGIndex ) -> ( uint , uint ) {
330
- let n = self . get_or_create_bitset_index ( cfgidx) ;
264
+ fn compute_id_range ( & self , cfgidx : CFGIndex ) -> ( uint , uint ) {
265
+ let n = cfgidx. node_id ( ) ;
331
266
let start = n * self . words_per_id ;
332
267
let end = start + self . words_per_id ;
333
268
@@ -340,10 +275,10 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
340
275
}
341
276
342
277
343
- pub fn each_bit_on_entry_frozen ( & self ,
344
- id : ast:: NodeId ,
345
- f: |uint| -> bool)
346
- -> bool {
278
+ pub fn each_bit_on_entry ( & self ,
279
+ id : ast:: NodeId ,
280
+ f: |uint| -> bool)
281
+ -> bool {
347
282
//! Iterates through each bit that is set on entry to `id`.
348
283
//! Only useful after `propagate()` has been called.
349
284
if !self . has_bitset_for_nodeid ( id) {
@@ -360,17 +295,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
360
295
-> bool {
361
296
//! Iterates through each bit that is set on entry/exit to `cfgidx`.
362
297
//! Only useful after `propagate()` has been called.
363
- if !self . has_bitset_for_cfgidx ( cfgidx) {
298
+
299
+ if self . bits_per_id == 0 {
300
+ // Skip the surprisingly common degenerate case. (Note
301
+ // compute_id_range requires self.words_per_id > 0.)
364
302
return true ;
365
303
}
366
- let ( start, end) = self . compute_id_range_frozen ( cfgidx) ;
304
+
305
+ let ( start, end) = self . compute_id_range ( cfgidx) ;
367
306
let on_entry = self . on_entry . slice ( start, end) ;
368
307
let temp_bits;
369
308
let slice = match e {
370
309
Entry => on_entry,
371
310
Exit => {
372
311
let mut t = on_entry. to_vec ( ) ;
373
- self . apply_gen_kill_frozen ( cfgidx, t. as_mut_slice ( ) ) ;
312
+ self . apply_gen_kill ( cfgidx, t. as_mut_slice ( ) ) ;
374
313
temp_bits = t;
375
314
temp_bits. as_slice ( )
376
315
}
@@ -380,15 +319,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
380
319
self . each_bit ( slice, f)
381
320
}
382
321
383
- pub fn each_gen_bit_frozen ( & self , id : ast:: NodeId , f: |uint| -> bool)
384
- -> bool {
322
+ pub fn each_gen_bit ( & self , id : ast:: NodeId , f: |uint| -> bool)
323
+ -> bool {
385
324
//! Iterates through each bit in the gen set for `id`.
386
- //! Only useful after `propagate()` has been called.
387
325
if !self . has_bitset_for_nodeid ( id) {
388
326
return true ;
389
327
}
328
+
329
+ if self . bits_per_id == 0 {
330
+ // Skip the surprisingly common degenerate case. (Note
331
+ // compute_id_range requires self.words_per_id > 0.)
332
+ return true ;
333
+ }
334
+
390
335
let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
391
- let ( start, end) = self . compute_id_range_frozen ( cfgidx) ;
336
+ let ( start, end) = self . compute_id_range ( cfgidx) ;
392
337
let gens = self . gens . slice ( start, end) ;
393
338
debug ! ( "{:s} each_gen_bit(id={:?}, gens={})" ,
394
339
self . analysis_name, id, bits_to_string( gens) ) ;
@@ -397,6 +342,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
397
342
398
343
fn each_bit ( & self , words : & [ uint ] , f: |uint| -> bool) -> bool {
399
344
//! Helper for iterating over the bits in a bit set.
345
+ //! Returns false on the first call to `f` that returns false;
346
+ //! if all calls to `f` return true, then returns true.
400
347
401
348
for ( word_index, & word) in words. iter ( ) . enumerate ( ) {
402
349
if word != 0 {
@@ -527,6 +474,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
527
474
in_out : & mut [ uint ] ) {
528
475
debug ! ( "DataFlowContext::walk_cfg(in_out={}) {:s}" ,
529
476
bits_to_string( in_out) , self . dfcx. analysis_name) ;
477
+ assert ! ( self . dfcx. bits_per_id > 0 ) ;
478
+
530
479
cfg. graph . each_node ( |node_index, node| {
531
480
debug ! ( "DataFlowContext::walk_cfg idx={} id={} begin in_out={}" ,
532
481
node_index, node. data. id, bits_to_string( in_out) ) ;
@@ -570,6 +519,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
570
519
let cfgidx = edge. target ( ) ;
571
520
debug ! ( "{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})" ,
572
521
self . dfcx. analysis_name, bits_to_string( pred_bits) , source, cfgidx) ;
522
+ assert ! ( self . dfcx. bits_per_id > 0 ) ;
523
+
573
524
let ( start, end) = self . dfcx . compute_id_range ( cfgidx) ;
574
525
let changed = {
575
526
// (scoping mutable borrow of self.dfcx.on_entry)
0 commit comments