@@ -48,9 +48,6 @@ pub struct DataFlowContext<'a, O> {
4848 /// equal to bits_per_id/uint::BITS rounded up.
4949 words_per_id : uint ,
5050
51- // mapping from cfg node index to bitset index.
52- index_to_bitset : Vec < Option < uint > > ,
53-
5451 // mapping from node to cfg node index
5552 // FIXME (#6298): Shouldn't this go with CFG?
5653 nodeid_to_index : NodeMap < CFGIndex > ,
@@ -98,58 +95,7 @@ fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
9895impl < ' a , O : DataFlowOperator > DataFlowContext < ' a , O > {
9996 fn has_bitset_for_nodeid ( & self , n : ast:: NodeId ) -> bool {
10097 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)
15399 }
154100}
155101
@@ -165,8 +111,9 @@ impl<'a, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, O> {
165111 } ;
166112
167113 if self . has_bitset_for_nodeid ( id) {
114+ assert ! ( self . bits_per_id > 0 ) ;
168115 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) ;
170117 let on_entry = self . on_entry . slice ( start, end) ;
171118 let entry_str = bits_to_string ( on_entry) ;
172119
@@ -243,22 +190,26 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
243190 id_range : IdRange ,
244191 bits_per_id : uint ) -> DataFlowContext < ' a , O > {
245192 let words_per_id = ( bits_per_id + uint:: BITS - 1 ) / uint:: BITS ;
193+ let num_nodes = cfg. graph . all_nodes ( ) . len ( ) ;
246194
247195 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) ;
250200
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) ;
254206
255207 let nodeid_to_index = build_nodeid_to_index ( decl, cfg) ;
256208
257209 DataFlowContext {
258210 tcx : tcx,
259211 analysis_name : analysis_name,
260212 words_per_id : words_per_id,
261- index_to_bitset : Vec :: new ( ) ,
262213 nodeid_to_index : nodeid_to_index,
263214 bits_per_id : bits_per_id,
264215 oper : oper,
@@ -273,6 +224,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
273224 debug ! ( "{:s} add_gen(id={:?}, bit={:?})" ,
274225 self . analysis_name, id, bit) ;
275226 assert ! ( self . nodeid_to_index. contains_key( & id) ) ;
227+ assert ! ( self . bits_per_id > 0 ) ;
228+
276229 let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
277230 let ( start, end) = self . compute_id_range ( cfgidx) ;
278231 let gens = self . gens . mut_slice ( start, end) ;
@@ -284,32 +237,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
284237 debug ! ( "{:s} add_kill(id={:?}, bit={:?})" ,
285238 self . analysis_name, id, bit) ;
286239 assert ! ( self . nodeid_to_index. contains_key( & id) ) ;
240+ assert ! ( self . bits_per_id > 0 ) ;
241+
287242 let cfgidx = to_cfgidx_or_die ( id, & self . nodeid_to_index ) ;
288243 let ( start, end) = self . compute_id_range ( cfgidx) ;
289244 let kills = self . kills . mut_slice ( start, end) ;
290245 set_bit ( kills, bit) ;
291246 }
292247
293- fn apply_gen_kill ( & mut self , cfgidx : CFGIndex , bits : & mut [ uint ] ) {
248+ fn apply_gen_kill ( & self , cfgidx : CFGIndex , bits : & mut [ uint ] ) {
294249 //! Applies the gen and kill sets for `cfgidx` to `bits`
295250 debug ! ( "{:s} apply_gen_kill(cfgidx={}, bits={}) [before]" ,
296251 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 ) ;
306253
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) ;
313255 let gens = self . gens . slice ( start, end) ;
314256 bitwise ( bits, gens, & Union ) ;
315257 let kills = self . kills . slice ( start, end) ;
@@ -319,15 +261,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
319261 self . analysis_name, cfgidx, mut_bits_to_string( bits) ) ;
320262 }
321263
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 ( ) ;
331266 let start = n * self . words_per_id ;
332267 let end = start + self . words_per_id ;
333268
@@ -340,10 +275,10 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
340275 }
341276
342277
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 {
347282 //! Iterates through each bit that is set on entry to `id`.
348283 //! Only useful after `propagate()` has been called.
349284 if !self . has_bitset_for_nodeid ( id) {
@@ -360,17 +295,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
360295 -> bool {
361296 //! Iterates through each bit that is set on entry/exit to `cfgidx`.
362297 //! 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.)
364302 return true ;
365303 }
366- let ( start, end) = self . compute_id_range_frozen ( cfgidx) ;
304+
305+ let ( start, end) = self . compute_id_range ( cfgidx) ;
367306 let on_entry = self . on_entry . slice ( start, end) ;
368307 let temp_bits;
369308 let slice = match e {
370309 Entry => on_entry,
371310 Exit => {
372311 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 ( ) ) ;
374313 temp_bits = t;
375314 temp_bits. as_slice ( )
376315 }
@@ -380,15 +319,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
380319 self . each_bit ( slice, f)
381320 }
382321
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 {
385324 //! Iterates through each bit in the gen set for `id`.
386- //! Only useful after `propagate()` has been called.
387325 if !self . has_bitset_for_nodeid ( id) {
388326 return true ;
389327 }
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+
390335 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) ;
392337 let gens = self . gens . slice ( start, end) ;
393338 debug ! ( "{:s} each_gen_bit(id={:?}, gens={})" ,
394339 self . analysis_name, id, bits_to_string( gens) ) ;
@@ -397,6 +342,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
397342
398343 fn each_bit ( & self , words : & [ uint ] , f: |uint| -> bool) -> bool {
399344 //! 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.
400347
401348 for ( word_index, & word) in words. iter ( ) . enumerate ( ) {
402349 if word != 0 {
@@ -527,6 +474,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
527474 in_out : & mut [ uint ] ) {
528475 debug ! ( "DataFlowContext::walk_cfg(in_out={}) {:s}" ,
529476 bits_to_string( in_out) , self . dfcx. analysis_name) ;
477+ assert ! ( self . dfcx. bits_per_id > 0 ) ;
478+
530479 cfg. graph . each_node ( |node_index, node| {
531480 debug ! ( "DataFlowContext::walk_cfg idx={} id={} begin in_out={}" ,
532481 node_index, node. data. id, bits_to_string( in_out) ) ;
@@ -570,6 +519,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
570519 let cfgidx = edge. target ( ) ;
571520 debug ! ( "{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})" ,
572521 self . dfcx. analysis_name, bits_to_string( pred_bits) , source, cfgidx) ;
522+ assert ! ( self . dfcx. bits_per_id > 0 ) ;
523+
573524 let ( start, end) = self . dfcx . compute_id_range ( cfgidx) ;
574525 let changed = {
575526 // (scoping mutable borrow of self.dfcx.on_entry)
0 commit comments