提交 9b8b8c6a 编写于 作者: F Felix S. Klock II

Move `DataFlowState::{each_bit,interpret_set}` method definitions to parent module.

Refactored `each_bit`, which traverses a `IdxSet`, so that the bulk of
its implementation lives in `rustc_data_structures`.
上级 3ef1afcf
......@@ -153,4 +153,38 @@ pub fn union(&mut self, other: &IdxSet<T>) -> bool {
pub fn subtract(&mut self, other: &IdxSet<T>) -> bool {
bitwise(self.words_mut(), other.words(), &Subtract)
}
/// Calls `f` on each index value held in this set, up to the
/// bound `max_bits` on the size of universe of indexes.
pub fn each_bit<F>(&self, max_bits: usize, f: F) where F: FnMut(T) {
each_bit(self, max_bits, f)
}
}
fn each_bit<T: Idx, F>(words: &IdxSet<T>, max_bits: usize, mut f: F) where F: FnMut(T) {
let usize_bits: usize = mem::size_of::<usize>() * 8;
for (word_index, &word) in words.words().iter().enumerate() {
if word != 0 {
let base_index = word_index * usize_bits;
for offset in 0..usize_bits {
let bit = 1 << offset;
if (word & bit) != 0 {
// NB: we round up the total number of bits
// that we store in any given bit set so that
// it is an even multiple of usize::BITS. This
// means that there may be some stray bits at
// the end that do not correspond to any
// actual value; that's why we first check
// that we are in range of bits_per_block.
let bit_index = base_index + offset as usize;
if bit_index >= max_bits {
return;
} else {
f(Idx::new(bit_index));
}
}
}
}
}
}
......@@ -13,7 +13,6 @@
use syntax::ast::NodeId;
use rustc::mir::{BasicBlock, Mir};
use rustc_data_structures::bitslice::bits_to_string;
use rustc_data_structures::indexed_set::{IdxSet};
use rustc_data_structures::indexed_vec::Idx;
use dot;
......@@ -24,7 +23,6 @@
use std::io;
use std::io::prelude::*;
use std::marker::PhantomData;
use std::mem;
use std::path::Path;
use util;
......@@ -32,54 +30,6 @@
use super::{BitDenotation, DataflowState};
use super::DataflowBuilder;
impl<O: BitDenotation> DataflowState<O> {
fn each_bit<F>(&self, words: &IdxSet<O::Idx>, mut f: F)
where F: FnMut(O::Idx) {
//! Helper for iterating over the bits in a bitvector.
let bits_per_block = self.operator.bits_per_block();
let usize_bits: usize = mem::size_of::<usize>() * 8;
for (word_index, &word) in words.words().iter().enumerate() {
if word != 0 {
let base_index = word_index * usize_bits;
for offset in 0..usize_bits {
let bit = 1 << offset;
if (word & bit) != 0 {
// NB: we round up the total number of bits
// that we store in any given bit set so that
// it is an even multiple of usize::BITS. This
// means that there may be some stray bits at
// the end that do not correspond to any
// actual value; that's why we first check
// that we are in range of bits_per_block.
let bit_index = base_index + offset as usize;
if bit_index >= bits_per_block {
return;
} else {
f(O::Idx::new(bit_index));
}
}
}
}
}
}
pub fn interpret_set<'c, P>(&self,
o: &'c O,
words: &IdxSet<O::Idx>,
render_idx: &P)
-> Vec<&'c Debug>
where P: Fn(&O, O::Idx) -> &Debug
{
let mut v = Vec::new();
self.each_bit(words, |i| {
v.push(render_idx(o, i));
});
v
}
}
pub trait MirWithFlowState<'tcx> {
type BD: BitDenotation;
fn node_id(&self) -> NodeId;
......
......@@ -293,6 +293,28 @@ pub struct DataflowState<O: BitDenotation>
pub(crate) operator: O,
}
impl<O: BitDenotation> DataflowState<O> {
pub fn each_bit<F>(&self, words: &IdxSet<O::Idx>, f: F) where F: FnMut(O::Idx)
{
let bits_per_block = self.operator.bits_per_block();
words.each_bit(bits_per_block, f)
}
pub fn interpret_set<'c, P>(&self,
o: &'c O,
words: &IdxSet<O::Idx>,
render_idx: &P)
-> Vec<&'c Debug>
where P: Fn(&O, O::Idx) -> &Debug
{
let mut v = Vec::new();
self.each_bit(words, |i| {
v.push(render_idx(o, i));
});
v
}
}
#[derive(Debug)]
pub struct AllSets<E: Idx> {
/// Analysis bitwidth for each block.
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册