Skip to content

Commit c48756c

Browse files
committed
Limit creation of tracked place directly.
1 parent 9a6c04f commit c48756c

File tree

2 files changed

+22
-11
lines changed

2 files changed

+22
-11
lines changed

compiler/rustc_mir_dataflow/src/value_analysis.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -599,10 +599,11 @@ impl Map {
599599
tcx: TyCtxt<'tcx>,
600600
body: &Body<'tcx>,
601601
filter: impl FnMut(Ty<'tcx>) -> bool,
602+
place_limit: Option<usize>,
602603
) -> Self {
603604
let mut map = Self::new();
604605
let exclude = excluded_locals(body);
605-
map.register_with_filter(tcx, body, filter, exclude);
606+
map.register_with_filter(tcx, body, filter, exclude, place_limit);
606607
debug!("registered {} places ({} nodes in total)", map.value_count, map.places.len());
607608
map
608609
}
@@ -614,12 +615,20 @@ impl Map {
614615
body: &Body<'tcx>,
615616
mut filter: impl FnMut(Ty<'tcx>) -> bool,
616617
exclude: BitSet<Local>,
618+
place_limit: Option<usize>,
617619
) {
618620
// We use this vector as stack, pushing and popping projections.
619621
let mut projection = Vec::new();
620622
for (local, decl) in body.local_decls.iter_enumerated() {
621623
if !exclude.contains(local) {
622-
self.register_with_filter_rec(tcx, local, &mut projection, decl.ty, &mut filter);
624+
self.register_with_filter_rec(
625+
tcx,
626+
local,
627+
&mut projection,
628+
decl.ty,
629+
&mut filter,
630+
place_limit,
631+
);
623632
}
624633
}
625634
}
@@ -634,7 +643,12 @@ impl Map {
634643
projection: &mut Vec<PlaceElem<'tcx>>,
635644
ty: Ty<'tcx>,
636645
filter: &mut impl FnMut(Ty<'tcx>) -> bool,
646+
place_limit: Option<usize>,
637647
) {
648+
if let Some(place_limit) = place_limit && self.value_count >= place_limit {
649+
return
650+
}
651+
638652
// We know that the projection only contains trackable elements.
639653
let place = self.make_place(local, projection).unwrap();
640654

@@ -672,13 +686,13 @@ impl Map {
672686
projection.push(PlaceElem::Downcast(None, variant));
673687
let _ = self.make_place(local, projection);
674688
projection.push(PlaceElem::Field(field, ty));
675-
self.register_with_filter_rec(tcx, local, projection, ty, filter);
689+
self.register_with_filter_rec(tcx, local, projection, ty, filter, place_limit);
676690
projection.pop();
677691
projection.pop();
678692
return;
679693
}
680694
projection.push(PlaceElem::Field(field, ty));
681-
self.register_with_filter_rec(tcx, local, projection, ty, filter);
695+
self.register_with_filter_rec(tcx, local, projection, ty, filter, place_limit);
682696
projection.pop();
683697
});
684698
}

compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+4-7
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,6 @@ impl<'tcx> MirPass<'tcx> for DataflowConstProp {
3737
return;
3838
}
3939

40-
// Decide which places to track during the analysis.
41-
let map = Map::from_filter(tcx, body, Ty::is_scalar);
42-
4340
// We want to have a somewhat linear runtime w.r.t. the number of statements/terminators.
4441
// Let's call this number `n`. Dataflow analysis has `O(h*n)` transfer function
4542
// applications, where `h` is the height of the lattice. Because the height of our lattice
@@ -48,10 +45,10 @@ impl<'tcx> MirPass<'tcx> for DataflowConstProp {
4845
// `O(num_nodes * tracked_places * n)` in terms of time complexity. Since the number of
4946
// map nodes is strongly correlated to the number of tracked places, this becomes more or
5047
// less `O(n)` if we place a constant limit on the number of tracked places.
51-
if tcx.sess.mir_opt_level() < 4 && map.tracked_places() > PLACE_LIMIT {
52-
debug!("aborted dataflow const prop due to too many tracked places");
53-
return;
54-
}
48+
let place_limit = if tcx.sess.mir_opt_level() < 4 { Some(PLACE_LIMIT) } else { None };
49+
50+
// Decide which places to track during the analysis.
51+
let map = Map::from_filter(tcx, body, Ty::is_scalar, place_limit);
5552

5653
// Perform the actual dataflow analysis.
5754
let analysis = ConstAnalysis::new(tcx, body, map);

0 commit comments

Comments
 (0)