Auto merge of #99946 - tmiasko:elide-storage-makers, r=oli-obk
Elide superfluous storage markers Follow the existing strategy of omitting the storage markers for temporaries introduced for internal usage when elaborating derefs and deref projections. Those temporaries are simple scalars which are used immediately after being defined and never have their address taken. There is no benefit from storage markers from either liveness analysis or code generation perspective.
This commit is contained in:
commit
5462da52ba
22 changed files with 48 additions and 198 deletions
|
@ -28,8 +28,6 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
|
|||
let mut last_len = 0;
|
||||
let mut last_deref_idx = 0;
|
||||
|
||||
let mut prev_temp: Option<Local> = None;
|
||||
|
||||
for (idx, elem) in place.projection[0..].iter().enumerate() {
|
||||
if *elem == ProjectionElem::Deref {
|
||||
last_deref_idx = idx;
|
||||
|
@ -39,14 +37,12 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
|
|||
for (idx, (p_ref, p_elem)) in place.iter_projections().enumerate() {
|
||||
if !p_ref.projection.is_empty() && p_elem == ProjectionElem::Deref {
|
||||
let ty = p_ref.ty(&self.local_decls, self.tcx).ty;
|
||||
let temp = self.patcher.new_local_with_info(
|
||||
let temp = self.patcher.new_internal_with_info(
|
||||
ty,
|
||||
self.local_decls[p_ref.local].source_info.span,
|
||||
Some(Box::new(LocalInfo::DerefTemp)),
|
||||
);
|
||||
|
||||
self.patcher.add_statement(loc, StatementKind::StorageLive(temp));
|
||||
|
||||
// We are adding current p_ref's projections to our
|
||||
// temp value, excluding projections we already covered.
|
||||
let deref_place = Place::from(place_local)
|
||||
|
@ -66,22 +62,8 @@ impl<'tcx> MutVisitor<'tcx> for DerefChecker<'tcx> {
|
|||
Place::from(temp).project_deeper(&place.projection[idx..], self.tcx);
|
||||
*place = temp_place;
|
||||
}
|
||||
|
||||
// We are destroying the previous temp since it's no longer used.
|
||||
if let Some(prev_temp) = prev_temp {
|
||||
self.patcher.add_statement(loc, StatementKind::StorageDead(prev_temp));
|
||||
}
|
||||
|
||||
prev_temp = Some(temp);
|
||||
}
|
||||
}
|
||||
|
||||
// Since we won't be able to reach final temp, we destroy it outside the loop.
|
||||
if let Some(prev_temp) = prev_temp {
|
||||
let last_loc =
|
||||
Location { block: loc.block, statement_index: loc.statement_index + 1 };
|
||||
self.patcher.add_statement(last_loc, StatementKind::StorageDead(prev_temp));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -69,9 +69,7 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
|
|||
let (unique_ty, nonnull_ty, ptr_ty) =
|
||||
build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did);
|
||||
|
||||
let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
|
||||
|
||||
self.patch.add_statement(location, StatementKind::StorageLive(ptr_local));
|
||||
let ptr_local = self.patch.new_internal(ptr_ty, source_info.span);
|
||||
|
||||
self.patch.add_assign(
|
||||
location,
|
||||
|
@ -83,11 +81,6 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
|
|||
);
|
||||
|
||||
place.local = ptr_local;
|
||||
|
||||
self.patch.add_statement(
|
||||
Location { block: location.block, statement_index: location.statement_index + 1 },
|
||||
StatementKind::StorageDead(ptr_local),
|
||||
);
|
||||
}
|
||||
|
||||
self.super_place(place, context, location);
|
||||
|
|
|
@ -616,7 +616,9 @@ impl<'tcx> Inliner<'tcx> {
|
|||
// If there are any locals without storage markers, give them storage only for the
|
||||
// duration of the call.
|
||||
for local in callee_body.vars_and_temps_iter() {
|
||||
if integrator.always_live_locals.contains(local) {
|
||||
if !callee_body.local_decls[local].internal
|
||||
&& integrator.always_live_locals.contains(local)
|
||||
{
|
||||
let new_local = integrator.map_local(local);
|
||||
caller_body[callsite.block].statements.push(Statement {
|
||||
source_info: callsite.source_info,
|
||||
|
@ -629,7 +631,9 @@ impl<'tcx> Inliner<'tcx> {
|
|||
// the slice once.
|
||||
let mut n = 0;
|
||||
for local in callee_body.vars_and_temps_iter().rev() {
|
||||
if integrator.always_live_locals.contains(local) {
|
||||
if !callee_body.local_decls[local].internal
|
||||
&& integrator.always_live_locals.contains(local)
|
||||
{
|
||||
let new_local = integrator.map_local(local);
|
||||
caller_body[block].statements.push(Statement {
|
||||
source_info: callsite.source_info,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue