only visit reachable blocks, do not use a visitor
This commit is contained in:
parent
5343550142
commit
172c05cca2
1 changed files with 16 additions and 28 deletions
|
@ -18,7 +18,7 @@ use rustc_middle::ty::adjustment::PointerCoercion;
|
||||||
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
|
use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TyCtxt, TypeVisitableExt};
|
||||||
use rustc_mir_dataflow::impls::MaybeStorageLive;
|
use rustc_mir_dataflow::impls::MaybeStorageLive;
|
||||||
use rustc_mir_dataflow::storage::always_storage_live_locals;
|
use rustc_mir_dataflow::storage::always_storage_live_locals;
|
||||||
use rustc_mir_dataflow::{Analysis, ResultsCursor};
|
use rustc_mir_dataflow::Analysis;
|
||||||
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
use rustc_span::{sym, Span, Symbol, DUMMY_SP};
|
||||||
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
|
||||||
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
|
use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
|
||||||
|
@ -275,40 +275,28 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
|
||||||
// A local is "transient" if it is guaranteed dead at all `Return`.
|
// A local is "transient" if it is guaranteed dead at all `Return`.
|
||||||
// So first compute the say of "maybe live" locals at each program point.
|
// So first compute the say of "maybe live" locals at each program point.
|
||||||
let always_live_locals = &always_storage_live_locals(&ccx.body);
|
let always_live_locals = &always_storage_live_locals(&ccx.body);
|
||||||
let maybe_storage_live = MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
|
let mut maybe_storage_live =
|
||||||
.into_engine(ccx.tcx, &ccx.body)
|
MaybeStorageLive::new(Cow::Borrowed(always_live_locals))
|
||||||
.iterate_to_fixpoint()
|
.into_engine(ccx.tcx, &ccx.body)
|
||||||
.into_results_cursor(&ccx.body);
|
.iterate_to_fixpoint()
|
||||||
|
.into_results_cursor(&ccx.body);
|
||||||
|
|
||||||
// And then check all `Return` in the MIR, and if a local is "maybe live" at a
|
// And then check all `Return` in the MIR, and if a local is "maybe live" at a
|
||||||
// `Return` then it is definitely not transient.
|
// `Return` then it is definitely not transient.
|
||||||
struct TransientLocalVisitor<'a, 'tcx> {
|
let mut transient = BitSet::new_filled(ccx.body.local_decls.len());
|
||||||
maybe_storage_live: ResultsCursor<'a, 'tcx, MaybeStorageLive<'a>>,
|
// Make sure to only visit reachable blocks, the dataflow engine can ICE otherwise.
|
||||||
transient: BitSet<Local>,
|
for (bb, data) in traversal::reachable(&ccx.body) {
|
||||||
}
|
if matches!(data.terminator().kind, TerminatorKind::Return) {
|
||||||
impl<'a, 'tcx> Visitor<'tcx> for TransientLocalVisitor<'a, 'tcx> {
|
let location = ccx.body.terminator_loc(bb);
|
||||||
fn visit_terminator(
|
maybe_storage_live.seek_after_primary_effect(location);
|
||||||
&mut self,
|
for local in maybe_storage_live.get().iter() {
|
||||||
terminator: &Terminator<'tcx>,
|
// If a local may be live here, it is definitely not transient.
|
||||||
location: Location,
|
transient.remove(local);
|
||||||
) {
|
|
||||||
if matches!(terminator.kind, TerminatorKind::Return) {
|
|
||||||
self.maybe_storage_live.seek_after_primary_effect(location);
|
|
||||||
for local in self.maybe_storage_live.get().iter() {
|
|
||||||
// If a local may be live here, it is definitely not transient.
|
|
||||||
self.transient.remove(local);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut v = TransientLocalVisitor {
|
transient
|
||||||
maybe_storage_live,
|
|
||||||
transient: BitSet::new_filled(ccx.body.local_decls.len()),
|
|
||||||
};
|
|
||||||
v.visit_body(&ccx.body);
|
|
||||||
|
|
||||||
v.transient
|
|
||||||
})
|
})
|
||||||
.contains(local)
|
.contains(local)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue