Skip to content

Commit 8165e10

Browse files
committed
Auto merge of #156046 - Amanieu:move-elimination, r=<try>
[WIP] MIR move elimination pass
2 parents 54f67d2 + a226132 commit 8165e10

14 files changed

Lines changed: 1512 additions & 28 deletions

File tree

compiler/rustc_index/src/interval.rs

Lines changed: 65 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use std::iter::Step;
22
use std::marker::PhantomData;
3-
use std::ops::{Bound, Range, RangeBounds};
3+
use std::ops::{Bound, RangeBounds};
4+
use std::range::RangeInclusive;
45

56
use smallvec::SmallVec;
67

@@ -59,11 +60,14 @@ impl<I: Idx> IntervalSet<I> {
5960
}
6061

6162
/// Iterates through intervals stored in the set, in order.
62-
pub fn iter_intervals(&self) -> impl Iterator<Item = std::ops::Range<I>>
63+
pub fn iter_intervals(&self) -> impl Iterator<Item = RangeInclusive<I>>
6364
where
6465
I: Step,
6566
{
66-
self.map.iter().map(|&(start, end)| I::new(start as usize)..I::new(end as usize + 1))
67+
self.map.iter().map(|&(start, end)| RangeInclusive {
68+
start: I::new(start as usize),
69+
last: I::new(end as usize),
70+
})
6771
}
6872

6973
/// Returns true if we increased the number of elements present.
@@ -164,6 +168,35 @@ impl<I: Idx> IntervalSet<I> {
164168
);
165169
}
166170

