Simplify visit_statement.

This commit is contained in:
Camille GILLOT 2023-03-07 14:41:13 +00:00
parent 9a56933e8c
commit 2247cd6643
2 changed files with 61 additions and 65 deletions

View File

@ -961,13 +961,14 @@ impl<'tcx> MutVisitor<'tcx> for ConstPropagator<'_, 'tcx> {
} }
} }
} }
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => { StatementKind::StorageLive(local) => {
let frame = self.ecx.frame_mut(); let frame = self.ecx.frame_mut();
frame.locals[local].value = if let StatementKind::StorageLive(_) = statement.kind { frame.locals[local].value =
LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit)) LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit));
} else { }
LocalValue::Dead StatementKind::StorageDead(local) => {
}; let frame = self.ecx.frame_mut();
frame.locals[local].value = LocalValue::Dead;
} }
_ => {} _ => {}
} }

View File

@ -522,75 +522,70 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> {
trace!("visit_statement: {:?}", statement); trace!("visit_statement: {:?}", statement);
let source_info = statement.source_info; let source_info = statement.source_info;
self.source_info = Some(source_info); self.source_info = Some(source_info);
if let StatementKind::Assign(box (place, ref rval)) = statement.kind { match statement.kind {
let can_const_prop = self.ecx.machine.can_const_prop[place.local]; StatementKind::Assign(box (place, ref rval)) => {
if let Some(()) = self.const_prop(rval, source_info, place) { let can_const_prop = self.ecx.machine.can_const_prop[place.local];
match can_const_prop { if let Some(()) = self.const_prop(rval, source_info, place) {
ConstPropMode::OnlyInsideOwnBlock => { match can_const_prop {
trace!( ConstPropMode::OnlyInsideOwnBlock => {
"found local restricted to its block. \ trace!(
"found local restricted to its block. \
Will remove it from const-prop after block is finished. Local: {:?}", Will remove it from const-prop after block is finished. Local: {:?}",
place.local place.local
); );
}
ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
trace!("can't propagate into {:?}", place);
if place.local != RETURN_PLACE {
Self::remove_const(&mut self.ecx, place.local);
} }
} ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
ConstPropMode::FullConstProp => {} trace!("can't propagate into {:?}", place);
} if place.local != RETURN_PLACE {
} else {
// Const prop failed, so erase the destination, ensuring that whatever happens
// from here on, does not know about the previous value.
// This is important in case we have
// ```rust
// let mut x = 42;
// x = SOME_MUTABLE_STATIC;
// // x must now be uninit
// ```
// FIXME: we overzealously erase the entire local, because that's easier to
// implement.
trace!(
"propagation into {:?} failed.
Nuking the entire site from orbit, it's the only way to be sure",
place,
);
Self::remove_const(&mut self.ecx, place.local);
}
} else {
match statement.kind {
StatementKind::SetDiscriminant { ref place, .. } => {
match self.ecx.machine.can_const_prop[place.local] {
ConstPropMode::FullConstProp | ConstPropMode::OnlyInsideOwnBlock => {
if self
.use_ecx(source_info, |this| this.ecx.statement(statement))
.is_some()
{
trace!("propped discriminant into {:?}", place);
} else {
Self::remove_const(&mut self.ecx, place.local); Self::remove_const(&mut self.ecx, place.local);
} }
} }
ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => { ConstPropMode::FullConstProp => {}
}
} else {
// Const prop failed, so erase the destination, ensuring that whatever happens
// from here on, does not know about the previous value.
// This is important in case we have
// ```rust
// let mut x = 42;
// x = SOME_MUTABLE_STATIC;
// // x must now be uninit
// ```
// FIXME: we overzealously erase the entire local, because that's easier to
// implement.
trace!(
"propagation into {:?} failed.
Nuking the entire site from orbit, it's the only way to be sure",
place,
);
Self::remove_const(&mut self.ecx, place.local);
}
}
StatementKind::SetDiscriminant { ref place, .. } => {
match self.ecx.machine.can_const_prop[place.local] {
ConstPropMode::FullConstProp | ConstPropMode::OnlyInsideOwnBlock => {
if self.use_ecx(source_info, |this| this.ecx.statement(statement)).is_some()
{
trace!("propped discriminant into {:?}", place);
} else {
Self::remove_const(&mut self.ecx, place.local); Self::remove_const(&mut self.ecx, place.local);
} }
} }
ConstPropMode::OnlyPropagateInto | ConstPropMode::NoPropagation => {
Self::remove_const(&mut self.ecx, place.local);
}
} }
StatementKind::StorageLive(local) | StatementKind::StorageDead(local) => {
let frame = self.ecx.frame_mut();
frame.locals[local].value =
if let StatementKind::StorageLive(_) = statement.kind {
LocalValue::Live(interpret::Operand::Immediate(
interpret::Immediate::Uninit,
))
} else {
LocalValue::Dead
};
}
_ => {}
} }
StatementKind::StorageLive(local) => {
let frame = self.ecx.frame_mut();
frame.locals[local].value =
LocalValue::Live(interpret::Operand::Immediate(interpret::Immediate::Uninit));
}
StatementKind::StorageDead(local) => {
let frame = self.ecx.frame_mut();
frame.locals[local].value = LocalValue::Dead;
}
_ => {}
} }
self.super_statement(statement, location); self.super_statement(statement, location);