Skip to content

Commit 7502b4c

Browse files
committedJul 18, 2014
auto merge of #15742 : pnkfelix/rust/fsk-fix-15019, r=pcwalton
Removed `index_to_bitset` field and `_frozen` methods. Drive-by: Added some missing docs on the `each_bit` method. Drive-by: Put in a regular pattern: when calling `compute_id_range`, ensure `words_per_id > 0` by either asserting it or checking and returning early. (The prior code did the latter in a few cases where necessary, but debugging is much aided by the asserts.) Fix #15019.
2 parents 9c9bdfd + 8f50428 commit 7502b4c

File tree

3 files changed

+55
-104
lines changed

3 files changed

+55
-104
lines changed
 

‎src/librustc/middle/borrowck/check_loans.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ impl<'a> CheckLoanCtxt<'a> {
172172
//! are issued for future scopes and thus they may have been
173173
//! *issued* but not yet be in effect.
174174
175-
self.dfcx_loans.each_bit_on_entry_frozen(scope_id, |loan_index| {
175+
self.dfcx_loans.each_bit_on_entry(scope_id, |loan_index| {
176176
let loan = &self.all_loans[loan_index];
177177
op(loan)
178178
})
@@ -271,7 +271,7 @@ impl<'a> CheckLoanCtxt<'a> {
271271
//! we encounter `scope_id`.
272272
273273
let mut result = Vec::new();
274-
self.dfcx_loans.each_gen_bit_frozen(scope_id, |loan_index| {
274+
self.dfcx_loans.each_gen_bit(scope_id, |loan_index| {
275275
result.push(loan_index);
276276
true
277277
});

‎src/librustc/middle/borrowck/move_data.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -576,7 +576,7 @@ impl<'a> FlowedMoveData<'a> {
576576
* Iterates through each path moved by `id`
577577
*/
578578

579-
self.dfcx_moves.each_gen_bit_frozen(id, |index| {
579+
self.dfcx_moves.each_gen_bit(id, |index| {
580580
let move = self.move_data.moves.borrow();
581581
let move = move.get(index);
582582
let moved_path = move.path;
@@ -592,7 +592,7 @@ impl<'a> FlowedMoveData<'a> {
592592
593593
let mut ret = None;
594594
for loan_path_index in self.move_data.path_map.borrow().find(&*loan_path).iter() {
595-
self.dfcx_moves.each_gen_bit_frozen(id, |move_index| {
595+
self.dfcx_moves.each_gen_bit(id, |move_index| {
596596
let move = self.move_data.moves.borrow();
597597
let move = move.get(move_index);
598598
if move.path == **loan_path_index {
@@ -637,7 +637,7 @@ impl<'a> FlowedMoveData<'a> {
637637

638638
let mut ret = true;
639639

640-
self.dfcx_moves.each_bit_on_entry_frozen(id, |index| {
640+
self.dfcx_moves.each_bit_on_entry(id, |index| {
641641
let move = self.move_data.moves.borrow();
642642
let move = move.get(index);
643643
let moved_path = move.path;
@@ -693,7 +693,7 @@ impl<'a> FlowedMoveData<'a> {
693693
}
694694
};
695695

696-
self.dfcx_assign.each_bit_on_entry_frozen(id, |index| {
696+
self.dfcx_assign.each_bit_on_entry(id, |index| {
697697
let assignment = self.move_data.var_assignments.borrow();
698698
let assignment = assignment.get(index);
699699
if assignment.path == loan_path_index && !f(assignment) {

‎src/librustc/middle/dataflow.rs

+49-98
Original file line numberDiff line numberDiff line change
@@ -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 {
9895
impl<'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

Comments
 (0)
Please sign in to comment.