diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2023-05-21 12:59:38 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2023-10-25 06:46:47 +0000 |
| commit | 80a5e8522de648d70a9ef1dfba7621f730832fb3 (patch) | |
| tree | c4d05921cef957fd40b7b502e3ea2f919b7dbb25 /compiler/rustc_mir_transform | |
| parent | 23d4857080a3968447adbb1d55b2720dba46d666 (diff) | |
| download | rust-80a5e8522de648d70a9ef1dfba7621f730832fb3.tar.gz rust-80a5e8522de648d70a9ef1dfba7621f730832fb3.zip | |
Extract simplify_aggregate.
Diffstat (limited to 'compiler/rustc_mir_transform')
| -rw-r--r-- | compiler/rustc_mir_transform/src/gvn.rs | 83 |
1 files changed, 56 insertions, 27 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 9880e239957..bbcb39226b7 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -682,33 +682,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { Value::Repeat(op, amount) } Rvalue::NullaryOp(op, ty) => Value::NullaryOp(op, ty), - Rvalue::Aggregate(box ref kind, ref mut fields) => { - let (ty, variant_index) = match *kind { - // For empty arrays, we have not mean to recover the type. They are ZSTs - // anyway, so return them as such. - AggregateKind::Array(..) | AggregateKind::Tuple if fields.is_empty() => { - return Some(self.insert(Value::Constant(Const::zero_sized( - rvalue.ty(self.local_decls, self.tcx), - )))); - } - AggregateKind::Array(..) => (AggregateTy::Array, FIRST_VARIANT), - AggregateKind::Tuple => (AggregateTy::Tuple, FIRST_VARIANT), - AggregateKind::Closure(did, substs) - | AggregateKind::Coroutine(did, substs, _) => { - (AggregateTy::Def(did, substs), FIRST_VARIANT) - } - AggregateKind::Adt(did, variant_index, substs, _, None) => { - (AggregateTy::Def(did, substs), variant_index) - } - // Do not track unions. - AggregateKind::Adt(_, _, _, _, Some(_)) => return None, - }; - let fields: Option<Vec<_>> = fields - .iter_mut() - .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque())) - .collect(); - Value::Aggregate(ty, variant_index, fields?) - } + Rvalue::Aggregate(..) => self.simplify_aggregate(rvalue, location)?, Rvalue::Ref(_, borrow_kind, ref mut place) => { self.simplify_place_projection(place, location); return self.new_pointer(*place, AddressKind::Ref(borrow_kind)); @@ -769,6 +743,61 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { None } + + fn simplify_aggregate( + &mut self, + rvalue: &mut Rvalue<'tcx>, + location: Location, + ) -> Option<Value<'tcx>> { + let Rvalue::Aggregate(box ref kind, ref mut fields) = *rvalue else { bug!() }; + + let tcx = self.tcx; + if fields.is_empty() { + let is_zst = match *kind { + AggregateKind::Array(..) | AggregateKind::Tuple | AggregateKind::Closure(..) => { + true + } + // Only enums can be non-ZST. + AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum, + // Coroutines are never ZST, as they at least contain the implicit states. + AggregateKind::Coroutine(..) => false, + }; + + if is_zst { + let ty = rvalue.ty(self.local_decls, tcx); + let value = Value::Constant(Const::zero_sized(ty)); + return Some(value); + } + } + + let (ty, variant_index) = match *kind { + AggregateKind::Array(..) => { + assert!(!fields.is_empty()); + (AggregateTy::Array, FIRST_VARIANT) + } + AggregateKind::Tuple => { + assert!(!fields.is_empty()); + (AggregateTy::Tuple, FIRST_VARIANT) + } + AggregateKind::Closure(did, substs) | AggregateKind::Coroutine(did, substs, _) => { + (AggregateTy::Def(did, substs), FIRST_VARIANT) + } + AggregateKind::Adt(did, variant_index, substs, _, None) => { + (AggregateTy::Def(did, substs), variant_index) + } + // Do not track unions. + AggregateKind::Adt(_, _, _, _, Some(_)) => return None, + }; + + let fields: Option<Vec<_>> = fields + .iter_mut() + .map(|op| self.simplify_operand(op, location).or_else(|| self.new_opaque())) + .collect(); + let fields = fields?; + + let value = Value::Aggregate(ty, variant_index, fields); + Some(value) + } } fn op_to_prop_const<'tcx>( |
