Skip to content

Commit 1a73464

Browse files
authored
Rollup merge of rust-lang#110685 - cjgillot:clean-dcp, r=oli-obk
Some cleanups to DataflowConstProp Mostly moving code around and short-circuiting useless cases.
2 parents 48c34fa + dd78b99 commit 1a73464

File tree

1 file changed

+52
-73
lines changed

1 file changed

+52
-73
lines changed

Diff for: compiler/rustc_mir_transform/src/dataflow_const_prop.rs

+52-73
Original file line numberDiff line numberDiff line change
@@ -70,22 +70,6 @@ struct ConstAnalysis<'a, 'tcx> {
7070
param_env: ty::ParamEnv<'tcx>,
7171
}
7272

73-
impl<'tcx> ConstAnalysis<'_, 'tcx> {
74-
fn eval_discriminant(
75-
&self,
76-
enum_ty: Ty<'tcx>,
77-
variant_index: VariantIdx,
78-
) -> Option<ScalarTy<'tcx>> {
79-
if !enum_ty.is_enum() {
80-
return None;
81-
}
82-
let discr = enum_ty.discriminant_for_variant(self.tcx, variant_index)?;
83-
let discr_layout = self.tcx.layout_of(self.param_env.and(discr.ty)).ok()?;
84-
let discr_value = Scalar::try_from_uint(discr.val, discr_layout.size)?;
85-
Some(ScalarTy(discr_value, discr.ty))
86-
}
87-
}
88-
8973
impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
9074
type Value = FlatSet<ScalarTy<'tcx>>;
9175

