Skip to content

Commit 2989fd8

Browse files
committed
Auto merge of #142915 - cjgillot:dest-prop-default, r=<try>
Enable DestinationPropagation by default r? `@ghost`
2 parents 42245d3 + b835228 commit 2989fd8

29 files changed

+672
-951
lines changed

compiler/rustc_index/src/interval.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,49 @@ impl<I: Idx> IntervalSet<I> {
140140
result
141141
}
142142

143+
/// Specialized version of `insert` when we know that the inserted point is *before* any
144+
/// contained.
145+
pub fn prepend(&mut self, point: I) {
146+
let point = point.index() as u32;
147+
148+
if let Some((first_start, _)) = self.map.first_mut() {
149+
assert!(point < *first_start);
150+
if point + 1 == *first_start {
151+
*first_start = point;
152+
} else {
153+
self.map.insert(0, (point, point));
154+
}
155+
} else {
156+
// If the map is empty, push is faster than insert.
157+
self.map.push((point, point));
158+
}
159+
160+
debug_assert!(
161+
self.check_invariants(),
162+
"wrong intervals after prepend {point:?} to {self:?}"
163+
);
164+
}
165+
166+
/// Specialized version of `insert` when we know that the inserted point is *after* any
167+
/// contained.
168+
pub fn append(&mut self, point: I) {
169+
let point = point.index() as u32;
170+
171+
if let Some((_, last_end)) = self.map.last_mut()
172+
&& let _ = assert!(*last_end < point)
173+
&& point == *last_end + 1
174+
{
175+
*last_end = point;
176+
} else {
177+
self.map.push((point, point));
178+
}
179+
180+
debug_assert!(
181+
self.check_invariants(),
182+
"wrong intervals after append {point:?} to {self:?}"
183+
);
184+
}
185+
143186
pub fn contains(&self, needle: I) -> bool {
144187
let needle = needle.index() as u32;
145188
let Some(last) = self.map.partition_point(|r| r.0 <= needle).checked_sub(1) else {
@@ -325,6 +368,14 @@ impl<R: Idx, C: Step + Idx> SparseIntervalMatrix<R, C> {
325368
self.ensure_row(row).insert(point)
326369
}
327370

371+
pub fn prepend(&mut self, row: R, point: C) {
372+
self.ensure_row(row).prepend(point)
373+
}
374+
375+
pub fn append(&mut self, row: R, point: C) {
376+
self.ensure_row(row).append(point)
377+
}
378+
328379
pub fn contains(&self, row: R, point: C) -> bool {
329380
self.row(row).is_some_and(|r| r.contains(point))
330381
}

compiler/rustc_mir_dataflow/src/points.rs

Lines changed: 39 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use rustc_index::interval::SparseIntervalMatrix;
33
use rustc_index::{Idx, IndexVec};
44
use rustc_middle::mir::{self, BasicBlock, Body, Location};
55

6-
use crate::framework::{Analysis, Results, ResultsVisitor, visit_results};
6+
use crate::framework::{Analysis, Direction, Results, ResultsVisitor, visit_results};
77

88
/// Maps between a `Location` and a `PointIndex` (and vice versa).
99
pub struct DenseLocationMap {
@@ -105,27 +105,47 @@ where
105105
N: Idx,
106106
A: Analysis<'tcx, Domain = DenseBitSet<N>>,
107107
{
108-
let values = SparseIntervalMatrix::new(elements.num_points());
109-
let mut visitor = Visitor { elements, values };
110-
visit_results(
111-
body,
112-
body.basic_blocks.reverse_postorder().iter().copied(),
113-
&mut analysis,
114-
&results,
115-
&mut visitor,
116-
);
117-
visitor.values
108+
let mut values = SparseIntervalMatrix::new(elements.num_points());
109+
let reachable_blocks = mir::traversal::reachable_as_bitset(body);
110+
if A::Direction::IS_BACKWARD {
111+
// Iterate blocks in decreasing order, to visit locations in decreasing order. This
112+
// allows to use the more efficient `prepend` method to interval sets.
113+
let callback = |state: &DenseBitSet<N>, location| {
114+
let point = elements.point_from_location(location);
115+
// Use internal iterator manually as it is much more efficient.
116+
state.iter().for_each(|node| values.prepend(node, point));
117+
};
118+
let mut visitor = Visitor { callback };
119+
visit_results(
120+
body,
121+
// Note the `.rev()`.
122+
body.basic_blocks.indices().filter(|&bb| reachable_blocks.contains(bb)).rev(),
123+
&mut analysis,
124+
&results,
125+
&mut visitor,
126+
);
127+
} else {
128+
// Iterate blocks in increasing order, to visit locations in increasing order. This
129+
// allows to use the more efficient `append` method to interval sets.
130+
let callback = |state: &DenseBitSet<N>, location| {
131+
let point = elements.point_from_location(location);
132+
// Use internal iterator manually as it is much more efficient.
133+
state.iter().for_each(|node| values.append(node, point));
134+
};
135+
let mut visitor = Visitor { callback };
136+
visit_results(body, reachable_blocks.iter(), &mut analysis, &results, &mut visitor);
137+
}
138+
values
118139
}
119140

120-
struct Visitor<'a, N: Idx> {
121-
elements: &'a DenseLocationMap,
122-
values: SparseIntervalMatrix<N, PointIndex>,
141+
struct Visitor<F> {
142+
callback: F,
123143
}
124144

125-
impl<'tcx, A, N> ResultsVisitor<'tcx, A> for Visitor<'_, N>
145+
impl<'tcx, A, F> ResultsVisitor<'tcx, A> for Visitor<F>
126146
where
127-
A: Analysis<'tcx, Domain = DenseBitSet<N>>,
128-
N: Idx,
147+
A: Analysis<'tcx>,
148+
F: FnMut(&A::Domain, Location),
129149
{
130150
fn visit_after_primary_statement_effect<'mir>(
131151
&mut self,
@@ -134,11 +154,7 @@ where
134154
_statement: &'mir mir::Statement<'tcx>,
135155
location: Location,
136156
) {
137-
let point = self.elements.point_from_location(location);
138-
// Use internal iterator manually as it is much more efficient.
139-
state.iter().for_each(|node| {
140-
self.values.insert(node, point);
141-
});
157+
(self.callback)(state, location);
142158
}
143159

144160
fn visit_after_primary_terminator_effect<'mir>(
@@ -148,10 +164,6 @@ where
148164
_terminator: &'mir mir::Terminator<'tcx>,
149165
location: Location,
150166
) {
151-
let point = self.elements.point_from_location(location);
152-
// Use internal iterator manually as it is much more efficient.
153-
state.iter().for_each(|node| {
154-
self.values.insert(node, point);
155-
});
167+
(self.callback)(state, location);
156168
}
157169
}

compiler/rustc_mir_transform/src/dest_prop.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,7 @@ impl<'tcx> crate::MirPass<'tcx> for DestinationPropagation {
158158
// 2. Despite being an overall perf improvement, this still causes a 30% regression in
159159
// keccak. We can temporarily fix this by bounding function size, but in the long term
160160
// we should fix this by being smarter about invalidating analysis results.
161-
sess.mir_opt_level() >= 3
161+
sess.mir_opt_level() >= 2
162162
}
163163

164164
fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {

compiler/rustc_mir_transform/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,6 @@ declare_passes! {
153153
mod match_branches : MatchBranchSimplification;
154154
mod mentioned_items : MentionedItems;
155155
mod multiple_return_terminators : MultipleReturnTerminators;
156-
mod nrvo : RenameReturnPlace;
157156
mod post_drop_elaboration : CheckLiveDrops;
158157
mod prettify : ReorderBasicBlocks, ReorderLocals;
159158
mod promote_consts : PromoteTemps;
@@ -708,15 +707,14 @@ pub(crate) fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'
708707
&jump_threading::JumpThreading,
709708
&early_otherwise_branch::EarlyOtherwiseBranch,
710709
&simplify_comparison_integral::SimplifyComparisonIntegral,
711-
&dest_prop::DestinationPropagation,
712710
&o1(simplify_branches::SimplifyConstCondition::Final),
713711
&o1(remove_noop_landing_pads::RemoveNoopLandingPads),
714712
&o1(simplify::SimplifyCfg::Final),
715713
// After the last SimplifyCfg, because this wants one-block functions.
716714
&strip_debuginfo::StripDebugInfo,
717715
&copy_prop::CopyProp,
718716
&dead_store_elimination::DeadStoreElimination::Final,
719-
&nrvo::RenameReturnPlace,
717+
&dest_prop::DestinationPropagation,
720718
&simplify::SimplifyLocals::Final,
721719
&multiple_return_terminators::MultipleReturnTerminators,
722720
&large_enums::EnumSizeOpt { discrepancy: 128 },

0 commit comments

Comments
 (0)