@@ -983,56 +983,72 @@ pub fn load_if_immediate<'blk, 'tcx>(cx: Block<'blk, 'tcx>,
983
983
/// gives us better information about what we are loading.
984
984
pub fn load_ty < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > ,
985
985
ptr : ValueRef , t : Ty < ' tcx > ) -> ValueRef {
986
- if type_is_zero_size ( cx. ccx ( ) , t) {
987
- C_undef ( type_of:: type_of ( cx. ccx ( ) , t) )
988
- } else if type_is_immediate ( cx. ccx ( ) , t) && type_of:: type_of ( cx. ccx ( ) , t) . is_aggregate ( ) {
989
- // We want to pass small aggregates as immediate values, but using an aggregate LLVM type
990
- // for this leads to bad optimizations, so its arg type is an appropriately sized integer
991
- // and we have to convert it
992
- Load ( cx, BitCast ( cx, ptr, type_of:: arg_type_of ( cx. ccx ( ) , t) . ptr_to ( ) ) )
993
- } else {
994
- unsafe {
995
- let global = llvm:: LLVMIsAGlobalVariable ( ptr) ;
996
- if !global. is_null ( ) && llvm:: LLVMIsGlobalConstant ( global) == llvm:: True {
997
- let val = llvm:: LLVMGetInitializer ( global) ;
998
- if !val. is_null ( ) {
999
- // This could go into its own function, for DRY.
1000
- // (something like "pre-store packing/post-load unpacking")
1001
- if ty:: type_is_bool ( t) {
1002
- return Trunc ( cx, val, Type :: i1 ( cx. ccx ( ) ) ) ;
1003
- } else {
1004
- return val;
1005
- }
1006
- }
986
+ if cx. unreachable . get ( ) || type_is_zero_size ( cx. ccx ( ) , t) {
987
+ return C_undef ( type_of:: type_of ( cx. ccx ( ) , t) ) ;
988
+ }
989
+
990
+ let ptr = to_arg_ty_ptr ( cx, ptr, t) ;
991
+
992
+ if type_is_immediate ( cx. ccx ( ) , t) && type_of:: type_of ( cx. ccx ( ) , t) . is_aggregate ( ) {
993
+ return Load ( cx, ptr) ;
994
+ }
995
+
996
+ unsafe {
997
+ let global = llvm:: LLVMIsAGlobalVariable ( ptr) ;
998
+ if !global. is_null ( ) && llvm:: LLVMIsGlobalConstant ( global) == llvm:: True {
999
+ let val = llvm:: LLVMGetInitializer ( global) ;
1000
+ if !val. is_null ( ) {
1001
+ return from_arg_ty ( cx, val, t) ;
1007
1002
}
1008
1003
}
1009
- if ty:: type_is_bool ( t) {
1010
- Trunc ( cx, LoadRangeAssert ( cx, ptr, 0 , 2 , llvm:: False ) , Type :: i1 ( cx. ccx ( ) ) )
1011
- } else if ty:: type_is_char ( t) {
1012
- // a char is a Unicode codepoint, and so takes values from 0
1013
- // to 0x10FFFF inclusive only.
1014
- LoadRangeAssert ( cx, ptr, 0 , 0x10FFFF + 1 , llvm:: False )
1015
- } else if ( ty:: type_is_region_ptr ( t) || ty:: type_is_unique ( t) )
1016
- && !common:: type_is_fat_ptr ( cx. tcx ( ) , t) {
1017
- LoadNonNull ( cx, ptr)
1018
- } else {
1019
- Load ( cx, ptr)
1020
- }
1021
1004
}
1005
+
1006
+ let val = if ty:: type_is_bool ( t) {
1007
+ LoadRangeAssert ( cx, ptr, 0 , 2 , llvm:: False )
1008
+ } else if ty:: type_is_char ( t) {
1009
+ // a char is a Unicode codepoint, and so takes values from 0
1010
+ // to 0x10FFFF inclusive only.
1011
+ LoadRangeAssert ( cx, ptr, 0 , 0x10FFFF + 1 , llvm:: False )
1012
+ } else if ( ty:: type_is_region_ptr ( t) || ty:: type_is_unique ( t) )
1013
+ && !common:: type_is_fat_ptr ( cx. tcx ( ) , t) {
1014
+ LoadNonNull ( cx, ptr)
1015
+ } else {
1016
+ Load ( cx, ptr)
1017
+ } ;
1018
+
1019
+ from_arg_ty ( cx, val, t)
1022
1020
}
1023
1021
1024
1022
/// Helper for storing values in memory. Does the necessary conversion if the in-memory type
1025
1023
/// differs from the type used for SSA values.
1026
1024
pub fn store_ty < ' blk , ' tcx > ( cx : Block < ' blk , ' tcx > , v : ValueRef , dst : ValueRef , t : Ty < ' tcx > ) {
1027
- if ty:: type_is_bool ( t) {
1028
- Store ( cx, ZExt ( cx, v, Type :: i8 ( cx. ccx ( ) ) ) , dst) ;
1029
- } else if type_is_immediate ( cx. ccx ( ) , t) && type_of:: type_of ( cx. ccx ( ) , t) . is_aggregate ( ) {
1025
+ Store ( cx, to_arg_ty ( cx, v, t) , to_arg_ty_ptr ( cx, dst, t) ) ;
1026
+ }
1027
+
1028
+ pub fn to_arg_ty ( bcx : Block , val : ValueRef , ty : Ty ) -> ValueRef {
1029
+ if ty:: type_is_bool ( ty) {
1030
+ ZExt ( bcx, val, Type :: i8 ( bcx. ccx ( ) ) )
1031
+ } else {
1032
+ val
1033
+ }
1034
+ }
1035
+
1036
+ pub fn from_arg_ty ( bcx : Block , val : ValueRef , ty : Ty ) -> ValueRef {
1037
+ if ty:: type_is_bool ( ty) {
1038
+ Trunc ( bcx, val, Type :: i1 ( bcx. ccx ( ) ) )
1039
+ } else {
1040
+ val
1041
+ }
1042
+ }
1043
+
1044
+ pub fn to_arg_ty_ptr < ' blk , ' tcx > ( bcx : Block < ' blk , ' tcx > , ptr : ValueRef , ty : Ty < ' tcx > ) -> ValueRef {
1045
+ if type_is_immediate ( bcx. ccx ( ) , ty) && type_of:: type_of ( bcx. ccx ( ) , ty) . is_aggregate ( ) {
1030
1046
// We want to pass small aggregates as immediate values, but using an aggregate LLVM type
1031
1047
// for this leads to bad optimizations, so its arg type is an appropriately sized integer
1032
1048
// and we have to convert it
1033
- Store ( cx , v , BitCast ( cx , dst , type_of:: arg_type_of ( cx . ccx ( ) , t ) . ptr_to ( ) ) ) ;
1049
+ BitCast ( bcx , ptr , type_of:: arg_type_of ( bcx . ccx ( ) , ty ) . ptr_to ( ) )
1034
1050
} else {
1035
- Store ( cx , v , dst ) ;
1051
+ ptr
1036
1052
}
1037
1053
}
1038
1054
0 commit comments