Skip to content

Commit 9a5bdd7

Browse files
committed
auto merge of #7202 : pcwalton/rust/resolve-speed, r=pcwalton
I'm pretty sure this got adequately reviewed by a combination of @nikomatsakis and @graydon so I'm rubber stamping it because I really want this in (it makes it much less likely for me to swap, allowing me to get more work done).
2 parents 17eec62 + 6914ff9 commit 9a5bdd7

File tree

3 files changed

+75
-24
lines changed

3 files changed

+75
-24
lines changed

src/librustc/middle/borrowck/check_loans.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ impl<'self> CheckLoanCtxt<'self> {
8282
//! are issued for future scopes and thus they may have been
8383
//! *issued* but not yet be in effect.
8484
85-
for self.dfcx_loans.each_bit_on_entry(scope_id) |loan_index| {
85+
for self.dfcx_loans.each_bit_on_entry_frozen(scope_id) |loan_index| {
8686
let loan = &self.all_loans[loan_index];
8787
if !op(loan) {
8888
return false;
@@ -134,7 +134,7 @@ impl<'self> CheckLoanCtxt<'self> {
134134
//! we encounter `scope_id`.
135135
136136
let mut result = ~[];
137-
for self.dfcx_loans.each_gen_bit(scope_id) |loan_index| {
137+
for self.dfcx_loans.each_gen_bit_frozen(scope_id) |loan_index| {
138138
result.push(loan_index);
139139
}
140140
return result;

src/librustc/middle/borrowck/move_data.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ impl FlowedMoveData {
504504

505505
let opt_loan_path_index = self.move_data.existing_move_path(loan_path);
506506

507-
for self.dfcx_moves.each_bit_on_entry(id) |index| {
507+
for self.dfcx_moves.each_bit_on_entry_frozen(id) |index| {
508508
let move = &self.move_data.moves[index];
509509
let moved_path = move.path;
510510
if base_indices.contains(&moved_path) {
@@ -560,7 +560,7 @@ impl FlowedMoveData {
560560
}
561561
};
562562

563-
for self.dfcx_assign.each_bit_on_entry(id) |index| {
563+
for self.dfcx_assign.each_bit_on_entry_frozen(id) |index| {
564564
let assignment = &self.move_data.var_assignments[index];
565565
if assignment.path == loan_path_index && !f(assignment) {
566566
return false;

src/librustc/middle/dataflow.rs

Lines changed: 71 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use core::cast;
2222
use core::io;
2323
use core::uint;
2424
use core::vec;
25+
use core::hashmap::HashMap;
2526
use syntax::ast;
2627
use syntax::ast_util;
2728
use syntax::ast_util::id_range;
@@ -37,16 +38,16 @@ pub struct DataFlowContext<O> {
3738
/// the data flow operator
3839
priv oper: O,
3940

40-
/// range of ids that appear within the item in question
41-
priv id_range: id_range,
42-
4341
/// number of bits to propagate per id
4442
priv bits_per_id: uint,
4543

4644
/// number of words we will use to store bits_per_id.
4745
/// equal to bits_per_id/uint::bits rounded up.
4846
priv words_per_id: uint,
4947

48+
// mapping from node to bitset index.
49+
priv nodeid_to_bitset: HashMap<ast::node_id,uint>,
50+
5051
// Bit sets per id. The following three fields (`gens`, `kills`,
5152
// and `on_entry`) all have the same structure. For each id in
5253
// `id_range`, there is a range of words equal to `words_per_id`.
@@ -108,19 +109,17 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
108109
debug!("DataFlowContext::new(id_range=%?, bits_per_id=%?, words_per_id=%?)",
109110
id_range, bits_per_id, words_per_id);
110111

111-
let len = (id_range.max - id_range.min) as uint * words_per_id;
112-
let gens = vec::from_elem(len, 0);
113-
let kills = vec::from_elem(len, 0);
114-
let elem = if oper.initial_value() {uint::max_value} else {0};
115-
let on_entry = vec::from_elem(len, elem);
112+
let gens = ~[];
113+
let kills = ~[];
114+
let on_entry = ~[];
116115

117116
DataFlowContext {
118117
tcx: tcx,
119118
method_map: method_map,
120119
words_per_id: words_per_id,
120+
nodeid_to_bitset: HashMap::new(),
121121
bits_per_id: bits_per_id,
122122
oper: oper,
123-
id_range: id_range,
124123
gens: gens,
125124
kills: kills,
126125
on_entry: on_entry
@@ -149,7 +148,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
149148
}
150149
}
151150

152-
fn apply_gen_kill(&self, id: ast::node_id, bits: &mut [uint]) {
151+
fn apply_gen_kill(&mut self, id: ast::node_id, bits: &mut [uint]) {
153152
//! Applies the gen and kill sets for `id` to `bits`
154153
155154
debug!("apply_gen_kill(id=%?, bits=%s) [before]",
@@ -164,7 +163,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
164163
id, mut_bits_to_str(bits));
165164
}
166165

167-
fn apply_kill(&self, id: ast::node_id, bits: &mut [uint]) {
166+
fn apply_kill(&mut self, id: ast::node_id, bits: &mut [uint]) {
168167
debug!("apply_kill(id=%?, bits=%s) [before]",
169168
id, mut_bits_to_str(bits));
170169
let (start, end) = self.compute_id_range(id);
@@ -174,18 +173,56 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
174173
id, mut_bits_to_str(bits));
175174
}
176175

177-
fn compute_id_range(&self, absolute_id: ast::node_id) -> (uint, uint) {
178-
assert!(absolute_id >= self.id_range.min);
179-
assert!(absolute_id < self.id_range.max);
176+
fn compute_id_range_frozen(&self, id: ast::node_id) -> (uint, uint) {
177+
let n = *self.nodeid_to_bitset.get(&id);
178+
let start = n * self.words_per_id;
179+
let end = start + self.words_per_id;
180+
(start, end)
181+
}
180182

181-
let relative_id = absolute_id - self.id_range.min;
182-
let start = (relative_id as uint) * self.words_per_id;
183+
fn compute_id_range(&mut self, id: ast::node_id) -> (uint, uint) {
184+
let mut expanded = false;
185+
let len = self.nodeid_to_bitset.len();
186+
let n = do self.nodeid_to_bitset.find_or_insert_with(id) |_| {
187+
expanded = true;
188+
len
189+
};
190+
if expanded {
191+
let entry = if self.oper.initial_value() { uint::max_value } else {0};
192+
for self.words_per_id.times {
193+
self.gens.push(0);
194+
self.kills.push(0);
195+
self.on_entry.push(entry);
196+
}
197+
}
198+
let start = *n * self.words_per_id;
183199
let end = start + self.words_per_id;
200+
201+
assert!(start < self.gens.len());
202+
assert!(end <= self.gens.len());
203+
assert!(self.gens.len() == self.kills.len());
204+
assert!(self.gens.len() == self.on_entry.len());
205+
184206
(start, end)
185207
}
186208

187209

188-
pub fn each_bit_on_entry(&self,
210+
pub fn each_bit_on_entry_frozen(&self,
211+
id: ast::node_id,
212+
f: &fn(uint) -> bool) -> bool {
213+
//! Iterates through each bit that is set on entry to `id`.
214+
//! Only useful after `propagate()` has been called.
215+
if !self.nodeid_to_bitset.contains_key(&id) {
216+
return true;
217+
}
218+
let (start, end) = self.compute_id_range_frozen(id);
219+
let on_entry = vec::slice(self.on_entry, start, end);
220+
debug!("each_bit_on_entry_frozen(id=%?, on_entry=%s)",
221+
id, bits_to_str(on_entry));
222+
self.each_bit(on_entry, f)
223+
}
224+
225+
pub fn each_bit_on_entry(&mut self,
189226
id: ast::node_id,
190227
f: &fn(uint) -> bool) -> bool {
191228
//! Iterates through each bit that is set on entry to `id`.
@@ -198,7 +235,7 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
198235
self.each_bit(on_entry, f)
199236
}
200237

201-
pub fn each_gen_bit(&self,
238+
pub fn each_gen_bit(&mut self,
202239
id: ast::node_id,
203240
f: &fn(uint) -> bool) -> bool {
204241
//! Iterates through each bit in the gen set for `id`.
@@ -210,6 +247,20 @@ impl<O:DataFlowOperator> DataFlowContext<O> {
210247
self.each_bit(gens, f)
211248
}
212249

250+
pub fn each_gen_bit_frozen(&self,
251+
id: ast::node_id,
252+
f: &fn(uint) -> bool) -> bool {
253+
//! Iterates through each bit in the gen set for `id`.
254+
if !self.nodeid_to_bitset.contains_key(&id) {
255+
return true;
256+
}
257+
let (start, end) = self.compute_id_range_frozen(id);
258+
let gens = vec::slice(self.gens, start, end);
259+
debug!("each_gen_bit(id=%?, gens=%s)",
260+
id, bits_to_str(gens));
261+
self.each_bit(gens, f)
262+
}
263+
213264
fn each_bit(&self,
214265
words: &[uint],
215266
f: &fn(uint) -> bool) -> bool {
@@ -285,8 +336,8 @@ impl<O:DataFlowOperator+Copy+'static> DataFlowContext<O> {
285336
pprust::node_pat(ps, pat) => (ps, pat.id)
286337
};
287338

288-
if id >= self.id_range.min || id < self.id_range.max {
289-
let (start, end) = self.compute_id_range(id);
339+
if self.nodeid_to_bitset.contains_key(&id) {
340+
let (start, end) = self.compute_id_range_frozen(id);
290341
let on_entry = vec::slice(self.on_entry, start, end);
291342
let entry_str = bits_to_str(on_entry);
292343

0 commit comments

Comments
 (0)