1
Fork 0

Rewrite dest prop.

This fixes a number of correctness issues from the previous version. Additionally, we use a new
strategy which has much better performance charactersitics and also finds more opportunities to
apply the optimization.
This commit is contained in:
Jakob Degen 2022-04-24 17:34:24 -04:00
parent 80a96467ec
commit 245c60749a
40 changed files with 1046 additions and 1231 deletions

View file

@ -70,6 +70,8 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
for Location { block, statement_index } in patch {
bbs[block].statements[statement_index].make_nop();
}
crate::simplify::SimplifyLocals.run_pass(tcx, body)
}
pub struct DeadStoreElimination;

View file

@ -110,15 +110,16 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
if let TerminatorKind::Call { ref args, .. } = terminator.kind {
for arg in args {
if let Operand::Move(_) = *arg {
// ArgumentChecker panics if a direct move of an argument from a caller to a
// callee was detected.
//
// If, in the future, MIR optimizations cause arguments to be moved directly
// from callers to callees, change the panic to instead add the argument in
// question to `mutating_uses`.
ArgumentChecker::new(self.mutable_args.domain_size())
.visit_operand(arg, location)
if let Operand::Move(place) = *arg {
let local = place.local;
if place.is_indirect()
|| local == RETURN_PLACE
|| local.index() > self.mutable_args.domain_size()
{
continue;
}
self.mutable_args.insert(local.index() - 1);
}
}
};
@ -127,35 +128,6 @@ impl<'tcx> Visitor<'tcx> for DeduceReadOnly {
}
}
/// A visitor that simply panics if a direct move of an argument from a caller to a callee was
/// detected.
struct ArgumentChecker {
/// The number of arguments to the calling function.
arg_count: usize,
}
impl ArgumentChecker {
/// Creates a new ArgumentChecker.
fn new(arg_count: usize) -> Self {
Self { arg_count }
}
}
impl<'tcx> Visitor<'tcx> for ArgumentChecker {
fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
// Check to make sure that, if this local is an argument, we didn't move directly from it.
if matches!(context, PlaceContext::NonMutatingUse(NonMutatingUseContext::Move))
&& local != RETURN_PLACE
&& local.index() <= self.arg_count
{
// If, in the future, MIR optimizations cause arguments to be moved directly from
// callers to callees, change this panic to instead add the argument in question to
// `mutating_uses`.
panic!("Detected a direct move from a caller's argument to a callee's argument!")
}
}
}
/// Returns true if values of a given type will never be passed indirectly, regardless of ABI.
fn type_will_always_be_passed_directly<'tcx>(ty: Ty<'tcx>) -> bool {
matches!(

File diff suppressed because it is too large Load diff