Skip to content

BitSlice fixes #52335

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

Merged
merged 3 commits into from
Jul 17, 2018
Merged
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
28 changes: 11 additions & 17 deletions src/librustc_data_structures/bitslice.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ impl BitSlice for [Word] {
fn clear_bit(&mut self, idx: usize) -> bool {
let words = self;
debug!("clear_bit: words={} idx={}",
bits_to_string(words, words.len() * mem::size_of::<Word>()), bit_str(idx));
bits_to_string(words, words.len() * mem::size_of::<Word>() * 8), idx);
let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
debug!("word={} bit_in_word={} bit_mask=0x{:x}", word, bit_in_word, bit_mask);
let oldv = words[word];
let newv = oldv & !bit_mask;
words[word] = newv;
Expand All @@ -42,7 +42,7 @@ impl BitSlice for [Word] {
fn set_bit(&mut self, idx: usize) -> bool {
let words = self;
debug!("set_bit: words={} idx={}",
bits_to_string(words, words.len() * mem::size_of::<Word>()), bit_str(idx));
bits_to_string(words, words.len() * mem::size_of::<Word>() * 8), idx);
let BitLookup { word, bit_in_word, bit_mask } = bit_lookup(idx);
debug!("word={} bit_in_word={} bit_mask={}", word, bit_in_word, bit_mask);
let oldv = words[word];
Expand Down Expand Up @@ -78,13 +78,6 @@ fn bit_lookup(bit: usize) -> BitLookup {
BitLookup { word: word, bit_in_word: bit_in_word, bit_mask: bit_mask }
}


fn bit_str(bit: Word) -> String {
let byte = bit >> 3;
let lobits = 1 << (bit & 0b111);
format!("[{}:{}-{:02x}]", bit, byte, lobits)
}

pub fn bits_to_string(words: &[Word], bits: usize) -> String {
let mut result = String::new();
let mut sep = '[';
Expand All @@ -95,7 +88,7 @@ pub fn bits_to_string(words: &[Word], bits: usize) -> String {
let mut i = 0;
for &word in words.iter() {
let mut v = word;
loop { // for each byte in `v`:
for _ in 0..mem::size_of::<Word>() { // for each byte in `v`:
let remain = bits - i;
// If less than a byte remains, then mask just that many bits.
let mask = if remain <= 8 { (1 << remain) - 1 } else { 0xFF };
Expand All @@ -110,14 +103,15 @@ pub fn bits_to_string(words: &[Word], bits: usize) -> String {
i += 8;
sep = '-';
}
sep = '|';
}
result.push(']');
return result
}

#[inline]
pub fn bitwise<Op:BitwiseOperator>(out_vec: &mut [usize],
in_vec: &[usize],
pub fn bitwise<Op:BitwiseOperator>(out_vec: &mut [Word],
in_vec: &[Word],
op: &Op) -> bool {
assert_eq!(out_vec.len(), in_vec.len());
let mut changed = false;
Expand All @@ -132,21 +126,21 @@ pub fn bitwise<Op:BitwiseOperator>(out_vec: &mut [usize],

pub trait BitwiseOperator {
/// Applies some bit-operation pointwise to each of the bits in the two inputs.
fn join(&self, pred1: usize, pred2: usize) -> usize;
fn join(&self, pred1: Word, pred2: Word) -> Word;
}

pub struct Intersect;
impl BitwiseOperator for Intersect {
#[inline]
fn join(&self, a: usize, b: usize) -> usize { a & b }
fn join(&self, a: Word, b: Word) -> Word { a & b }
}
pub struct Union;
impl BitwiseOperator for Union {
#[inline]
fn join(&self, a: usize, b: usize) -> usize { a | b }
fn join(&self, a: Word, b: Word) -> Word { a | b }
}
pub struct Subtract;
impl BitwiseOperator for Subtract {
#[inline]
fn join(&self, a: usize, b: usize) -> usize { a & !b }
fn join(&self, a: Word, b: Word) -> Word { a & !b }
}
2 changes: 1 addition & 1 deletion src/librustc_mir/dataflow/impls/borrowed_locals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> {

impl<'a, 'tcx> BitwiseOperator for HaveBeenBorrowedLocals<'a, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/librustc_mir/dataflow/impls/borrows.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use rustc::ty::TyCtxt;
use rustc::ty::{RegionKind, RegionVid};
use rustc::ty::RegionKind::ReScope;

use rustc_data_structures::bitslice::BitwiseOperator;
use rustc_data_structures::bitslice::{BitwiseOperator, Word};
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_data_structures::indexed_set::IdxSet;
use rustc_data_structures::indexed_vec::IndexVec;
Expand Down Expand Up @@ -370,7 +370,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for Borrows<'a, 'gcx, 'tcx> {

impl<'a, 'gcx, 'tcx> BitwiseOperator for Borrows<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // union effects of preds when computing reservations
}
}
Expand Down
12 changes: 6 additions & 6 deletions src/librustc_mir/dataflow/impls/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

use rustc::ty::TyCtxt;
use rustc::mir::{self, Mir, Location};
use rustc_data_structures::bitslice::{BitwiseOperator};
use rustc_data_structures::bitslice::{BitwiseOperator, Word};
use rustc_data_structures::indexed_set::{IdxSet};
use rustc_data_structures::indexed_vec::Idx;

Expand Down Expand Up @@ -663,35 +663,35 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedPlaces<'a, 'gcx, 'tcx> {

impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeInitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
}
}

impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeUninitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
}
}

impl<'a, 'gcx, 'tcx> BitwiseOperator for DefinitelyInitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 & pred2 // "definitely" means we intersect effects of both preds
}
}

impl<'a, 'gcx, 'tcx> BitwiseOperator for MovingOutStatements<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // moves from both preds are in scope
}
}

