@@ -1451,13 +1451,13 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1451
1451
return OperandRef :: zero_sized ( place. layout ) ;
1452
1452
}
1453
1453
1454
- let val = if let Some ( llextra ) = place. llextra {
1455
- OperandValue :: Ref ( place. llval , Some ( llextra ) , place . align )
1454
+ let val = if place. val . llextra . is_some ( ) {
1455
+ OperandValue :: Ref ( place. val )
1456
1456
} else if self . cx . is_backend_immediate ( place. layout ) {
1457
1457
let llval = self . load (
1458
1458
place. layout . spirv_type ( self . span ( ) , self ) ,
1459
- place. llval ,
1460
- place. align ,
1459
+ place. val . llval ,
1460
+ place. val . align ,
1461
1461
) ;
1462
1462
OperandValue :: Immediate ( self . to_immediate ( llval, place. layout ) )
1463
1463
} else if let Abi :: ScalarPair ( a, b) = place. layout . abi {
@@ -1468,9 +1468,9 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1468
1468
1469
1469
let mut load = |i, scalar : Scalar , align| {
1470
1470
let llptr = if i == 0 {
1471
- place. llval
1471
+ place. val . llval
1472
1472
} else {
1473
- self . inbounds_ptradd ( place. llval , self . const_usize ( b_offset. bytes ( ) ) )
1473
+ self . inbounds_ptradd ( place. val . llval , self . const_usize ( b_offset. bytes ( ) ) )
1474
1474
} ;
1475
1475
let load = self . load (
1476
1476
self . scalar_pair_element_backend_type ( place. layout , i, false ) ,
@@ -1481,11 +1481,11 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1481
1481
} ;
1482
1482
1483
1483
OperandValue :: Pair (
1484
- load ( 0 , a, place. align ) ,
1485
- load ( 1 , b, place. align . restrict_for_offset ( b_offset) ) ,
1484
+ load ( 0 , a, place. val . align ) ,
1485
+ load ( 1 , b, place. val . align . restrict_for_offset ( b_offset) ) ,
1486
1486
)
1487
1487
} else {
1488
- OperandValue :: Ref ( place. llval , None , place . align )
1488
+ OperandValue :: Ref ( place. val )
1489
1489
} ;
1490
1490
OperandRef {
1491
1491
val,
@@ -1501,11 +1501,11 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
1501
1501
dest : PlaceRef < ' tcx , Self :: Value > ,
1502
1502
) {
1503
1503
let zero = self . const_usize ( 0 ) ;
1504
- let start = dest. project_index ( self , zero) . llval ;
1504
+ let start = dest. project_index ( self , zero) . val . llval ;
1505
1505
1506
1506
let elem_layout = dest. layout . field ( self . cx ( ) , 0 ) ;
1507
1507
let elem_ty = elem_layout. spirv_type ( self . span ( ) , self ) ;
1508
- let align = dest. align . restrict_for_offset ( elem_layout. size ) ;
1508
+ let align = dest. val . align . restrict_for_offset ( elem_layout. size ) ;
1509
1509
1510
1510
for i in 0 ..count {
1511
1511
let current = self . inbounds_gep ( elem_ty, start, & [ self . const_usize ( i) ] ) ;
@@ -2834,12 +2834,13 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
2834
2834
// are decoded to values of this `enum`. For instructions that
2835
2835
// produce results, the result ID is the first `ID` value.
2836
2836
#[ derive( Debug ) ]
2837
- enum Inst < ' tcx , ID > {
2837
+ enum Inst < ID > {
2838
2838
Bitcast ( ID , ID ) ,
2839
2839
CompositeExtract ( ID , ID , u32 ) ,
2840
- InBoundsAccessChain ( ID , ID , SpirvConst < ' tcx , ' tcx > ) ,
2840
+ InBoundsAccessChain ( ID , ID , u32 ) ,
2841
2841
Store ( ID , ID ) ,
2842
2842
Load ( ID , ID ) ,
2843
+ CopyMemory ( ID , ID ) ,
2843
2844
Call ( ID , ID , SmallVec < [ ID ; 4 ] > ) ,
2844
2845
2845
2846
// HACK(eddyb) this only exists for better error reporting,
@@ -2882,14 +2883,17 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
2882
2883
match ( inst. class . opcode , inst. result_id , & id_operands[ ..] ) {
2883
2884
( Op :: Bitcast , Some ( r) , & [ x] ) => Inst :: Bitcast ( r, x) ,
2884
2885
( Op :: InBoundsAccessChain , Some ( r) , & [ p, i] ) => {
2885
- Inst :: InBoundsAccessChain (
2886
- r,
2887
- p,
2888
- self . builder . lookup_const_by_id ( i) ?,
2889
- )
2886
+ if let Some ( SpirvConst :: U32 ( i) ) =
2887
+ self . builder . lookup_const_by_id ( i)
2888
+ {
2889
+ Inst :: InBoundsAccessChain ( r, p, i)
2890
+ } else {
2891
+ Inst :: Unsupported ( inst. class . opcode )
2892
+ }
2890
2893
}
2891
2894
( Op :: Store , None , & [ p, v] ) => Inst :: Store ( p, v) ,
2892
2895
( Op :: Load , Some ( r) , & [ p] ) => Inst :: Load ( r, p) ,
2896
+ ( Op :: CopyMemory , None , & [ a, b] ) => Inst :: CopyMemory ( a, b) ,
2893
2897
( Op :: FunctionCall , Some ( r) , [ f, args @ ..] ) => {
2894
2898
Inst :: Call ( r, * f, args. iter ( ) . copied ( ) . collect ( ) )
2895
2899
}
@@ -2989,46 +2993,50 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
2989
2993
} ;
2990
2994
require_local_var ( rt_args_array_ptr_id, "[fmt::rt::Argument; N]" ) ?;
2991
2995
2992
- // Each runtime argument has 3 instructions to call one of
2993
- // the `fmt::rt::Argument::new_*` functions (and split its
2994
- // scalar pair result), and 5 instructions to store it into
2995
- // the appropriate slot in the array. The groups of 3 and 5
2996
+ // Each runtime argument has 4 instructions to call one of
2997
+ // the `fmt::rt::Argument::new_*` functions (and temporarily
2998
+ // store its result), and 4 instructions to copy it into
2999
+ // the appropriate slot in the array. The groups of 4 and 4
2996
3000
// instructions, for all runtime args, are each separate.
2997
- let stores_to_rt_args_array =
2998
- try_rev_take ( rt_args_count * 5 ) . ok_or_else ( || {
3001
+ let copies_to_rt_args_array =
3002
+ try_rev_take ( rt_args_count * 4 ) . ok_or_else ( || {
2999
3003
FormatArgsNotRecognized (
3000
- "[fmt::rt::Argument; N] stores : ran out of instructions" . into ( ) ,
3004
+ "[fmt::rt::Argument; N] copies : ran out of instructions" . into ( ) ,
3001
3005
)
3002
3006
} ) ?;
3003
- let stores_to_rt_args_array = stores_to_rt_args_array . chunks ( 5 ) ;
3004
- let rt_arg_new_calls = try_rev_take ( rt_args_count * 3 ) . ok_or_else ( || {
3007
+ let copies_to_rt_args_array = copies_to_rt_args_array . chunks ( 4 ) ;
3008
+ let rt_arg_new_calls = try_rev_take ( rt_args_count * 4 ) . ok_or_else ( || {
3005
3009
FormatArgsNotRecognized (
3006
3010
"fmt::rt::Argument::new calls: ran out of instructions" . into ( ) ,
3007
3011
)
3008
3012
} ) ?;
3009
- let rt_arg_new_calls = rt_arg_new_calls. chunks ( 3 ) ;
3013
+ let rt_arg_new_calls = rt_arg_new_calls. chunks ( 4 ) ;
3010
3014
3011
- for ( rt_arg_idx, ( rt_arg_new_call_insts, store_to_rt_args_array_insts ) ) in
3012
- rt_arg_new_calls. zip ( stores_to_rt_args_array ) . enumerate ( )
3015
+ for ( rt_arg_idx, ( rt_arg_new_call_insts, copy_to_rt_args_array_insts ) ) in
3016
+ rt_arg_new_calls. zip ( copies_to_rt_args_array ) . enumerate ( )
3013
3017
{
3014
- let ( a , b ) = match rt_arg_new_call_insts[ ..] {
3018
+ let call_ret_slot_ptr = match rt_arg_new_call_insts[ ..] {
3015
3019
[
3016
3020
Inst :: Call ( call_ret_id, callee_id, ref call_args) ,
3017
- Inst :: CompositeExtract ( a, a_parent_pair, 0 ) ,
3018
- Inst :: CompositeExtract ( b, b_parent_pair, 1 ) ,
3019
- ] if [ a_parent_pair, b_parent_pair] == [ call_ret_id; 2 ] => self
3020
- . fmt_rt_arg_new_fn_ids_to_ty_and_spec
3021
- . borrow ( )
3022
- . get ( & callee_id)
3023
- . and_then ( |& ( ty, spec) | match call_args[ ..] {
3024
- [ x] => {
3025
- decoded_format_args
3026
- . ref_arg_ids_with_ty_and_spec
3027
- . push ( ( x, ty, spec) ) ;
3028
- Some ( ( a, b) )
3029
- }
3030
- _ => None ,
3031
- } ) ,
3021
+ Inst :: InBoundsAccessChain ( tmp_slot_field_ptr, tmp_slot_ptr, 0 ) ,
3022
+ Inst :: CompositeExtract ( field, wrapper_newtype, 0 ) ,
3023
+ Inst :: Store ( st_dst_ptr, st_val) ,
3024
+ ] if wrapper_newtype == call_ret_id
3025
+ && ( st_dst_ptr, st_val) == ( tmp_slot_field_ptr, field) =>
3026
+ {
3027
+ self . fmt_rt_arg_new_fn_ids_to_ty_and_spec
3028
+ . borrow ( )
3029
+ . get ( & callee_id)
3030
+ . and_then ( |& ( ty, spec) | match call_args[ ..] {
3031
+ [ x] => {
3032
+ decoded_format_args
3033
+ . ref_arg_ids_with_ty_and_spec
3034
+ . push ( ( x, ty, spec) ) ;
3035
+ Some ( tmp_slot_ptr)
3036
+ }
3037
+ _ => None ,
3038
+ } )
3039
+ }
3032
3040
_ => None ,
3033
3041
}
3034
3042
. ok_or_else ( || {
@@ -3037,25 +3045,20 @@ impl<'a, 'tcx> BuilderMethods<'a, 'tcx> for Builder<'a, 'tcx> {
3037
3045
) )
3038
3046
} ) ?;
3039
3047
3040
- match store_to_rt_args_array_insts [ ..] {
3048
+ match copy_to_rt_args_array_insts [ ..] {
3041
3049
[
3042
- Inst :: InBoundsAccessChain (
3043
- array_slot_ptr,
3044
- array_base_ptr,
3045
- SpirvConst :: U32 ( array_idx) ,
3046
- ) ,
3047
- Inst :: InBoundsAccessChain ( a_ptr, a_base_ptr, SpirvConst :: U32 ( 0 ) ) ,
3048
- Inst :: Store ( a_st_dst, a_st_val) ,
3049
- Inst :: InBoundsAccessChain ( b_ptr, b_base_ptr, SpirvConst :: U32 ( 1 ) ) ,
3050
- Inst :: Store ( b_st_dst, b_st_val) ,
3051
- ] if array_base_ptr == rt_args_array_ptr_id
3050
+ Inst :: InBoundsAccessChain ( array_slot, array_base, array_idx) ,
3051
+ Inst :: InBoundsAccessChain ( dst_field_ptr, dst_base_ptr, 0 ) ,
3052
+ Inst :: InBoundsAccessChain ( src_field_ptr, src_base_ptr, 0 ) ,
3053
+ Inst :: CopyMemory ( copy_dst, copy_src) ,
3054
+ ] if array_base == rt_args_array_ptr_id
3052
3055
&& array_idx as usize == rt_arg_idx
3053
- && [ a_base_ptr , b_base_ptr ] == [ array_slot_ptr ; 2 ]
3054
- && ( a , b ) == ( a_st_val , b_st_val )
3055
- && ( a_ptr , b_ptr ) == ( a_st_dst , b_st_dst ) => { }
3056
+ && dst_base_ptr == array_slot
3057
+ && src_base_ptr == call_ret_slot_ptr
3058
+ && ( copy_dst , copy_src ) == ( dst_field_ptr , src_field_ptr ) => { }
3056
3059
_ => {
3057
3060
return Err ( FormatArgsNotRecognized ( format ! (
3058
- "[fmt::rt::Argument; N] stores sequence ({store_to_rt_args_array_insts :?})"
3061
+ "[fmt::rt::Argument; N] copies sequence ({copy_to_rt_args_array_insts :?})"
3059
3062
) ) ) ;
3060
3063
}
3061
3064
}
0 commit comments