Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit ca3d3c4

Browse files
committed
Make Value Copy by arena-allocating vectors.
1 parent 6d6a08c commit ca3d3c4

File tree

1 file changed

+59
-56
lines changed
  • compiler/rustc_mir_transform/src

1 file changed

+59
-56
lines changed

‎compiler/rustc_mir_transform/src/gvn.rs‎

Lines changed: 59 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ use std::borrow::Cow;
8888

8989
use either::Either;
9090
use rustc_abi::{self as abi, BackendRepr, FIRST_VARIANT, FieldIdx, Primitive, Size, VariantIdx};
91+
use rustc_arena::DroplessArena;
9192
use rustc_const_eval::const_eval::DummyMachine;
9293
use rustc_const_eval::interpret::{
9394
ImmTy, Immediate, InterpCx, MemPlaceMeta, MemoryKind, OpTy, Projectable, Scalar,
@@ -126,7 +127,9 @@ impl<'tcx> crate::MirPass<'tcx> for GVN {
126127
// Clone dominators because we need them while mutating the body.
127128
let dominators = body.basic_blocks.dominators().clone();
128129

129-
let mut state = VnState::new(tcx, body, typing_env, &ssa, dominators, &body.local_decls);
130+
let arena = DroplessArena::default();
131+
let mut state =
132+
VnState::new(tcx, body, typing_env, &ssa, dominators, &body.local_decls, &arena);
130133

131134
for local in body.args_iter().filter(|&local| ssa.is_ssa(local)) {
132135
let opaque = state.new_opaque(body.local_decls[local].ty);
@@ -160,8 +163,8 @@ enum AddressKind {
160163
Address(RawPtrKind),
161164
}
162165

163-
#[derive(Debug, PartialEq, Eq, Hash)]
164-
enum Value<'tcx> {
166+
#[derive(Copy,Clone,Debug, PartialEq, Eq, Hash)]
167+
enum Value<'a,'tcx> {
165168
// Root values.
166169
/// Used to represent values we know nothing about.
167170
/// The `usize` is a counter incremented by `new_opaque`.
@@ -176,7 +179,7 @@ enum Value<'tcx> {
176179
},
177180
/// An aggregate value, either tuple/closure/struct/enum.
178181
/// This does not contain unions, as we cannot reason with the value.
179-
Aggregate(VariantIdx, Vec<VnIndex>),
182+
Aggregate(VariantIdx, &'a[VnIndex]),
180183
/// A raw pointer aggregate built from a thin pointer and metadata.
181184
RawPtr {
182185
/// Thin pointer component. This is field 0 in MIR.
@@ -212,7 +215,7 @@ enum Value<'tcx> {
212215
},
213216
}
214217

215-
struct VnState<'body, 'tcx> {
218+
struct VnState<'body, 'a,'tcx> {
216219
tcx: TyCtxt<'tcx>,
217220
ecx: InterpCx<'tcx, DummyMachine>,
218221
local_decls: &'body LocalDecls<'tcx>,
@@ -222,7 +225,7 @@ struct VnState<'body, 'tcx> {
222225
/// Locals that are assigned that value.
223226
// This vector does not hold all the values of `VnIndex` that we create.
224227
rev_locals: IndexVec<VnIndex, SmallVec<[Local; 1]>>,
225-
values: FxIndexSet<(Value<'tcx>, Ty<'tcx>)>,
228+
values: FxIndexSet<(Value<'a,'tcx>, Ty<'tcx>)>,
226229
/// Values evaluated as constants if possible.
227230
evaluated: IndexVec<VnIndex, Option<OpTy<'tcx>>>,
228231
/// Counter to generate different values.
@@ -232,16 +235,18 @@ struct VnState<'body, 'tcx> {
232235
ssa: &'body SsaLocals,
233236
dominators: Dominators<BasicBlock>,
234237
reused_locals: DenseBitSet<Local>,
238+
arena: &'a DroplessArena,
235239
}
236240

237-
impl<'body, 'tcx> VnState<'body, 'tcx> {
241+
impl<'body, 'a,'tcx> VnState<'body,'a, 'tcx> {
238242
fn new(
239243
tcx: TyCtxt<'tcx>,
240244
body: &Body<'tcx>,
241245
typing_env: ty::TypingEnv<'tcx>,
242246
ssa: &'body SsaLocals,
243247
dominators: Dominators<BasicBlock>,
244248
local_decls: &'body LocalDecls<'tcx>,
249+
arena: &'a DroplessArena,
245250
) -> Self {
246251
// Compute a rough estimate of the number of values in the body from the number of
247252
// statements. This is meant to reduce the number of allocations, but it's all right if
@@ -264,6 +269,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
264269
ssa,
265270
dominators,
266271
reused_locals: DenseBitSet::new_empty(local_decls.len()),
272+
arena,
267273
}
268274
}
269275

@@ -272,7 +278,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
272278
}
273279

274280
#[instrument(level = "trace", skip(self), ret)]
275-
fn insert(&mut self, ty: Ty<'tcx>, value: Value<'tcx>) -> VnIndex {
281+
fn insert(&mut self, ty: Ty<'tcx>, value: Value<'a,'tcx>) -> VnIndex {
276282
let (index, new) = self.values.insert_full((value, ty));
277283
let index = VnIndex::from_usize(index);
278284
if new {
@@ -315,8 +321,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
315321
}
316322

317323
#[inline]
318-
fn get(&self, index: VnIndex) -> &Value<'tcx> {
319-
&self.values.get_index(index.as_usize()).unwrap().0
324+
fn get(&self, index: VnIndex) -> Value<'a,'tcx> {
325+
self.values.get_index(index.as_usize()).unwrap().0
320326
}
321327

322328
#[inline]
@@ -361,8 +367,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
361367
self.insert(ty, Value::Constant { value, disambiguator: 0 })
362368
}
363369

364-
fn insert_tuple(&mut self, ty: Ty<'tcx>, values: Vec<VnIndex>) -> VnIndex {
365-
self.insert(ty, Value::Aggregate(VariantIdx::ZERO, values))
370+
fn insert_tuple(&mut self, ty: Ty<'tcx>, values: &[VnIndex]) -> VnIndex {
371+
self.insert(ty, Value::Aggregate(VariantIdx::ZERO, self.arena.alloc_slice(values)))
366372
}
367373

368374
fn insert_deref(&mut self, ty: Ty<'tcx>, value: VnIndex) -> VnIndex {
@@ -388,7 +394,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
388394
} else {
389395
return None;
390396
};
391-
let op = match *self.get(value) {
397+
let op = match self.get(value) {
392398
_ if ty.is_zst() => ImmTy::uninit(ty).into(),
393399

394400
Opaque(_) => return None,
@@ -608,7 +614,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
608614
if let Value::Aggregate(_, fields) = self.get(value) {
609615
return Some((projection_ty, fields[f.as_usize()]));
610616
} else if let Value::Projection(outer_value, ProjectionElem::Downcast(_, read_variant)) = self.get(value)
611-
&& let Value::Aggregate(written_variant, fields) = self.get(*outer_value)
617+
&& let Value::Aggregate(written_variant, fields) = self.get(outer_value)
612618
// This pass is not aware of control-flow, so we do not know whether the
613619
// replacement we are doing is actually reachable. We could be in any arm of
614620
// ```
@@ -633,15 +639,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
633639
ProjectionElem::Index(idx) => {
634640
if let Value::Repeat(inner, _) = self.get(value) {
635641
*from_non_ssa_index |= self.locals[idx].is_none();
636-
return Some((projection_ty, *inner));
642+
return Some((projection_ty, inner));
637643
}
638644
let idx = self.locals[idx]?;
639645
ProjectionElem::Index(idx)
640646
}
641647
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
642648
match self.get(value) {
643649
Value::Repeat(inner, _) => {
644-
return Some((projection_ty, *inner));
650+
return Some((projection_ty, inner));
645651
}
646652
Value::Aggregate(_, operands) => {
647653
let offset = if from_end {
@@ -731,8 +737,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
731737
let mut place_ty = PlaceTy::from_ty(self.local_decls[place.local].ty);
732738
let mut from_non_ssa_index = false;
733739
for (index, proj) in place.projection.iter().enumerate() {
734-
if let Value::Projection(pointer, ProjectionElem::Deref) = *self.get(value)
735-
&& let Value::Address { place: mut pointee, kind, .. } = *self.get(pointer)
740+
if let Value::Projection(pointer, ProjectionElem::Deref) = self.get(value)
741+
&& let Value::Address { place: mut pointee, kind, .. } = self.get(pointer)
736742
&& let AddressKind::Ref(BorrowKind::Shared) = kind
737743
&& let Some(v) = self.simplify_place_value(&mut pointee, location)
738744
{
@@ -755,8 +761,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
755761
(place_ty, value) = self.project(place_ty, value, proj, &mut from_non_ssa_index)?;
756762
}
757763

758-
if let Value::Projection(pointer, ProjectionElem::Deref) = *self.get(value)
759-
&& let Value::Address { place: mut pointee, kind, .. } = *self.get(pointer)
764+
if let Value::Projection(pointer, ProjectionElem::Deref) = self.get(value)
765+
&& let Value::Address { place: mut pointee, kind, .. } = self.get(pointer)
760766
&& let AddressKind::Ref(BorrowKind::Shared) = kind
761767
&& let Some(v) = self.simplify_place_value(&mut pointee, location)
762768
{
@@ -868,7 +874,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
868874
fn simplify_discriminant(&mut self, place: VnIndex) -> Option<VnIndex> {
869875
let enum_ty = self.ty(place);
870876
if enum_ty.is_enum()
871-
&& let Value::Aggregate(variant, _) = *self.get(place)
877+
&& let Value::Aggregate(variant, _) = self.get(place)
872878
{
873879
let discr = self.ecx.discriminant_for_variant(enum_ty, variant).discard_err()?;
874880
return Some(self.insert_scalar(discr.layout.ty, discr.to_scalar()));
@@ -904,12 +910,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
904910
let Some(&first_field) = fields.first() else {
905911
return None;
906912
};
907-
let Value::Projection(copy_from_value, _) = *self.get(first_field) else {
913+
let Value::Projection(copy_from_value, _) = self.get(first_field) else {
908914
return None;
909915
};
910916
// All fields must correspond one-to-one and come from the same aggregate value.
911917
if fields.iter().enumerate().any(|(index, &v)| {
912-
if let Value::Projection(pointer, ProjectionElem::Field(from_index, _)) = *self.get(v)
918+
if let Value::Projection(pointer, ProjectionElem::Field(from_index, _)) = self.get(v)
913919
&& copy_from_value == pointer
914920
&& from_index.index() == index
915921
{
@@ -921,7 +927,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
921927
}
922928

923929
let mut copy_from_local_value = copy_from_value;
924-
if let Value::Projection(pointer, proj) = *self.get(copy_from_value)
930+
if let Value::Projection(pointer, proj) = self.get(copy_from_value)
925931
&& let ProjectionElem::Downcast(_, read_variant) = proj
926932
{
927933
if variant_index == read_variant {
@@ -979,13 +985,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
979985
}
980986
}
981987

982-
let fields: Vec<_> = field_ops
983-
.iter_mut()
984-
.map(|op| {
985-
self.simplify_operand(op, location)
986-
.unwrap_or_else(|| self.new_opaque(op.ty(self.local_decls, self.tcx)))
987-
})
988-
.collect();
988+
let fields = self.arena.alloc_from_iter(field_ops.iter_mut().map(|op| {
989+
self.simplify_operand(op, location)
990+
.unwrap_or_else(|| self.new_opaque(op.ty(self.local_decls, self.tcx)))
991+
}));
989992

990993
let variant_index = match *kind {
991994
AggregateKind::Array(..) | AggregateKind::Tuple => {
@@ -1006,12 +1009,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10061009
let mut was_updated = false;
10071010
while let Value::Cast { kind: CastKind::PtrToPtr, value: cast_value } =
10081011
self.get(pointer)
1009-
&& let ty::RawPtr(from_pointee_ty, from_mtbl) = self.ty(*cast_value).kind()
1012+
&& let ty::RawPtr(from_pointee_ty, from_mtbl) = self.ty(cast_value).kind()
10101013
&& let ty::RawPtr(_, output_mtbl) = ty.kind()
10111014
&& from_mtbl == output_mtbl
10121015
&& from_pointee_ty.is_sized(self.tcx, self.typing_env())
10131016
{
1014-
pointer = *cast_value;
1017+
pointer = cast_value;
10151018
was_updated = true;
10161019
}
10171020

@@ -1069,9 +1072,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10691072
// To allow things like `*mut (?A, ?T)` <-> `*mut (?B, ?T)`,
10701073
// it's fine to get a projection as the type.
10711074
Value::Cast { kind: CastKind::PtrToPtr, value: inner }
1072-
if self.pointers_have_same_metadata(self.ty(*inner), arg_ty) =>
1075+
if self.pointers_have_same_metadata(self.ty(inner), arg_ty) =>
10731076
{
1074-
arg_index = *inner;
1077+
arg_index = inner;
10751078
was_updated = true;
10761079
continue;
10771080
}
@@ -1098,15 +1101,15 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
10981101
}
10991102

11001103
let value = match (op, self.get(arg_index)) {
1101-
(UnOp::Not, Value::UnaryOp(UnOp::Not, inner)) => return Some(*inner),
1102-
(UnOp::Neg, Value::UnaryOp(UnOp::Neg, inner)) => return Some(*inner),
1104+
(UnOp::Not, Value::UnaryOp(UnOp::Not, inner)) => return Some(inner),
1105+
(UnOp::Neg, Value::UnaryOp(UnOp::Neg, inner)) => return Some(inner),
11031106
(UnOp::Not, Value::BinaryOp(BinOp::Eq, lhs, rhs)) => {
1104-
Value::BinaryOp(BinOp::Ne, *lhs, *rhs)
1107+
Value::BinaryOp(BinOp::Ne, lhs, rhs)
11051108
}
11061109
(UnOp::Not, Value::BinaryOp(BinOp::Ne, lhs, rhs)) => {
1107-
Value::BinaryOp(BinOp::Eq, *lhs, *rhs)
1110+
Value::BinaryOp(BinOp::Eq, lhs, rhs)
11081111
}
1109-
(UnOp::PtrMetadata, Value::RawPtr { metadata, .. }) => return Some(*metadata),
1112+
(UnOp::PtrMetadata, Value::RawPtr { metadata, .. }) => return Some(metadata),
11101113
// We have an unsizing cast, which assigns the length to wide pointer metadata.
11111114
(
11121115
UnOp::PtrMetadata,
@@ -1115,7 +1118,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
11151118
value: inner,
11161119
},
11171120
) if let ty::Slice(..) = arg_ty.builtin_deref(true).unwrap().kind()
1118-
&& let ty::Array(_, len) = self.ty(*inner).builtin_deref(true).unwrap().kind() =>
1121+
&& let ty::Array(_, len) = self.ty(inner).builtin_deref(true).unwrap().kind() =>
11191122
{
11201123
return Some(self.insert_constant(Const::Ty(self.tcx.types.usize, *len)));
11211124
}
@@ -1148,12 +1151,12 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
11481151
&& lhs_ty.is_any_ptr()
11491152
&& let Value::Cast { kind: CastKind::PtrToPtr, value: lhs_value } = self.get(lhs)
11501153
&& let Value::Cast { kind: CastKind::PtrToPtr, value: rhs_value } = self.get(rhs)
1151-
&& let lhs_from = self.ty(*lhs_value)
1152-
&& lhs_from == self.ty(*rhs_value)
1154+
&& let lhs_from = self.ty(lhs_value)
1155+
&& lhs_from == self.ty(rhs_value)
11531156
&& self.pointers_have_same_metadata(lhs_from, lhs_ty)
11541157
{
1155-
lhs = *lhs_value;
1156-
rhs = *rhs_value;
1158+
lhs = lhs_value;
1159+
rhs = rhs_value;
11571160
if let Some(lhs_op) = self.try_as_operand(lhs, location)
11581161
&& let Some(rhs_op) = self.try_as_operand(rhs, location)
11591162
{
@@ -1287,7 +1290,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
12871290
if op.is_overflowing() {
12881291
let ty = Ty::new_tup(self.tcx, &[self.ty(result), self.tcx.types.bool]);
12891292
let false_val = self.insert_bool(false);
1290-
Some(self.insert_tuple(ty, vec![result, false_val]))
1293+
Some(self.insert_tuple(ty, &[result, false_val]))
12911294
} else {
12921295
Some(result)
12931296
}
@@ -1340,11 +1343,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
13401343
&& let ty::RawPtr(to_pointee, _) = to.kind()
13411344
&& to_pointee.is_sized(self.tcx, self.typing_env())
13421345
{
1343-
from = self.ty(*pointer);
1344-
value = *pointer;
1346+
from = self.ty(pointer);
1347+
value = pointer;
13451348
was_updated_this_iteration = true;
13461349
if from == to {
1347-
return Some(*pointer);
1350+
return Some(pointer);
13481351
}
13491352
}
13501353

@@ -1353,7 +1356,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
13531356
if let Transmute = kind
13541357
&& let Value::Aggregate(variant_idx, field_values) = self.get(value)
13551358
&& let Some((field_idx, field_ty)) =
1356-
self.value_is_all_in_one_field(from, *variant_idx)
1359+
self.value_is_all_in_one_field(from, variant_idx)
13571360
{
13581361
from = field_ty;
13591362
value = field_values[field_idx.as_usize()];
@@ -1364,7 +1367,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
13641367
}
13651368

13661369
// Various cast-then-cast cases can be simplified.
1367-
if let Value::Cast { kind: inner_kind, value: inner_value } = *self.get(value) {
1370+
if let Value::Cast { kind: inner_kind, value: inner_value } = self.get(value) {
13681371
let inner_from = self.ty(inner_value);
13691372
let new_kind = match (inner_kind, kind) {
13701373
// Even if there's a narrowing cast in here that's fine, because
@@ -1438,7 +1441,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
14381441
// We have an unsizing cast, which assigns the length to wide pointer metadata.
14391442
if let Value::Cast { kind, value: from } = self.get(inner)
14401443
&& let CastKind::PointerCoercion(ty::adjustment::PointerCoercion::Unsize, _) = kind
1441-
&& let Some(from) = self.ty(*from).builtin_deref(true)
1444+
&& let Some(from) = self.ty(from).builtin_deref(true)
14421445
&& let ty::Array(_, len) = from.kind()
14431446
&& let Some(to) = self.ty(inner).builtin_deref(true)
14441447
&& let ty::Slice(..) = to.kind()
@@ -1596,7 +1599,7 @@ fn op_to_prop_const<'tcx>(
15961599
None
15971600
}
15981601

1599-
impl<'tcx> VnState<'_, 'tcx> {
1602+
impl<'tcx> VnState<'_, '_,'tcx> {
16001603
/// If either [`Self::try_as_constant`] as [`Self::try_as_place`] succeeds,
16011604
/// returns that result as an [`Operand`].
16021605
fn try_as_operand(&mut self, index: VnIndex, location: Location) -> Option<Operand<'tcx>> {
@@ -1615,7 +1618,7 @@ impl<'tcx> VnState<'_, 'tcx> {
16151618
// This was already constant in MIR, do not change it. If the constant is not
16161619
// deterministic, adding an additional mention of it in MIR will not give the same value as
16171620
// the former mention.
1618-
if let Value::Constant { value, disambiguator: 0 } = *self.get(index) {
1621+
if let Value::Constant { value, disambiguator: 0 } = self.get(index) {
16191622
debug_assert!(value.is_deterministic());
16201623
return Some(ConstOperand { span: DUMMY_SP, user_ty: None, const_: value });
16211624
}
@@ -1654,7 +1657,7 @@ impl<'tcx> VnState<'_, 'tcx> {
16541657
let place =
16551658
Place { local, projection: self.tcx.mk_place_elems(projection.as_slice()) };
16561659
return Some(place);
1657-
} else if let Value::Projection(pointer, proj) = *self.get(index)
1660+
} else if let Value::Projection(pointer, proj) = self.get(index)
16581661
&& (allow_complex_projection || proj.is_stable_offset())
16591662
&& let Some(proj) = self.try_as_place_elem(self.ty(index), proj, loc)
16601663
{
@@ -1677,7 +1680,7 @@ impl<'tcx> VnState<'_, 'tcx> {
16771680
}
16781681
}
16791682

1680-
impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1683+
impl<'tcx> MutVisitor<'tcx> for VnState<'_, '_,'tcx> {
16811684
fn tcx(&self) -> TyCtxt<'tcx> {
16821685
self.tcx
16831686
}

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /