diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index d730ef58deba6..892c408963abe 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1699,14 +1699,15 @@ impl BitMatrix { let (read_start, read_end) = self.range(read); let (write_start, write_end) = self.range(write); let words = &mut self.words[..]; - let mut changed = false; + let mut changed = 0; for (read_index, write_index) in iter::zip(read_start..read_end, write_start..write_end) { let word = words[write_index]; let new_word = word | words[read_index]; words[write_index] = new_word; - changed |= word != new_word; + // See `bitwise` for the rationale. + changed |= word ^ new_word; } - changed + changed != 0 } /// Adds the bits from `with` to the bits from row `write`, and @@ -1715,14 +1716,7 @@ impl BitMatrix { assert!(write.index() < self.num_rows); assert_eq!(with.domain_size(), self.num_columns); let (write_start, write_end) = self.range(write); - let mut changed = false; - for (read_index, write_index) in iter::zip(0..with.words.len(), write_start..write_end) { - let word = self.words[write_index]; - let new_word = word | with.words[read_index]; - self.words[write_index] = new_word; - changed |= word != new_word; - } - changed + bitwise(&mut self.words[write_start..write_end], &with.words, |a, b| a | b) } /// Sets every cell in `row` to true. diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs index ce1a36cf67021..193479cc59f3a 100644 --- a/compiler/rustc_mir_transform/src/coroutine.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -942,6 +942,7 @@ fn compute_storage_conflicts<'mir, 'tcx>( body, saved_locals: saved_locals, local_conflicts: BitMatrix::from_row_n(&ineligible_locals, body.local_decls.len()), + eligible_storage_live: BitSet::new_empty(body.local_decls.len()), }; requires_storage.visit_reachable_with(body, &mut visitor); @@ -978,6 +979,8 @@ struct StorageConflictVisitor<'mir, 'tcx, 's> { // FIXME(tmandry): Consider using sparse bitsets here once we have good // benchmarks for coroutines. local_conflicts: BitMatrix, + // We keep this bitset as a buffer to avoid reallocating memory. + eligible_storage_live: BitSet, } impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> @@ -1009,19 +1012,19 @@ impl<'mir, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'mir, 'tcx, R> impl StorageConflictVisitor<'_, '_, '_> { fn apply_state(&mut self, flow_state: &BitSet, loc: Location) { // Ignore unreachable blocks. - if self.body.basic_blocks[loc.block].terminator().kind == TerminatorKind::Unreachable { + if let TerminatorKind::Unreachable = self.body.basic_blocks[loc.block].terminator().kind { return; } - let mut eligible_storage_live = flow_state.clone(); - eligible_storage_live.intersect(&**self.saved_locals); + self.eligible_storage_live.clone_from(flow_state); + self.eligible_storage_live.intersect(&**self.saved_locals); - for local in eligible_storage_live.iter() { - self.local_conflicts.union_row_with(&eligible_storage_live, local); + for local in self.eligible_storage_live.iter() { + self.local_conflicts.union_row_with(&self.eligible_storage_live, local); } - if eligible_storage_live.count() > 1 { - trace!("at {:?}, eligible_storage_live={:?}", loc, eligible_storage_live); + if self.eligible_storage_live.count() > 1 { + trace!("at {:?}, eligible_storage_live={:?}", loc, self.eligible_storage_live); } } }