Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

dataflow: removed the CFGIndex to bitset mapping. #15742

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/librustc/middle/borrowck/check_loans.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ impl<'a> CheckLoanCtxt<'a> {
//! are issued for future scopes and thus they may have been
//! *issued* but not yet be in effect.

self.dfcx_loans.each_bit_on_entry_frozen(scope_id, |loan_index| {
self.dfcx_loans.each_bit_on_entry(scope_id, |loan_index| {
let loan = &self.all_loans[loan_index];
op(loan)
})
Expand Down Expand Up @@ -271,7 +271,7 @@ impl<'a> CheckLoanCtxt<'a> {
//! we encounter `scope_id`.

let mut result = Vec::new();
self.dfcx_loans.each_gen_bit_frozen(scope_id, |loan_index| {
self.dfcx_loans.each_gen_bit(scope_id, |loan_index| {
result.push(loan_index);
true
});
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/borrowck/move_data.rs
Original file line number Diff line number Diff line change
Expand Up @@ -576,7 +576,7 @@ impl<'a> FlowedMoveData<'a> {
* Iterates through each path moved by `id`
*/

self.dfcx_moves.each_gen_bit_frozen(id, |index| {
self.dfcx_moves.each_gen_bit(id, |index| {
let move = self.move_data.moves.borrow();
let move = move.get(index);
let moved_path = move.path;
Expand All @@ -592,7 +592,7 @@ impl<'a> FlowedMoveData<'a> {

let mut ret = None;
for loan_path_index in self.move_data.path_map.borrow().find(&*loan_path).iter() {
self.dfcx_moves.each_gen_bit_frozen(id, |move_index| {
self.dfcx_moves.each_gen_bit(id, |move_index| {
let move = self.move_data.moves.borrow();
let move = move.get(move_index);
if move.path == **loan_path_index {
Expand Down Expand Up @@ -637,7 +637,7 @@ impl<'a> FlowedMoveData<'a> {

let mut ret = true;

self.dfcx_moves.each_bit_on_entry_frozen(id, |index| {
self.dfcx_moves.each_bit_on_entry(id, |index| {
let move = self.move_data.moves.borrow();
let move = move.get(index);
let moved_path = move.path;
Expand Down Expand Up @@ -693,7 +693,7 @@ impl<'a> FlowedMoveData<'a> {
}
};

self.dfcx_assign.each_bit_on_entry_frozen(id, |index| {
self.dfcx_assign.each_bit_on_entry(id, |index| {
let assignment = self.move_data.var_assignments.borrow();
let assignment = assignment.get(index);
if assignment.path == loan_path_index && !f(assignment) {
Expand Down
147 changes: 49 additions & 98 deletions src/librustc/middle/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,6 @@ pub struct DataFlowContext<'a, O> {
/// equal to bits_per_id/uint::BITS rounded up.
words_per_id: uint,

// mapping from cfg node index to bitset index.
index_to_bitset: Vec<Option<uint>>,

// mapping from node to cfg node index
// FIXME (#6298): Shouldn't this go with CFG?
nodeid_to_index: NodeMap<CFGIndex>,
Expand Down Expand Up @@ -98,58 +95,7 @@ fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
fn has_bitset_for_nodeid(&self, n: ast::NodeId) -> bool {
assert!(n != ast::DUMMY_NODE_ID);
match self.nodeid_to_index.find(&n) {
None => false,
Some(&cfgidx) => self.has_bitset_for_cfgidx(cfgidx),
}
}
fn has_bitset_for_cfgidx(&self, cfgidx: CFGIndex) -> bool {
let node_id = cfgidx.node_id();
node_id < self.index_to_bitset.len() &&
self.index_to_bitset.get(node_id).is_some()
}
fn get_bitset_index(&self, cfgidx: CFGIndex) -> uint {
let node_id = cfgidx.node_id();
self.index_to_bitset.get(node_id).unwrap()
}
fn get_or_create_bitset_index(&mut self, cfgidx: CFGIndex) -> uint {
assert!(self.words_per_id > 0);
let len = self.gens.len() / self.words_per_id;
let expanded;
let n;
if self.index_to_bitset.len() <= cfgidx.node_id() {
self.index_to_bitset.grow_set(cfgidx.node_id(), &None, Some(len));
expanded = true;
n = len;
} else {
let entry = self.index_to_bitset.get_mut(cfgidx.node_id());
match *entry {
None => {
*entry = Some(len);
expanded = true;
n = len;
}
Some(bitidx) => {
expanded = false;
n = bitidx;
}
}
}
if expanded {
let entry = if self.oper.initial_value() { uint::MAX } else {0};
for _ in range(0, self.words_per_id) {
self.gens.push(0);
self.kills.push(0);
self.on_entry.push(entry);
}
}

let start = n * self.words_per_id;
let end = start + self.words_per_id;
let len = self.gens.len();
assert!(start < len);
assert!(end <= len);
n
self.nodeid_to_index.contains_key(&n)
}
}

Expand All @@ -165,8 +111,9 @@ impl<'a, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, O> {
};

if self.has_bitset_for_nodeid(id) {
assert!(self.bits_per_id > 0);
let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
let (start, end) = self.compute_id_range_frozen(cfgidx);
let (start, end) = self.compute_id_range(cfgidx);
let on_entry = self.on_entry.slice(start, end);
let entry_str = bits_to_string(on_entry);

Expand Down Expand Up @@ -243,22 +190,26 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
id_range: IdRange,
bits_per_id: uint) -> DataFlowContext<'a, O> {
let words_per_id = (bits_per_id + uint::BITS - 1) / uint::BITS;
let num_nodes = cfg.graph.all_nodes().len();

debug!("DataFlowContext::new(analysis_name: {:s}, id_range={:?}, \
bits_per_id={:?}, words_per_id={:?})",
analysis_name, id_range, bits_per_id, words_per_id);
bits_per_id={:?}, words_per_id={:?}) \
num_nodes: {}",
analysis_name, id_range, bits_per_id, words_per_id,
num_nodes);

let gens = Vec::new();
let kills = Vec::new();
let on_entry = Vec::new();
let entry = if oper.initial_value() { uint::MAX } else {0};

let gens = Vec::from_elem(num_nodes * words_per_id, 0);
let kills = Vec::from_elem(num_nodes * words_per_id, 0);
let on_entry = Vec::from_elem(num_nodes * words_per_id, entry);

let nodeid_to_index = build_nodeid_to_index(decl, cfg);

DataFlowContext {
tcx: tcx,
analysis_name: analysis_name,
words_per_id: words_per_id,
index_to_bitset: Vec::new(),
nodeid_to_index: nodeid_to_index,
bits_per_id: bits_per_id,
oper: oper,
Expand All @@ -273,6 +224,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
debug!("{:s} add_gen(id={:?}, bit={:?})",
self.analysis_name, id, bit);
assert!(self.nodeid_to_index.contains_key(&id));
assert!(self.bits_per_id > 0);

let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
let (start, end) = self.compute_id_range(cfgidx);
let gens = self.gens.mut_slice(start, end);
Expand All @@ -284,32 +237,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
debug!("{:s} add_kill(id={:?}, bit={:?})",
self.analysis_name, id, bit);
assert!(self.nodeid_to_index.contains_key(&id));
assert!(self.bits_per_id > 0);

let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
let (start, end) = self.compute_id_range(cfgidx);
let kills = self.kills.mut_slice(start, end);
set_bit(kills, bit);
}

fn apply_gen_kill(&mut self, cfgidx: CFGIndex, bits: &mut [uint]) {
fn apply_gen_kill(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
//! Applies the gen and kill sets for `cfgidx` to `bits`
debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
self.analysis_name, cfgidx, mut_bits_to_string(bits));
let (start, end) = self.compute_id_range(cfgidx);
let gens = self.gens.slice(start, end);
bitwise(bits, gens, &Union);
let kills = self.kills.slice(start, end);
bitwise(bits, kills, &Subtract);

debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [after]",
self.analysis_name, cfgidx, mut_bits_to_string(bits));
}
assert!(self.bits_per_id > 0);

fn apply_gen_kill_frozen(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
//! Applies the gen and kill sets for `cfgidx` to `bits`
//! Only useful after `propagate()` has been called.
debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
self.analysis_name, cfgidx, mut_bits_to_string(bits));
let (start, end) = self.compute_id_range_frozen(cfgidx);
let (start, end) = self.compute_id_range(cfgidx);
let gens = self.gens.slice(start, end);
bitwise(bits, gens, &Union);
let kills = self.kills.slice(start, end);
Expand All @@ -319,15 +261,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
self.analysis_name, cfgidx, mut_bits_to_string(bits));
}

fn compute_id_range_frozen(&self, cfgidx: CFGIndex) -> (uint, uint) {
let n = self.get_bitset_index(cfgidx);
let start = n * self.words_per_id;
let end = start + self.words_per_id;
(start, end)
}

fn compute_id_range(&mut self, cfgidx: CFGIndex) -> (uint, uint) {
let n = self.get_or_create_bitset_index(cfgidx);
fn compute_id_range(&self, cfgidx: CFGIndex) -> (uint, uint) {
let n = cfgidx.node_id();
let start = n * self.words_per_id;
let end = start + self.words_per_id;

Expand All @@ -340,10 +275,10 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
}


pub fn each_bit_on_entry_frozen(&self,
id: ast::NodeId,
f: |uint| -> bool)
-> bool {
pub fn each_bit_on_entry(&self,
id: ast::NodeId,
f: |uint| -> bool)
-> bool {
//! Iterates through each bit that is set on entry to `id`.
//! Only useful after `propagate()` has been called.
if !self.has_bitset_for_nodeid(id) {
Expand All @@ -360,17 +295,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
-> bool {
//! Iterates through each bit that is set on entry/exit to `cfgidx`.
//! Only useful after `propagate()` has been called.
if !self.has_bitset_for_cfgidx(cfgidx) {

if self.bits_per_id == 0 {
// Skip the surprisingly common degenerate case. (Note
// compute_id_range requires self.words_per_id > 0.)
return true;
}
let (start, end) = self.compute_id_range_frozen(cfgidx);

let (start, end) = self.compute_id_range(cfgidx);
let on_entry = self.on_entry.slice(start, end);
let temp_bits;
let slice = match e {
Entry => on_entry,
Exit => {
let mut t = on_entry.to_vec();
self.apply_gen_kill_frozen(cfgidx, t.as_mut_slice());
self.apply_gen_kill(cfgidx, t.as_mut_slice());
temp_bits = t;
temp_bits.as_slice()
}
Expand All @@ -380,15 +319,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
self.each_bit(slice, f)
}

pub fn each_gen_bit_frozen(&self, id: ast::NodeId, f: |uint| -> bool)
-> bool {
pub fn each_gen_bit(&self, id: ast::NodeId, f: |uint| -> bool)
-> bool {
//! Iterates through each bit in the gen set for `id`.
//! Only useful after `propagate()` has been called.
if !self.has_bitset_for_nodeid(id) {
return true;
}

if self.bits_per_id == 0 {
// Skip the surprisingly common degenerate case. (Note
// compute_id_range requires self.words_per_id > 0.)
return true;
}

let cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
let (start, end) = self.compute_id_range_frozen(cfgidx);
let (start, end) = self.compute_id_range(cfgidx);
let gens = self.gens.slice(start, end);
debug!("{:s} each_gen_bit(id={:?}, gens={})",
self.analysis_name, id, bits_to_string(gens));
Expand All @@ -397,6 +342,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {

fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
//! Helper for iterating over the bits in a bit set.
//! Returns false on the first call to `f` that returns false;
//! if all calls to `f` return true, then returns true.

for (word_index, &word) in words.iter().enumerate() {
if word != 0 {
Expand Down Expand Up @@ -527,6 +474,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
in_out: &mut [uint]) {
debug!("DataFlowContext::walk_cfg(in_out={}) {:s}",
bits_to_string(in_out), self.dfcx.analysis_name);
assert!(self.dfcx.bits_per_id > 0);

cfg.graph.each_node(|node_index, node| {
debug!("DataFlowContext::walk_cfg idx={} id={} begin in_out={}",
node_index, node.data.id, bits_to_string(in_out));
Expand Down Expand Up @@ -570,6 +519,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
let cfgidx = edge.target();
debug!("{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})",
self.dfcx.analysis_name, bits_to_string(pred_bits), source, cfgidx);
assert!(self.dfcx.bits_per_id > 0);

let (start, end) = self.dfcx.compute_id_range(cfgidx);
let changed = {
// (scoping mutable borrow of self.dfcx.on_entry)
Expand Down