Auto merge of #147619 - nnethercote:union-ne-check, r=Zalathar
Add a `!=` check to `ChunkedBitSet::union`. It's a big speed win for `cranelift-codegen-0.119.0`. r? `@Zalathar`
This commit is contained in:
commit
4f08307f6e
1 changed files with 61 additions and 47 deletions
|
|
@ -800,27 +800,39 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
|
|||
// words, and this happens often enough that it's a
|
||||
// performance win. Also, we only need to operate on the
|
||||
// in-use words, hence the slicing.
|
||||
let op = |a, b| a | b;
|
||||
let num_words = num_words(chunk_domain_size as usize);
|
||||
if bitwise_changes(
|
||||
|
||||
// If both sides are the same, nothing will change. This
|
||||
// case is very common and it's a pretty fast check, so
|
||||
// it's a performance win to do it.
|
||||
if self_chunk_words[0..num_words] == other_chunk_words[0..num_words] {
|
||||
continue;
|
||||
}
|
||||
|
||||
// Do a more precise "will anything change?" test. Also a
|
||||
// performance win.
|
||||
let op = |a, b| a | b;
|
||||
if !bitwise_changes(
|
||||
&self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
) {
|
||||
let self_chunk_words = Rc::make_mut(self_chunk_words);
|
||||
let has_changed = bitwise(
|
||||
&mut self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
);
|
||||
debug_assert!(has_changed);
|
||||
*self_chunk_count =
|
||||
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
|
||||
if *self_chunk_count == chunk_domain_size {
|
||||
*self_chunk = Ones;
|
||||
}
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
// If we reach here, `self_chunk_words` is definitely changing.
|
||||
let self_chunk_words = Rc::make_mut(self_chunk_words);
|
||||
let has_changed = bitwise(
|
||||
&mut self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
);
|
||||
debug_assert!(has_changed);
|
||||
*self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
|
||||
if *self_chunk_count == chunk_domain_size {
|
||||
*self_chunk = Ones;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -874,28 +886,29 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
|
|||
Mixed(self_chunk_count, self_chunk_words),
|
||||
Mixed(_other_chunk_count, other_chunk_words),
|
||||
) => {
|
||||
// See [`<Self as BitRelations<ChunkedBitSet<T>>>::union`] for the explanation
|
||||
let op = |a: u64, b: u64| a & !b;
|
||||
// See `ChunkedBitSet::union` for details on what is happening here.
|
||||
let num_words = num_words(chunk_domain_size as usize);
|
||||
if bitwise_changes(
|
||||
let op = |a: u64, b: u64| a & !b;
|
||||
if !bitwise_changes(
|
||||
&self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
) {
|
||||
let self_chunk_words = Rc::make_mut(self_chunk_words);
|
||||
let has_changed = bitwise(
|
||||
&mut self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
);
|
||||
debug_assert!(has_changed);
|
||||
*self_chunk_count =
|
||||
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
|
||||
if *self_chunk_count == 0 {
|
||||
*self_chunk = Zeros;
|
||||
}
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
let self_chunk_words = Rc::make_mut(self_chunk_words);
|
||||
let has_changed = bitwise(
|
||||
&mut self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
);
|
||||
debug_assert!(has_changed);
|
||||
*self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
|
||||
if *self_chunk_count == 0 {
|
||||
*self_chunk = Zeros;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -931,28 +944,29 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
|
|||
Mixed(self_chunk_count, self_chunk_words),
|
||||
Mixed(_other_chunk_count, other_chunk_words),
|
||||
) => {
|
||||
// See [`<Self as BitRelations<ChunkedBitSet<T>>>::union`] for the explanation
|
||||
let op = |a, b| a & b;
|
||||
// See `ChunkedBitSet::union` for details on what is happening here.
|
||||
let num_words = num_words(chunk_domain_size as usize);
|
||||
if bitwise_changes(
|
||||
let op = |a, b| a & b;
|
||||
if !bitwise_changes(
|
||||
&self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
) {
|
||||
let self_chunk_words = Rc::make_mut(self_chunk_words);
|
||||
let has_changed = bitwise(
|
||||
&mut self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
);
|
||||
debug_assert!(has_changed);
|
||||
*self_chunk_count =
|
||||
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
|
||||
if *self_chunk_count == 0 {
|
||||
*self_chunk = Zeros;
|
||||
}
|
||||
changed = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
let self_chunk_words = Rc::make_mut(self_chunk_words);
|
||||
let has_changed = bitwise(
|
||||
&mut self_chunk_words[0..num_words],
|
||||
&other_chunk_words[0..num_words],
|
||||
op,
|
||||
);
|
||||
debug_assert!(has_changed);
|
||||
*self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
|
||||
if *self_chunk_count == 0 {
|
||||
*self_chunk = Zeros;
|
||||
}
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue