Simplify visit_statement.
This commit is contained in:
parent
9a56933e8c
commit
2247cd6643
@ -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;
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user