@@ -138,7 +138,7 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
138
138
let value = state. simplify_rvalue ( rvalue, location) ;
139
139
// FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark `local` as
140
140
// reusable if we have an exact type match.
141
- if state. local_decls [ local] . ty != rvalue. ty ( state. local_decls , tcx) {
141
+ if state. local_decls [ local] . ty != rvalue. ty ( state. local_decls , state . tcx ) {
142
142
return ;
143
143
}
144
144
value
@@ -382,7 +382,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
382
382
let ty = match kind {
383
383
AggregateTy :: Array => {
384
384
assert ! ( fields. len( ) > 0 ) ;
385
- Ty :: new_array ( self . tcx , fields[ 0 ] . layout . ty , fields. len ( ) as u64 )
385
+ let field_ty = fields[ 0 ] . layout . ty ;
386
+ Ty :: new_array ( self . tcx , field_ty, fields. len ( ) as u64 )
386
387
}
387
388
AggregateTy :: Tuple => {
388
389
Ty :: new_tup_from_iter ( self . tcx , fields. iter ( ) . map ( |f| f. layout . ty ) )
@@ -406,7 +407,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
406
407
} ;
407
408
let ptr_imm = Immediate :: new_pointer_with_meta ( data, meta, & self . ecx ) ;
408
409
ImmTy :: from_immediate ( ptr_imm, ty) . into ( )
409
- } else if matches ! ( ty. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) {
410
+ } else if matches ! ( kind, AggregateTy :: Array )
411
+ || matches ! ( ty. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) )
412
+ {
410
413
let dest = self . ecx . allocate ( ty, MemoryKind :: Stack ) . ok ( ) ?;
411
414
let variant_dest = if let Some ( variant) = variant {
412
415
self . ecx . project_downcast ( & dest, variant) . ok ( ) ?
@@ -418,9 +421,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
418
421
self . ecx . copy_op ( op, & field_dest) . ok ( ) ?;
419
422
}
420
423
self . ecx . write_discriminant ( variant. unwrap_or ( FIRST_VARIANT ) , & dest) . ok ( ) ?;
421
- self . ecx
422
- . alloc_mark_immutable ( dest. ptr ( ) . provenance . unwrap ( ) . alloc_id ( ) )
423
- . ok ( ) ?;
424
+ let dest = dest. map_provenance ( |prov| prov. as_immutable ( ) ) ;
424
425
dest. into ( )
425
426
} else {
426
427
return None ;
@@ -704,7 +705,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
704
705
place. projection = self . tcx . mk_place_elems ( & projection) ;
705
706
}
706
707
707
- trace ! ( ?place) ;
708
+ trace ! ( after_place = ?place) ;
708
709
}
709
710
710
711
/// Represent the *value* which would be read from `place`, and point `place` to a preexisting
@@ -777,6 +778,11 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
777
778
}
778
779
Operand :: Copy ( ref mut place) | Operand :: Move ( ref mut place) => {
779
780
let value = self . simplify_place_value ( place, location) ?;
781
+ // NOTE(tesuji): We just want to promote rvalues of array kind that assigned to a local, and
782
+ // not evaluate this local as a const operand of a function to avoid bloating MIR.
783
+ if let Value :: Aggregate ( AggregateTy :: Array , ..) = self . get ( value) {
784
+ return None ;
785
+ }
780
786
if let Some ( const_) = self . try_as_constant ( value) {
781
787
* operand = Operand :: Constant ( Box :: new ( const_) ) ;
782
788
}
@@ -884,7 +890,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
884
890
}
885
891
886
892
let ( mut ty, variant_index) = match * kind {
887
- AggregateKind :: Array ( .. ) => {
893
+ AggregateKind :: Array ( _ ) => {
888
894
assert ! ( !field_ops. is_empty( ) ) ;
889
895
( AggregateTy :: Array , FIRST_VARIANT )
890
896
}
@@ -1347,6 +1353,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
1347
1353
}
1348
1354
}
1349
1355
1356
+ #[ instrument( level = "trace" , skip( ecx) , ret) ]
1350
1357
fn op_to_prop_const < ' tcx > (
1351
1358
ecx : & mut InterpCx < ' tcx , DummyMachine > ,
1352
1359
op : & OpTy < ' tcx > ,
@@ -1361,8 +1368,11 @@ fn op_to_prop_const<'tcx>(
1361
1368
return Some ( ConstValue :: ZeroSized ) ;
1362
1369
}
1363
1370
1364
- // Do not synthetize too large constants. Codegen will just memcpy them, which we'd like to avoid.
1365
- if !matches ! ( op. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) {
1371
+ // Do not synthesize too large constants, except constant arrays.
1372
+ // For arrays, codegen will just memcpy them, but LLVM will optimize out those unneeded memcpy.
1373
+ // For others, we'd prefer in-place initialization over memcpy them.
1374
+ if !( op. layout . ty . is_array ( ) || matches ! ( op. layout. abi, Abi :: Scalar ( ..) | Abi :: ScalarPair ( ..) ) )
1375
+ {
1366
1376
return None ;
1367
1377
}
1368
1378
@@ -1433,6 +1443,7 @@ impl<'tcx> VnState<'_, 'tcx> {
1433
1443
}
1434
1444
1435
1445
/// If `index` is a `Value::Constant`, return the `Constant` to be put in the MIR.
1446
+ #[ instrument( level = "trace" , skip( self , index) , ret) ]
1436
1447
fn try_as_constant ( & mut self , index : VnIndex ) -> Option < ConstOperand < ' tcx > > {
1437
1448
// This was already constant in MIR, do not change it.
1438
1449
if let Value :: Constant { value, disambiguator : _ } = * self . get ( index)
@@ -1444,10 +1455,6 @@ impl<'tcx> VnState<'_, 'tcx> {
1444
1455
}
1445
1456
1446
1457
let op = self . evaluated [ index] . as_ref ( ) ?;
1447
- if op. layout . is_unsized ( ) {
1448
- // Do not attempt to propagate unsized locals.
1449
- return None ;
1450
- }
1451
1458
1452
1459
let value = op_to_prop_const ( & mut self . ecx , op) ?;
1453
1460
@@ -1484,6 +1491,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> {
1484
1491
self . simplify_operand ( operand, location) ;
1485
1492
}
1486
1493
1494
+ #[ instrument( level = "trace" , skip( self , stmt) ) ]
1487
1495
fn visit_statement ( & mut self , stmt : & mut Statement < ' tcx > , location : Location ) {
1488
1496
if let StatementKind :: Assign ( box ( ref mut lhs, ref mut rvalue) ) = stmt. kind {
1489
1497
self . simplify_place_projection ( lhs, location) ;
0 commit comments