171+
/// Specialized version of `insert` when we know that the inserted range is
172+
/// *after* any contained.
173+
pub fn append_range(&mut self, range: impl RangeBounds<I> + Clone) {
174+
let start = inclusive_start(range.clone());
175+
let Some(end) = inclusive_end(self.domain, range) else {
176+
// empty range
177+
return;
178+
};
179+
if start > end {
180+
return;
181+
}
182+
183+
if let Some((_, last_end)) = self.map.last_mut() {
184+
assert!(*last_end < start);
185+
if start == *last_end + 1 {
186+
*last_end = end;
187+
} else {
188+
self.map.push((start, end));
189+
}
190+
} else {
191+
self.map.push((start, end));
192+
}
193+
194+
debug_assert!(
195+
self.check_invariants(),
196+
"wrong intervals after append {start:?}..={end:?} to {self:?}"
197+
);
198+
}
199+
167200
pub fn contains(&self, needle: I) -> bool {
168201
let needle = needle.index() as u32;
169202
let Some(last) = self.map.partition_point(|r| r.0 <= needle).checked_sub(1) else {
@@ -180,11 +213,12 @@ impl<I: Idx> IntervalSet<I> {
180213
{
181214
let mut sup_iter = self.iter_intervals();
182215
let mut current = None;
183-
let contains = |sup: Range<I>, sub: Range<I>, current: &mut Option<Range<I>>| {
184-
if sup.end < sub.start {
185-
// if `sup.end == sub.start`, the next sup doesn't contain `sub.start`
216+
let contains = |sup: RangeInclusive<I>,
217+
sub: RangeInclusive<I>,
218+
current: &mut Option<RangeInclusive<I>>| {
219+
if sup.last < sub.start {
186220
None // continue to the next sup
187-
} else if sup.end >= sub.end && sup.start <= sub.start {
221+
} else if sup.last >= sub.last && sup.start <= sub.start {
188222
*current = Some(sup); // save the current sup
189223
Some(true)
190224
} else {
@@ -194,8 +228,8 @@ impl<I: Idx> IntervalSet<I> {
194228
other.iter_intervals().all(|sub| {
195229
current
196230
.take()
197-
.and_then(|sup| contains(sup, sub.clone(), &mut current))
198-
.or_else(|| sup_iter.find_map(|sup| contains(sup, sub.clone(), &mut current)))
231+
.and_then(|sup| contains(sup, sub, &mut current))
232+
.or_else(|| sup_iter.find_map(|sup| contains(sup, sub, &mut current)))
199233
.unwrap_or(false)
200234
})
201235
}
@@ -212,11 +246,11 @@ impl<I: Idx> IntervalSet<I> {
212246
let mut other_current = other_iter.next()?;
213247

214248
loop {
215-
if self_current.end <= other_current.start {
249+
if self_current.last < other_current.start {
216250
self_current = self_iter.next()?;
217251
continue;
218252
}
219-
if other_current.end <= self_current.start {
253+
if other_current.last < self_current.start {
220254
other_current = other_iter.next()?;
221255
continue;
222256
}
@@ -340,6 +374,12 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
340374
self.rows.get(row)
341375
}
342376

377+
pub fn clear_row(&mut self, row: R) {
378+
if let Some(row) = self.rows.get_mut(row) {
379+
row.clear();
380+
}
381+
}
382+
343383
fn ensure_row(&mut self, row: R) -> &mut IntervalSet<C> {
344384
self.rows.ensure_contains_elem(row, || IntervalSet::new(self.column_size))
345385
}
@@ -363,6 +403,16 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
363403
write_row.union(read_row)
364404
}
365405

406+
pub fn disjoint_rows(&self, a: R, b: R) -> bool
407+
where
408+
C: Step,
409+
{
410+
let (Some(a), Some(b)) = (self.rows.get(a), self.rows.get(b)) else {
411+
return true;
412+
};
413+
a.disjoint(b)
414+
}
415+
366416
pub fn insert_all_into_row(&mut self, row: R) {
367417
self.ensure_row(row).insert_all();
368418
}
@@ -379,6 +429,10 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
379429
self.ensure_row(row).append(point)
380430
}
381431

432+
pub fn append_range(&mut self, row: R, range: impl RangeBounds<C> + Clone) {
433+
self.ensure_row(row).append_range(range)
434+
}
435+
382436
pub fn contains(&self, row: R, point: C) -> bool {
383437
self.row(row).is_some_and(|r| r.contains(point))
384438
}

compiler/rustc_index/src/interval/tests.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ fn insert_collapses() {
55
let mut set = IntervalSet::<u32>::new(10000);
66
set.insert_range(9831..=9837);
77
set.insert_range(43..=9830);
8-
assert_eq!(set.iter_intervals().collect::<Vec<_>>(), [43..9838]);
8+
assert_eq!(set.iter_intervals().collect::<Vec<_>>(), [(43..=9837).into()]);
99
}
1010

1111
#[test]

compiler/rustc_middle/src/mir/syntax.rs

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,6 @@ pub enum RuntimePhase {
124124
/// disallowed:
125125
/// * [`TerminatorKind::Yield`]
126126
/// * [`TerminatorKind::CoroutineDrop`]
127-
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
128127
/// * [`Rvalue::CopyForDeref`]
129128
/// * [`PlaceElem::OpaqueCast`]
130129
/// * [`LocalInfo::DerefTemp`](super::LocalInfo::DerefTemp)
@@ -1442,9 +1441,6 @@ pub enum Rvalue<'tcx> {
14421441
/// This is needed because dataflow analysis needs to distinguish
14431442
/// `dest = Foo { x: ..., y: ... }` from `dest.x = ...; dest.y = ...;` in the case that `Foo`
14441443
/// has a destructor.
1445-
///
1446-
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Coroutine`. After
1447-
/// coroutine lowering, `Coroutine` aggregate kinds are disallowed too.
14481444
Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>),
14491445

14501446
/// A CopyForDeref is equivalent to a read from a place at the

compiler/rustc_mir_dataflow/src/framework/direction.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ impl Direction for Backward {
214214
) where
215215
A: Analysis<'tcx>,
216216
{
217-
vis.visit_block_end(state);
217+
vis.visit_block_end(state, block);
218218

219219
let loc = Location { block, statement_index: block_data.statements.len() };
220220
let term = block_data.terminator();
@@ -231,7 +231,7 @@ impl Direction for Backward {
231231
vis.visit_after_primary_statement_effect(analysis, state, stmt, loc);
232232
}
233233

234-
vis.visit_block_start(state);
234+
vis.visit_block_start(state, block);
235235
}
236236
}
237237

@@ -394,7 +394,7 @@ impl Direction for Forward {
394394
) where
395395
A: Analysis<'tcx>,
396396
{
397-
vis.visit_block_start(state);
397+
vis.visit_block_start(state, block);
398398

399399
for (statement_index, stmt) in block_data.statements.iter().enumerate() {
400400
let loc = Location { block, statement_index };
@@ -411,6 +411,6 @@ impl Direction for Forward {
411411
analysis.apply_primary_terminator_effect(state, term, loc);
412412
vis.visit_after_primary_terminator_effect(analysis, state, term, loc);
413413

414-
vis.visit_block_end(state);
414+
vis.visit_block_end(state, block);
415415
}
416416
}

compiler/rustc_mir_dataflow/src/framework/graphviz.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -660,13 +660,13 @@ where
660660
A: Analysis<'tcx>,
661661
A::Domain: DebugWithContext<A>,
662662
{
663-
fn visit_block_start(&mut self, state: &A::Domain) {
663+
fn visit_block_start(&mut self, state: &A::Domain, _block: BasicBlock) {
664664
if A::Direction::IS_FORWARD {
665665
self.prev_state.clone_from(state);
666666
}
667667
}
668668

669-
fn visit_block_end(&mut self, state: &A::Domain) {
669+
fn visit_block_end(&mut self, state: &A::Domain, _block: BasicBlock) {
670670
if A::Direction::IS_BACKWARD {
671671
self.prev_state.clone_from(state);
672672
}

compiler/rustc_mir_dataflow/src/framework/visitor.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ pub trait ResultsVisitor<'tcx, A>
4646
where
4747
A: Analysis<'tcx>,
4848
{
49-
fn visit_block_start(&mut self, _state: &A::Domain) {}
49+
fn visit_block_start(&mut self, _state: &A::Domain, _block: BasicBlock) {}
5050

5151
/// Called after the "early" effect of the given statement is applied to `state`.
5252
fn visit_after_early_statement_effect(
@@ -90,5 +90,5 @@ where
9090
) {
9191
}
9292

93-
fn visit_block_end(&mut self, _state: &A::Domain) {}
93+
fn visit_block_end(&mut self, _state: &A::Domain, _block: BasicBlock) {}
9494
}

compiler/rustc_mir_dataflow/src/impls/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
mod borrowed_locals;
22
mod initialized;
33
mod liveness;
4+
mod precise_liveness;
45
mod storage_liveness;
56

67
pub use self::borrowed_locals::{MaybeBorrowedLocals, borrowed_locals};
@@ -12,6 +13,7 @@ pub use self::liveness::{
1213
DefUse, MaybeLiveLocals, MaybeTransitiveLiveLocals,
1314
TransferFunction as LivenessTransferFunction,
1415
};
16+
pub use self::precise_liveness::{SplitPointEffect, SplitPointIndex, liveness_matrix};
1517
pub use self::storage_liveness::{
1618
MaybeRequiresStorage, MaybeStorageDead, MaybeStorageLive, always_storage_live_locals,
1719
};

0 commit comments

Comments
 (0)