Stop deaggregating enums in MIR.

This commit is contained in:
Camille GILLOT 2023-01-25 18:34:19 +00:00
parent b62a9da0c8
commit 6a0b218161
41 changed files with 166 additions and 440 deletions

View file

@ -1,5 +1,6 @@
use crate::util::expand_aggregate;
use crate::MirPass;
use rustc_hir::def::DefKind;
use rustc_middle::mir::*;
use rustc_middle::ty::TyCtxt;
@ -11,16 +12,19 @@ impl<'tcx> MirPass<'tcx> for Deaggregator {
for bb in basic_blocks {
bb.expand_statements(|stmt| {
// FIXME(eddyb) don't match twice on `stmt.kind` (post-NLL).
match stmt.kind {
// FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
StatementKind::Assign(box (
_,
Rvalue::Aggregate(box AggregateKind::Array(_), _),
)) => {
return None;
}
StatementKind::Assign(box (_, Rvalue::Aggregate(_, _))) => {}
_ => return None,
let StatementKind::Assign(box (
_, Rvalue::Aggregate(box ref kind, _))
) = stmt.kind else { return None };
// FIXME(#48193) Deaggregate arrays when it's cheaper to do so.
if let AggregateKind::Array(_) = kind {
return None;
}
if let AggregateKind::Adt(def_id, ..) = kind
&& matches!(tcx.def_kind(def_id), DefKind::Enum)
{
return None;
}
let stmt = stmt.replace_nop();

View file

@ -52,7 +52,6 @@
use crate::deref_separator::deref_finder;
use crate::simplify;
use crate::util::expand_aggregate;
use crate::MirPass;
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
use rustc_errors::pluralize;
@ -272,31 +271,26 @@ impl<'tcx> TransformVisitor<'tcx> {
assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 0);
// FIXME(swatinem): assert that `val` is indeed unit?
statements.extend(expand_aggregate(
Place::return_place(),
std::iter::empty(),
kind,
statements.push(Statement {
kind: StatementKind::Assign(Box::new((
Place::return_place(),
Rvalue::Aggregate(Box::new(kind), vec![]),
))),
source_info,
self.tcx,
));
});
return;
}
// else: `Poll::Ready(x)`, `GeneratorState::Yielded(x)` or `GeneratorState::Complete(x)`
assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1);
let ty = self
.tcx
.bound_type_of(self.state_adt_ref.variant(idx).fields[0].did)
.subst(self.tcx, self.state_substs);
statements.extend(expand_aggregate(
Place::return_place(),
std::iter::once((val, ty)),
kind,
statements.push(Statement {
kind: StatementKind::Assign(Box::new((
Place::return_place(),
Rvalue::Aggregate(Box::new(kind), vec![val]),
))),
source_info,
self.tcx,
));
});
}
// Create a Place referencing a generator struct field

View file

@ -15,7 +15,6 @@ use rustc_target::spec::abi::Abi;
use std::fmt;
use std::iter;
use crate::util::expand_aggregate;
use crate::{
abort_unwinding_calls, add_call_guards, add_moves_for_packed_drops, deref_separator,
pass_manager as pm, remove_noop_landing_pads, simplify,
@ -831,19 +830,23 @@ pub fn build_adt_ctor(tcx: TyCtxt<'_>, ctor_id: DefId) -> Body<'_> {
// return;
debug!("build_ctor: variant_index={:?}", variant_index);
let statements = expand_aggregate(
Place::return_place(),
adt_def.variant(variant_index).fields.iter().enumerate().map(|(idx, field_def)| {
(Operand::Move(Place::from(Local::new(idx + 1))), field_def.ty(tcx, substs))
}),
AggregateKind::Adt(adt_def.did(), variant_index, substs, None, None),
let kind = AggregateKind::Adt(adt_def.did(), variant_index, substs, None, None);
let variant = adt_def.variant(variant_index);
let statement = Statement {
kind: StatementKind::Assign(Box::new((
Place::return_place(),
Rvalue::Aggregate(
Box::new(kind),
(0..variant.fields.len())
.map(|idx| Operand::Move(Place::from(Local::new(idx + 1))))
.collect(),
),
))),
source_info,
tcx,
)
.collect();
};
let start_block = BasicBlockData {
statements,
statements: vec![statement],
terminator: Some(Terminator { source_info, kind: TerminatorKind::Return }),
is_cleanup: false,
};