@@ -126,59 +110,55 @@ impl<'tcx> ValueAnalysis<'tcx> for ConstAnalysis<'_, 'tcx> {
126110
// we must make sure that all `target as Variant#i` are `Top`.
127111
state.flood(target.as_ref(), self.map());
128112

129-
if let Some(target_idx) = self.map().find(target.as_ref()) {
130-
let (variant_target, variant_index) = match **kind {
131-
AggregateKind::Tuple | AggregateKind::Closure(..) => {
132-
(Some(target_idx), None)
133-
}
134-
AggregateKind::Adt(def_id, variant_index, ..) => {
135-
match self.tcx.def_kind(def_id) {
136-
DefKind::Struct => (Some(target_idx), None),
137-
DefKind::Enum => (
138-
self.map.apply(target_idx, TrackElem::Variant(variant_index)),
139-
Some(variant_index),
140-
),
141-
_ => (None, None),
142-
}
143-
}
144-
_ => (None, None),
145-
};
146-
if let Some(variant_target_idx) = variant_target {
147-
for (field_index, operand) in operands.iter().enumerate() {
148-
if let Some(field) = self.map().apply(
149-
variant_target_idx,
150-
TrackElem::Field(FieldIdx::from_usize(field_index)),
151-
) {
152-
let result = self.handle_operand(operand, state);
153-
state.insert_idx(field, result, self.map());
154-
}
113+
let Some(target_idx) = self.map().find(target.as_ref()) else { return };
114+
115+
let (variant_target, variant_index) = match **kind {
116+
AggregateKind::Tuple | AggregateKind::Closure(..) => (Some(target_idx), None),
117+
AggregateKind::Adt(def_id, variant_index, ..) => {
118+
match self.tcx.def_kind(def_id) {
119+
DefKind::Struct => (Some(target_idx), None),
120+
DefKind::Enum => (
121+
self.map.apply(target_idx, TrackElem::Variant(variant_index)),
122+
Some(variant_index),
123+
),
124+
_ => return,
155125
}
156126
}
157-
if let Some(variant_index) = variant_index
158-
&& let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant)
159-
{
160-
// We are assigning the discriminant as part of an aggregate.
161-
// This discriminant can only alias a variant field's value if the operand
162-
// had an invalid value for that type.
163-
// Using invalid values is UB, so we are allowed to perform the assignment
164-
// without extra flooding.
165-
let enum_ty = target.ty(self.local_decls, self.tcx).ty;
166-
if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) {
167-
state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map);
127+
_ => return,
128+
};
129+
if let Some(variant_target_idx) = variant_target {
130+
for (field_index, operand) in operands.iter().enumerate() {
131+
if let Some(field) = self.map().apply(
132+
variant_target_idx,
133+
TrackElem::Field(FieldIdx::from_usize(field_index)),
134+
) {
135+
let result = self.handle_operand(operand, state);
136+
state.insert_idx(field, result, self.map());
168137
}
169138
}
170139
}
140+
if let Some(variant_index) = variant_index
141+
&& let Some(discr_idx) = self.map().apply(target_idx, TrackElem::Discriminant)
142+
{
143+
// We are assigning the discriminant as part of an aggregate.
144+
// This discriminant can only alias a variant field's value if the operand
145+
// had an invalid value for that type.
146+
// Using invalid values is UB, so we are allowed to perform the assignment
147+
// without extra flooding.
148+
let enum_ty = target.ty(self.local_decls, self.tcx).ty;
149+
if let Some(discr_val) = self.eval_discriminant(enum_ty, variant_index) {
150+
state.insert_value_idx(discr_idx, FlatSet::Elem(discr_val), &self.map);
151+
}
152+
}
171153
}
172154
Rvalue::CheckedBinaryOp(op, box (left, right)) => {
173155
// Flood everything now, so we can use `insert_value_idx` directly later.
174156
state.flood(target.as_ref(), self.map());
175157

176-
let target = self.map().find(target.as_ref());
158+
let Some(target) = self.map().find(target.as_ref()) else { return };
177159

178-
let value_target = target
179-
.and_then(|target| self.map().apply(target, TrackElem::Field(0_u32.into())));
180-
let overflow_target = target
181-
.and_then(|target| self.map().apply(target, TrackElem::Field(1_u32.into())));
160+
let value_target = self.map().apply(target, TrackElem::Field(0_u32.into()));
161+
let overflow_target = self.map().apply(target, TrackElem::Field(1_u32.into()));
182162

183163
if value_target.is_some() || overflow_target.is_some() {
184164
let (val, overflow) = self.binary_op(state, *op, left, right);
@@ -377,6 +357,20 @@ impl<'a, 'tcx> ConstAnalysis<'a, 'tcx> {
377357
}
378358
}
379359

360+
fn eval_discriminant(
361+
&self,
362+
enum_ty: Ty<'tcx>,
363+
variant_index: VariantIdx,
364+
) -> Option<ScalarTy<'tcx>> {
365+
if !enum_ty.is_enum() {
366+
return None;
367+
}
368+
let discr = enum_ty.discriminant_for_variant(self.tcx, variant_index)?;
369+
let discr_layout = self.tcx.layout_of(self.param_env.and(discr.ty)).ok()?;
370+
let discr_value = Scalar::try_from_uint(discr.val, discr_layout.size)?;
371+
Some(ScalarTy(discr_value, discr.ty))
372+
}
373+
380374
fn wrap_scalar(&self, scalar: Scalar, ty: Ty<'tcx>) -> FlatSet<ScalarTy<'tcx>> {
381375
FlatSet::Elem(ScalarTy(scalar, ty))
382376
}
@@ -520,21 +514,6 @@ impl<'tcx, 'map, 'a> Visitor<'tcx> for OperandCollector<'tcx, 'map, 'a> {
520514
_ => (),
521515
}
522516
}
523-
524-
fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
525-
match rvalue {
526-
Rvalue::Discriminant(place) => {
527-
match self.state.get_discr(place.as_ref(), self.visitor.map) {
528-
FlatSet::Top => (),
529-
FlatSet::Elem(value) => {
530-
self.visitor.before_effect.insert((location, *place), value);
531-
}
532-
FlatSet::Bottom => (),
533-
}
534-
}
535-
_ => self.super_rvalue(rvalue, location),
536-
}
537-
}
538517
}
539518

540519
struct DummyMachine;

0 commit comments

Comments
 (0)