impl<'a, 'gcx, 'tcx> BitwiseOperator for EverInitializedPlaces<'a, 'gcx, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // inits from both preds are in scope
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/dataflow/impls/storage_liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ impl<'a, 'tcx> BitDenotation for MaybeStorageLive<'a, 'tcx> {

impl<'a, 'tcx> BitwiseOperator for MaybeStorageLive<'a, 'tcx> {
#[inline]
fn join(&self, pred1: usize, pred2: usize) -> usize {
fn join(&self, pred1: Word, pred2: Word) -> Word {
pred1 | pred2 // "maybe" means we union effects of both preds
}
}
Expand Down
24 changes: 7 additions & 17 deletions src/librustc_mir/dataflow/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use syntax::ast::{self, MetaItem};

use rustc_data_structures::indexed_set::{IdxSet, IdxSetBuf};
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
use rustc_data_structures::bitslice::{bitwise, BitwiseOperator, Word};
use rustc_data_structures::work_queue::WorkQueue;

use rustc::ty::{self, TyCtxt};
Expand Down Expand Up @@ -467,7 +467,7 @@ pub struct AllSets<E: Idx> {
bits_per_block: usize,

/// Number of words associated with each block entry
/// equal to bits_per_block / usize::BITS, rounded up.
/// equal to bits_per_block / (mem::size_of::<Word> * 8), rounded up.
words_per_block: usize,

/// For each block, bits generated by executing the statements in
Expand Down Expand Up @@ -734,9 +734,11 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
dead_unwinds: &'a IdxSet<mir::BasicBlock>,
denotation: D) -> Self where D: InitialFlow {
let bits_per_block = denotation.bits_per_block();
let usize_bits = mem::size_of::<usize>() * 8;
let words_per_block = (bits_per_block + usize_bits - 1) / usize_bits;
let num_overall = Self::num_bits_overall(mir, bits_per_block);
let bits_per_word = mem::size_of::<Word>() * 8;
let words_per_block = (bits_per_block + bits_per_word - 1) / bits_per_word;
let bits_per_block_rounded_up = words_per_block * bits_per_word; // a multiple of word size
let num_blocks = mir.basic_blocks().len();
let num_overall = num_blocks * bits_per_block_rounded_up;

let zeroes = Bits::new(IdxSetBuf::new_empty(num_overall));
let on_entry = Bits::new(if D::bottom_value() {
Expand Down Expand Up @@ -774,18 +776,6 @@ impl<'a, 'tcx, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
}
}
}

fn num_bits_overall(mir: &Mir, bits_per_block: usize) -> usize {
let usize_bits = mem::size_of::<usize>() * 8;
let words_per_block = (bits_per_block + usize_bits - 1) / usize_bits;

// (now rounded up to multiple of word size)
let bits_per_block = words_per_block * usize_bits;

let num_blocks = mir.basic_blocks().len();
let num_overall = num_blocks * bits_per_block;
num_overall
}
}

impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D> where D: BitDenotation
Expand Down