Introduce helper.
This commit is contained in:
parent
dc4fe8e295
commit
e465d647b1
@ -211,7 +211,7 @@ fn replace_flattened_locals<'tcx>(
|
|||||||
local_decls: &body.local_decls,
|
local_decls: &body.local_decls,
|
||||||
replacements,
|
replacements,
|
||||||
all_dead_locals,
|
all_dead_locals,
|
||||||
fragments,
|
fragments: &fragments,
|
||||||
patch: MirPatch::new(body),
|
patch: MirPatch::new(body),
|
||||||
};
|
};
|
||||||
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
|
for (bb, data) in body.basic_blocks.as_mut_preserves_cfg().iter_enumerated_mut() {
|
||||||
@ -239,7 +239,7 @@ struct ReplacementVisitor<'tcx, 'll> {
|
|||||||
all_dead_locals: BitSet<Local>,
|
all_dead_locals: BitSet<Local>,
|
||||||
/// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage
|
/// Pre-computed list of all "new" locals for each "old" local. This is used to expand storage
|
||||||
/// and deinit statement and debuginfo.
|
/// and deinit statement and debuginfo.
|
||||||
fragments: IndexVec<Local, Option<Vec<(&'tcx [PlaceElem<'tcx>], Local)>>>,
|
fragments: &'ll IndexVec<Local, Option<Vec<(&'tcx [PlaceElem<'tcx>], Local)>>>,
|
||||||
patch: MirPatch<'tcx>,
|
patch: MirPatch<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -270,6 +270,14 @@ impl<'tcx, 'll> ReplacementVisitor<'tcx, 'll> {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn place_fragments(
|
||||||
|
&self,
|
||||||
|
place: Place<'tcx>,
|
||||||
|
) -> Option<&'ll Vec<(&'tcx [PlaceElem<'tcx>], Local)>> {
|
||||||
|
let local = place.as_local()?;
|
||||||
|
self.fragments[local].as_ref()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
|
impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
|
||||||
@ -297,25 +305,19 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
StatementKind::Deinit(box ref place) => {
|
StatementKind::Deinit(box place) => {
|
||||||
if let Some(local) = place.as_local()
|
if let Some(final_locals) = self.place_fragments(place) {
|
||||||
&& let Some(final_locals) = &self.fragments[local]
|
|
||||||
{
|
|
||||||
for &(_, fl) in final_locals {
|
for &(_, fl) in final_locals {
|
||||||
self.patch.add_statement(
|
self.patch
|
||||||
location,
|
.add_statement(location, StatementKind::Deinit(Box::new(fl.into())));
|
||||||
StatementKind::Deinit(Box::new(fl.into())),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
statement.make_nop();
|
statement.make_nop();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatementKind::Assign(box (ref place, Rvalue::Aggregate(_, ref operands))) => {
|
StatementKind::Assign(box (place, Rvalue::Aggregate(_, ref operands))) => {
|
||||||
if let Some(local) = place.as_local()
|
if let Some(final_locals) = self.place_fragments(place) {
|
||||||
&& let Some(final_locals) = &self.fragments[local]
|
|
||||||
{
|
|
||||||
for &(projection, fl) in final_locals {
|
for &(projection, fl) in final_locals {
|
||||||
let &[PlaceElem::Field(index, _)] = projection else { bug!() };
|
let &[PlaceElem::Field(index, _)] = projection else { bug!() };
|
||||||
let index = index.as_usize();
|
let index = index.as_usize();
|
||||||
@ -330,31 +332,28 @@ impl<'tcx, 'll> MutVisitor<'tcx> for ReplacementVisitor<'tcx, 'll> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatementKind::Assign(box (ref place, Rvalue::Use(Operand::Constant(_)))) => {
|
StatementKind::Assign(box (place, Rvalue::Use(Operand::Constant(_)))) => {
|
||||||
if let Some(local) = place.as_local()
|
if let Some(final_locals) = self.place_fragments(place) {
|
||||||
&& let Some(final_locals) = &self.fragments[local]
|
|
||||||
{
|
|
||||||
for &(projection, fl) in final_locals {
|
for &(projection, fl) in final_locals {
|
||||||
let rvalue = Rvalue::Use(Operand::Move(place.project_deeper(projection, self.tcx)));
|
let rvalue =
|
||||||
|
Rvalue::Use(Operand::Move(place.project_deeper(projection, self.tcx)));
|
||||||
self.patch.add_statement(
|
self.patch.add_statement(
|
||||||
location,
|
location,
|
||||||
StatementKind::Assign(Box::new((fl.into(), rvalue))),
|
StatementKind::Assign(Box::new((fl.into(), rvalue))),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
self.all_dead_locals.remove(local);
|
self.all_dead_locals.remove(place.local);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
StatementKind::Assign(box (ref lhs, Rvalue::Use(ref op))) => {
|
StatementKind::Assign(box (lhs, Rvalue::Use(ref op))) => {
|
||||||
let (rplace, copy) = match op {
|
let (rplace, copy) = match op {
|
||||||
Operand::Copy(rplace) => (rplace, true),
|
Operand::Copy(rplace) => (rplace, true),
|
||||||
Operand::Move(rplace) => (rplace, false),
|
Operand::Move(rplace) => (rplace, false),
|
||||||
Operand::Constant(_) => bug!(),
|
Operand::Constant(_) => bug!(),
|
||||||
};
|
};
|
||||||
if let Some(local) = lhs.as_local()
|
if let Some(final_locals) = self.place_fragments(lhs) {
|
||||||
&& let Some(final_locals) = &self.fragments[local]
|
|
||||||
{
|
|
||||||
for &(projection, fl) in final_locals {
|
for &(projection, fl) in final_locals {
|
||||||
let rplace = rplace.project_deeper(projection, self.tcx);
|
let rplace = rplace.project_deeper(projection, self.tcx);
|
||||||
let rvalue = if copy {
|
let rvalue = if copy {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user