Skip to content

Commit 44437da

Browse files
committed
Introduce new dataflow implementation for available locals,
and use it to implement unneeded deref mir-opt pass
1 parent cf9cf7c commit 44437da

36 files changed

+1640
-761
lines changed

compiler/rustc_middle/src/mir/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2395,7 +2395,7 @@ impl<'tcx> UserTypeProjections {
23952395

23962396
/// Encodes the effect of a user-supplied type annotation on the
23972397
/// subcomponents of a pattern. The effect is determined by applying the
2398-
/// given list of proejctions to some underlying base type. Often,
2398+
/// given list of projections to some underlying base type. Often,
23992399
/// the projection element list `projs` is empty, in which case this
24002400
/// directly encodes a type in `base`. But in the case of complex patterns with
24012401
/// subpatterns and bindings, we want to apply only a *part* of the type to a variable,

compiler/rustc_middle/src/mir/tcx.rs

+16
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use crate::mir::*;
77
use crate::ty::subst::Subst;
88
use crate::ty::{self, Ty, TyCtxt};
99
use rustc_hir as hir;
10+
use rustc_middle::mir::visit::{PlaceContext, Visitor};
1011
use rustc_target::abi::VariantIdx;
1112

1213
#[derive(Copy, Clone, Debug, TypeFoldable)]
@@ -208,6 +209,21 @@ impl<'tcx> Rvalue<'tcx> {
208209
_ => RvalueInitializationState::Deep,
209210
}
210211
}
212+
213+
/// Returns all locals that participate in the Rvalue
214+
pub fn participating_locals(&self, location: Location) -> impl Iterator<Item = Local> {
215+
struct LocalVisitor(Vec<Local>);
216+
217+
impl<'tcx> Visitor<'tcx> for LocalVisitor {
218+
fn visit_local(&mut self, local: &Local, _: PlaceContext, _: Location) {
219+
self.0.push(*local);
220+
}
221+
}
222+
223+
let mut visitor = LocalVisitor(vec![]);
224+
visitor.visit_rvalue(self, location);
225+
visitor.0.into_iter()
226+
}
211227
}
212228

213229
impl<'tcx> Operand<'tcx> {

compiler/rustc_mir/src/dataflow/framework/mod.rs

+15
Original file line numberDiff line numberDiff line change
@@ -412,6 +412,9 @@ pub trait GenKill<T> {
412412
self.kill(elem);
413413
}
414414
}
415+
416+
/// Returns whether `elem` is alive
417+
fn is_alive(&self, elem: T) -> bool;
415418
}
416419

417420
/// Stores a transfer function for a gen/kill problem.
@@ -450,6 +453,10 @@ impl<T: Idx> GenKill<T> for GenKillSet<T> {
450453
self.kill.insert(elem);
451454
self.gen.remove(elem);
452455
}
456+
457+
fn is_alive(&self, elem: T) -> bool {
458+
self.gen.contains(elem) && !self.kill.contains(elem)
459+
}
453460
}
454461

455462
impl<T: Idx> GenKill<T> for BitSet<T> {
@@ -460,6 +467,10 @@ impl<T: Idx> GenKill<T> for BitSet<T> {
460467
fn kill(&mut self, elem: T) {
461468
self.remove(elem);
462469
}
470+
471+
fn is_alive(&self, elem: T) -> bool {
472+
self.contains(elem)
473+
}
463474
}
464475

465476
impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
@@ -470,6 +481,10 @@ impl<T: Idx> GenKill<T> for lattice::Dual<BitSet<T>> {
470481
fn kill(&mut self, elem: T) {
471482
self.0.remove(elem);
472483
}
484+
485+
fn is_alive(&self, elem: T) -> bool {
486+
self.0.contains(elem)
487+
}
473488
}
474489

475490
// NOTE: DO NOT CHANGE VARIANT ORDER. The derived `Ord` impls rely on the current order.

0 commit comments

Comments
 (0)