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.
This commit is contained in:
commit
7502b4cd6b
3 changed files with 55 additions and 104 deletions
|
@ -172,7 +172,7 @@ impl<'a> CheckLoanCtxt<'a> {
|
||||||
//! are issued for future scopes and thus they may have been
|
//! are issued for future scopes and thus they may have been
|
||||||
//! *issued* but not yet be in effect.
|
//! *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];
|
let loan = &self.all_loans[loan_index];
|
||||||
op(loan)
|
op(loan)
|
||||||
})
|
})
|
||||||
|
@ -271,7 +271,7 @@ impl<'a> CheckLoanCtxt<'a> {
|
||||||
//! we encounter `scope_id`.
|
//! we encounter `scope_id`.
|
||||||
|
|
||||||
let mut result = Vec::new();
|
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);
|
result.push(loan_index);
|
||||||
true
|
true
|
||||||
});
|
});
|
||||||
|
|
|
@ -576,7 +576,7 @@ impl<'a> FlowedMoveData<'a> {
|
||||||
* Iterates through each path moved by `id`
|
* 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 = self.move_data.moves.borrow();
|
||||||
let move = move.get(index);
|
let move = move.get(index);
|
||||||
let moved_path = move.path;
|
let moved_path = move.path;
|
||||||
|
@ -592,7 +592,7 @@ impl<'a> FlowedMoveData<'a> {
|
||||||
|
|
||||||
let mut ret = None;
|
let mut ret = None;
|
||||||
for loan_path_index in self.move_data.path_map.borrow().find(&*loan_path).iter() {
|
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 = self.move_data.moves.borrow();
|
||||||
let move = move.get(move_index);
|
let move = move.get(move_index);
|
||||||
if move.path == **loan_path_index {
|
if move.path == **loan_path_index {
|
||||||
|
@ -637,7 +637,7 @@ impl<'a> FlowedMoveData<'a> {
|
||||||
|
|
||||||
let mut ret = true;
|
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 = self.move_data.moves.borrow();
|
||||||
let move = move.get(index);
|
let move = move.get(index);
|
||||||
let moved_path = move.path;
|
let moved_path = move.path;
|
||||||
|
@ -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 = self.move_data.var_assignments.borrow();
|
||||||
let assignment = assignment.get(index);
|
let assignment = assignment.get(index);
|
||||||
if assignment.path == loan_path_index && !f(assignment) {
|
if assignment.path == loan_path_index && !f(assignment) {
|
||||||
|
|
|
@ -48,9 +48,6 @@ pub struct DataFlowContext<'a, O> {
|
||||||
/// equal to bits_per_id/uint::BITS rounded up.
|
/// equal to bits_per_id/uint::BITS rounded up.
|
||||||
words_per_id: uint,
|
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
|
// mapping from node to cfg node index
|
||||||
// FIXME (#6298): Shouldn't this go with CFG?
|
// FIXME (#6298): Shouldn't this go with CFG?
|
||||||
nodeid_to_index: NodeMap<CFGIndex>,
|
nodeid_to_index: NodeMap<CFGIndex>,
|
||||||
|
@ -98,58 +95,7 @@ fn to_cfgidx_or_die(id: ast::NodeId, index: &NodeMap<CFGIndex>) -> CFGIndex {
|
||||||
impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
fn has_bitset_for_nodeid(&self, n: ast::NodeId) -> bool {
|
fn has_bitset_for_nodeid(&self, n: ast::NodeId) -> bool {
|
||||||
assert!(n != ast::DUMMY_NODE_ID);
|
assert!(n != ast::DUMMY_NODE_ID);
|
||||||
match self.nodeid_to_index.find(&n) {
|
self.nodeid_to_index.contains_key(&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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -165,8 +111,9 @@ impl<'a, O:DataFlowOperator> pprust::PpAnn for DataFlowContext<'a, O> {
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.has_bitset_for_nodeid(id) {
|
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 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 on_entry = self.on_entry.slice(start, end);
|
||||||
let entry_str = bits_to_string(on_entry);
|
let entry_str = bits_to_string(on_entry);
|
||||||
|
|
||||||
|
@ -243,14 +190,19 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
id_range: IdRange,
|
id_range: IdRange,
|
||||||
bits_per_id: uint) -> DataFlowContext<'a, O> {
|
bits_per_id: uint) -> DataFlowContext<'a, O> {
|
||||||
let words_per_id = (bits_per_id + uint::BITS - 1) / uint::BITS;
|
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={:?}, \
|
debug!("DataFlowContext::new(analysis_name: {:s}, id_range={:?}, \
|
||||||
bits_per_id={:?}, words_per_id={:?})",
|
bits_per_id={:?}, words_per_id={:?}) \
|
||||||
analysis_name, id_range, 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 entry = if oper.initial_value() { uint::MAX } else {0};
|
||||||
let kills = Vec::new();
|
|
||||||
let on_entry = Vec::new();
|
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);
|
let nodeid_to_index = build_nodeid_to_index(decl, cfg);
|
||||||
|
|
||||||
|
@ -258,7 +210,6 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
analysis_name: analysis_name,
|
analysis_name: analysis_name,
|
||||||
words_per_id: words_per_id,
|
words_per_id: words_per_id,
|
||||||
index_to_bitset: Vec::new(),
|
|
||||||
nodeid_to_index: nodeid_to_index,
|
nodeid_to_index: nodeid_to_index,
|
||||||
bits_per_id: bits_per_id,
|
bits_per_id: bits_per_id,
|
||||||
oper: oper,
|
oper: oper,
|
||||||
|
@ -273,6 +224,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
debug!("{:s} add_gen(id={:?}, bit={:?})",
|
debug!("{:s} add_gen(id={:?}, bit={:?})",
|
||||||
self.analysis_name, id, bit);
|
self.analysis_name, id, bit);
|
||||||
assert!(self.nodeid_to_index.contains_key(&id));
|
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 cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
|
||||||
let (start, end) = self.compute_id_range(cfgidx);
|
let (start, end) = self.compute_id_range(cfgidx);
|
||||||
let gens = self.gens.mut_slice(start, end);
|
let gens = self.gens.mut_slice(start, end);
|
||||||
|
@ -284,16 +237,20 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
debug!("{:s} add_kill(id={:?}, bit={:?})",
|
debug!("{:s} add_kill(id={:?}, bit={:?})",
|
||||||
self.analysis_name, id, bit);
|
self.analysis_name, id, bit);
|
||||||
assert!(self.nodeid_to_index.contains_key(&id));
|
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 cfgidx = to_cfgidx_or_die(id, &self.nodeid_to_index);
|
||||||
let (start, end) = self.compute_id_range(cfgidx);
|
let (start, end) = self.compute_id_range(cfgidx);
|
||||||
let kills = self.kills.mut_slice(start, end);
|
let kills = self.kills.mut_slice(start, end);
|
||||||
set_bit(kills, bit);
|
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`
|
//! Applies the gen and kill sets for `cfgidx` to `bits`
|
||||||
debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
|
debug!("{:s} apply_gen_kill(cfgidx={}, bits={}) [before]",
|
||||||
self.analysis_name, cfgidx, mut_bits_to_string(bits));
|
self.analysis_name, cfgidx, mut_bits_to_string(bits));
|
||||||
|
assert!(self.bits_per_id > 0);
|
||||||
|
|
||||||
let (start, end) = self.compute_id_range(cfgidx);
|
let (start, end) = self.compute_id_range(cfgidx);
|
||||||
let gens = self.gens.slice(start, end);
|
let gens = self.gens.slice(start, end);
|
||||||
bitwise(bits, gens, &Union);
|
bitwise(bits, gens, &Union);
|
||||||
|
@ -304,30 +261,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
self.analysis_name, cfgidx, mut_bits_to_string(bits));
|
self.analysis_name, cfgidx, mut_bits_to_string(bits));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_gen_kill_frozen(&self, cfgidx: CFGIndex, bits: &mut [uint]) {
|
fn compute_id_range(&self, cfgidx: CFGIndex) -> (uint, uint) {
|
||||||
//! Applies the gen and kill sets for `cfgidx` to `bits`
|
let n = cfgidx.node_id();
|
||||||
//! 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 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));
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
let start = n * self.words_per_id;
|
let start = n * self.words_per_id;
|
||||||
let end = start + self.words_per_id;
|
let end = start + self.words_per_id;
|
||||||
|
|
||||||
|
@ -340,10 +275,10 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn each_bit_on_entry_frozen(&self,
|
pub fn each_bit_on_entry(&self,
|
||||||
id: ast::NodeId,
|
id: ast::NodeId,
|
||||||
f: |uint| -> bool)
|
f: |uint| -> bool)
|
||||||
-> bool {
|
-> bool {
|
||||||
//! Iterates through each bit that is set on entry to `id`.
|
//! Iterates through each bit that is set on entry to `id`.
|
||||||
//! Only useful after `propagate()` has been called.
|
//! Only useful after `propagate()` has been called.
|
||||||
if !self.has_bitset_for_nodeid(id) {
|
if !self.has_bitset_for_nodeid(id) {
|
||||||
|
@ -360,17 +295,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
-> bool {
|
-> bool {
|
||||||
//! Iterates through each bit that is set on entry/exit to `cfgidx`.
|
//! Iterates through each bit that is set on entry/exit to `cfgidx`.
|
||||||
//! Only useful after `propagate()` has been called.
|
//! 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;
|
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 on_entry = self.on_entry.slice(start, end);
|
||||||
let temp_bits;
|
let temp_bits;
|
||||||
let slice = match e {
|
let slice = match e {
|
||||||
Entry => on_entry,
|
Entry => on_entry,
|
||||||
Exit => {
|
Exit => {
|
||||||
let mut t = on_entry.to_vec();
|
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 = t;
|
||||||
temp_bits.as_slice()
|
temp_bits.as_slice()
|
||||||
}
|
}
|
||||||
|
@ -380,15 +319,21 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
self.each_bit(slice, f)
|
self.each_bit(slice, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn each_gen_bit_frozen(&self, id: ast::NodeId, f: |uint| -> bool)
|
pub fn each_gen_bit(&self, id: ast::NodeId, f: |uint| -> bool)
|
||||||
-> bool {
|
-> bool {
|
||||||
//! Iterates through each bit in the gen set for `id`.
|
//! Iterates through each bit in the gen set for `id`.
|
||||||
//! Only useful after `propagate()` has been called.
|
|
||||||
if !self.has_bitset_for_nodeid(id) {
|
if !self.has_bitset_for_nodeid(id) {
|
||||||
return true;
|
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 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);
|
let gens = self.gens.slice(start, end);
|
||||||
debug!("{:s} each_gen_bit(id={:?}, gens={})",
|
debug!("{:s} each_gen_bit(id={:?}, gens={})",
|
||||||
self.analysis_name, id, bits_to_string(gens));
|
self.analysis_name, id, bits_to_string(gens));
|
||||||
|
@ -397,6 +342,8 @@ impl<'a, O:DataFlowOperator> DataFlowContext<'a, O> {
|
||||||
|
|
||||||
fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
|
fn each_bit(&self, words: &[uint], f: |uint| -> bool) -> bool {
|
||||||
//! Helper for iterating over the bits in a bit set.
|
//! 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() {
|
for (word_index, &word) in words.iter().enumerate() {
|
||||||
if word != 0 {
|
if word != 0 {
|
||||||
|
@ -527,6 +474,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||||
in_out: &mut [uint]) {
|
in_out: &mut [uint]) {
|
||||||
debug!("DataFlowContext::walk_cfg(in_out={}) {:s}",
|
debug!("DataFlowContext::walk_cfg(in_out={}) {:s}",
|
||||||
bits_to_string(in_out), self.dfcx.analysis_name);
|
bits_to_string(in_out), self.dfcx.analysis_name);
|
||||||
|
assert!(self.dfcx.bits_per_id > 0);
|
||||||
|
|
||||||
cfg.graph.each_node(|node_index, node| {
|
cfg.graph.each_node(|node_index, node| {
|
||||||
debug!("DataFlowContext::walk_cfg idx={} id={} begin in_out={}",
|
debug!("DataFlowContext::walk_cfg idx={} id={} begin in_out={}",
|
||||||
node_index, node.data.id, bits_to_string(in_out));
|
node_index, node.data.id, bits_to_string(in_out));
|
||||||
|
@ -570,6 +519,8 @@ impl<'a, 'b, O:DataFlowOperator> PropagationContext<'a, 'b, O> {
|
||||||
let cfgidx = edge.target();
|
let cfgidx = edge.target();
|
||||||
debug!("{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})",
|
debug!("{:s} propagate_bits_into_entry_set_for(pred_bits={}, {} to {})",
|
||||||
self.dfcx.analysis_name, bits_to_string(pred_bits), source, cfgidx);
|
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 (start, end) = self.dfcx.compute_id_range(cfgidx);
|
||||||
let changed = {
|
let changed = {
|
||||||
// (scoping mutable borrow of self.dfcx.on_entry)
|
// (scoping mutable borrow of self.dfcx.on_entry)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue