Skip to content

Commit 4f08307

Browse files
committed
Auto merge of rust-lang#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`
2 parents 5413f7d + 6048182 commit 4f08307

File tree

1 file changed

+61
-47
lines changed

1 file changed

+61
-47
lines changed

compiler/rustc_index/src/bit_set.rs

Lines changed: 61 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -800,27 +800,39 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
800800
// words, and this happens often enough that it's a
801801
// performance win. Also, we only need to operate on the
802802
// in-use words, hence the slicing.
803-
let op = |a, b| a | b;
804803
let num_words = num_words(chunk_domain_size as usize);
805-
if bitwise_changes(
804+
805+
// If both sides are the same, nothing will change. This
806+
// case is very common and it's a pretty fast check, so
807+
// it's a performance win to do it.
808+
if self_chunk_words[0..num_words] == other_chunk_words[0..num_words] {
809+
continue;
810+
}
811+
812+
// Do a more precise "will anything change?" test. Also a
813+
// performance win.
814+
let op = |a, b| a | b;
815+
if !bitwise_changes(
806816
&self_chunk_words[0..num_words],
807817
&other_chunk_words[0..num_words],
808818
op,
809819
) {
810-
let self_chunk_words = Rc::make_mut(self_chunk_words);
811-
let has_changed = bitwise(
812-
&mut self_chunk_words[0..num_words],
813-
&other_chunk_words[0..num_words],
814-
op,
815-
);
816-
debug_assert!(has_changed);
817-
*self_chunk_count =
818-
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
819-
if *self_chunk_count == chunk_domain_size {
820-
*self_chunk = Ones;
821-
}
822-
changed = true;
820+
continue;
821+
}
822+
823+
// If we reach here, `self_chunk_words` is definitely changing.
824+
let self_chunk_words = Rc::make_mut(self_chunk_words);
825+
let has_changed = bitwise(
826+
&mut self_chunk_words[0..num_words],
827+
&other_chunk_words[0..num_words],
828+
op,
829+
);
830+
debug_assert!(has_changed);
831+
*self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
832+
if *self_chunk_count == chunk_domain_size {
833+
*self_chunk = Ones;
823834
}
835+
changed = true;
824836
}
825837
}
826838
}
@@ -874,28 +886,29 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
874886
Mixed(self_chunk_count, self_chunk_words),
875887
Mixed(_other_chunk_count, other_chunk_words),
876888
) => {
877-
// See [`<Self as BitRelations<ChunkedBitSet<T>>>::union`] for the explanation
878-
let op = |a: u64, b: u64| a & !b;
889+
// See `ChunkedBitSet::union` for details on what is happening here.
879890
let num_words = num_words(chunk_domain_size as usize);
880-
if bitwise_changes(
891+
let op = |a: u64, b: u64| a & !b;
892+
if !bitwise_changes(
881893
&self_chunk_words[0..num_words],
882894
&other_chunk_words[0..num_words],
883895
op,
884896
) {
885-
let self_chunk_words = Rc::make_mut(self_chunk_words);
886-
let has_changed = bitwise(
887-
&mut self_chunk_words[0..num_words],
888-
&other_chunk_words[0..num_words],
889-
op,
890-
);
891-
debug_assert!(has_changed);
892-
*self_chunk_count =
893-
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
894-
if *self_chunk_count == 0 {
895-
*self_chunk = Zeros;
896-
}
897-
changed = true;
897+
continue;
898898
}
899+
900+
let self_chunk_words = Rc::make_mut(self_chunk_words);
901+
let has_changed = bitwise(
902+
&mut self_chunk_words[0..num_words],
903+
&other_chunk_words[0..num_words],
904+
op,
905+
);
906+
debug_assert!(has_changed);
907+
*self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
908+
if *self_chunk_count == 0 {
909+
*self_chunk = Zeros;
910+
}
911+
changed = true;
899912
}
900913
}
901914
}
@@ -931,28 +944,29 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
931944
Mixed(self_chunk_count, self_chunk_words),
932945
Mixed(_other_chunk_count, other_chunk_words),
933946
) => {
934-
// See [`<Self as BitRelations<ChunkedBitSet<T>>>::union`] for the explanation
935-
let op = |a, b| a & b;
947+
// See `ChunkedBitSet::union` for details on what is happening here.
936948
let num_words = num_words(chunk_domain_size as usize);
937-
if bitwise_changes(
949+
let op = |a, b| a & b;
950+
if !bitwise_changes(
938951
&self_chunk_words[0..num_words],
939952
&other_chunk_words[0..num_words],
940953
op,
941954
) {
942-
let self_chunk_words = Rc::make_mut(self_chunk_words);
943-
let has_changed = bitwise(
944-
&mut self_chunk_words[0..num_words],
945-
&other_chunk_words[0..num_words],
946-
op,
947-
);
948-
debug_assert!(has_changed);
949-
*self_chunk_count =
950-
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
951-
if *self_chunk_count == 0 {
952-
*self_chunk = Zeros;
953-
}
954-
changed = true;
955+
continue;
955956
}
957+
958+
let self_chunk_words = Rc::make_mut(self_chunk_words);
959+
let has_changed = bitwise(
960+
&mut self_chunk_words[0..num_words],
961+
&other_chunk_words[0..num_words],
962+
op,
963+
);
964+
debug_assert!(has_changed);
965+
*self_chunk_count = count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
966+
if *self_chunk_count == 0 {
967+
*self_chunk = Zeros;
968+
}
969+
changed = true;
956970
}
957971
}
958972
}

0 commit comments

Comments
 (0)