9
9
// except according to those terms.
10
10
11
11
use llvm:: { self , AttributePlace } ;
12
- use base;
13
- use builder:: { Builder , MemFlags } ;
14
- use common:: C_usize ;
12
+ use rustc_codegen_ssa:: MemFlags ;
13
+ use builder:: Builder ;
15
14
use context:: CodegenCx ;
16
- use mir:: place:: PlaceRef ;
17
- use mir:: operand:: OperandValue ;
15
+ use rustc_codegen_ssa :: mir:: place:: PlaceRef ;
16
+ use rustc_codegen_ssa :: mir:: operand:: OperandValue ;
18
17
use type_:: Type ;
19
18
use type_of:: { LayoutLlvmExt , PointerKind } ;
20
19
use value:: Value ;
20
+ use rustc_target:: abi:: call:: ArgType ;
21
+
22
+ use rustc_codegen_ssa:: traits:: * ;
21
23
22
24
use rustc_target:: abi:: { HasDataLayout , LayoutOf , Size , TyLayout , Abi as LayoutAbi } ;
23
- use rustc:: ty:: { self , Ty } ;
25
+ use rustc:: ty:: { self , Ty , Instance } ;
24
26
use rustc:: ty:: layout;
25
27
26
28
use libc:: c_uint;
@@ -110,16 +112,16 @@ pub trait LlvmType {
110
112
impl LlvmType for Reg {
111
113
fn llvm_type ( & self , cx : & CodegenCx < ' ll , ' _ > ) -> & ' ll Type {
112
114
match self . kind {
113
- RegKind :: Integer => Type :: ix ( cx , self . size . bits ( ) ) ,
115
+ RegKind :: Integer => cx . type_ix ( self . size . bits ( ) ) ,
114
116
RegKind :: Float => {
115
117
match self . size . bits ( ) {
116
- 32 => Type :: f32 ( cx ) ,
117
- 64 => Type :: f64 ( cx ) ,
118
+ 32 => cx . type_f32 ( ) ,
119
+ 64 => cx . type_f64 ( ) ,
118
120
_ => bug ! ( "unsupported float: {:?}" , self )
119
121
}
120
122
}
121
123
RegKind :: Vector => {
122
- Type :: vector ( Type :: i8 ( cx ) , self . size . bytes ( ) )
124
+ cx . type_vector ( cx . type_i8 ( ) , self . size . bytes ( ) )
123
125
}
124
126
}
125
127
}
@@ -143,7 +145,7 @@ impl LlvmType for CastTarget {
143
145
144
146
// Simplify to array when all chunks are the same size and type
145
147
if rem_bytes == 0 {
146
- return Type :: array ( rest_ll_unit, rest_count) ;
148
+ return cx . type_array ( rest_ll_unit, rest_count) ;
147
149
}
148
150
}
149
151
@@ -158,17 +160,27 @@ impl LlvmType for CastTarget {
158
160
if rem_bytes != 0 {
159
161
// Only integers can be really split further.
160
162
assert_eq ! ( self . rest. unit. kind, RegKind :: Integer ) ;
161
- args. push ( Type :: ix ( cx , rem_bytes * 8 ) ) ;
163
+ args. push ( cx . type_ix ( rem_bytes * 8 ) ) ;
162
164
}
163
165
164
- Type :: struct_ ( cx , & args, false )
166
+ cx . type_struct ( & args, false )
165
167
}
166
168
}
167
169
168
170
pub trait ArgTypeExt < ' ll , ' tcx > {
169
171
fn memory_ty ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
170
- fn store ( & self , bx : & Builder < ' _ , ' ll , ' tcx > , val : & ' ll Value , dst : PlaceRef < ' ll , ' tcx > ) ;
171
- fn store_fn_arg ( & self , bx : & Builder < ' _ , ' ll , ' tcx > , idx : & mut usize , dst : PlaceRef < ' ll , ' tcx > ) ;
172
+ fn store (
173
+ & self ,
174
+ bx : & mut Builder < ' _ , ' ll , ' tcx > ,
175
+ val : & ' ll Value ,
176
+ dst : PlaceRef < ' tcx , & ' ll Value > ,
177
+ ) ;
178
+ fn store_fn_arg (
179
+ & self ,
180
+ bx : & mut Builder < ' _ , ' ll , ' tcx > ,
181
+ idx : & mut usize ,
182
+ dst : PlaceRef < ' tcx , & ' ll Value > ,
183
+ ) ;
172
184
}
173
185
174
186
impl ArgTypeExt < ' ll , ' tcx > for ArgType < ' tcx , Ty < ' tcx > > {
@@ -182,11 +194,15 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
182
194
/// place for the original Rust type of this argument/return.
183
195
/// Can be used for both storing formal arguments into Rust variables
184
196
/// or results of call/invoke instructions into their destinations.
185
- fn store ( & self , bx : & Builder < ' _ , ' ll , ' tcx > , val : & ' ll Value , dst : PlaceRef < ' ll , ' tcx > ) {
197
+ fn store (
198
+ & self ,
199
+ bx : & mut Builder < ' _ , ' ll , ' tcx > ,
200
+ val : & ' ll Value ,
201
+ dst : PlaceRef < ' tcx , & ' ll Value > ,
202
+ ) {
186
203
if self . is_ignore ( ) {
187
204
return ;
188
205
}
189
- let cx = bx. cx ;
190
206
if self . is_sized_indirect ( ) {
191
207
OperandValue :: Ref ( val, None , self . layout . align ) . store ( bx, dst)
192
208
} else if self . is_unsized_indirect ( ) {
@@ -196,7 +212,8 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
196
212
// uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
197
213
let can_store_through_cast_ptr = false ;
198
214
if can_store_through_cast_ptr {
199
- let cast_dst = bx. pointercast ( dst. llval , cast. llvm_type ( cx) . ptr_to ( ) ) ;
215
+ let cast_ptr_llty = bx. cx ( ) . type_ptr_to ( cast. llvm_type ( bx. cx ( ) ) ) ;
216
+ let cast_dst = bx. pointercast ( dst. llval , cast_ptr_llty) ;
200
217
bx. store ( val, cast_dst, self . layout . align ) ;
201
218
} else {
202
219
// The actual return type is a struct, but the ABI
@@ -214,22 +231,23 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
214
231
// bitcasting to the struct type yields invalid cast errors.
215
232
216
233
// We instead thus allocate some scratch space...
217
- let scratch_size = cast. size ( cx ) ;
218
- let scratch_align = cast. align ( cx ) ;
219
- let llscratch = bx. alloca ( cast. llvm_type ( cx ) , "abi_cast" , scratch_align) ;
234
+ let scratch_size = cast. size ( bx . cx ( ) ) ;
235
+ let scratch_align = cast. align ( bx . cx ( ) ) ;
236
+ let llscratch = bx. alloca ( cast. llvm_type ( bx . cx ( ) ) , "abi_cast" , scratch_align) ;
220
237
bx. lifetime_start ( llscratch, scratch_size) ;
221
238
222
239
// ...where we first store the value...
223
240
bx. store ( val, llscratch, scratch_align) ;
224
241
225
242
// ...and then memcpy it to the intended destination.
226
- base:: call_memcpy ( bx,
227
- bx. pointercast ( dst. llval , Type :: i8p ( cx) ) ,
228
- self . layout . align ,
229
- bx. pointercast ( llscratch, Type :: i8p ( cx) ) ,
230
- scratch_align,
231
- C_usize ( cx, self . layout . size . bytes ( ) ) ,
232
- MemFlags :: empty ( ) ) ;
243
+ bx. memcpy (
244
+ dst. llval ,
245
+ self . layout . align ,
246
+ llscratch,
247
+ scratch_align,
248
+ bx. cx ( ) . const_usize ( self . layout . size . bytes ( ) ) ,
249
+ MemFlags :: empty ( )
250
+ ) ;
233
251
234
252
bx. lifetime_end ( llscratch, scratch_size) ;
235
253
}
@@ -238,7 +256,12 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
238
256
}
239
257
}
240
258
241
- fn store_fn_arg ( & self , bx : & Builder < ' a , ' ll , ' tcx > , idx : & mut usize , dst : PlaceRef < ' ll , ' tcx > ) {
259
+ fn store_fn_arg (
260
+ & self ,
261
+ bx : & mut Builder < ' a , ' ll , ' tcx > ,
262
+ idx : & mut usize ,
263
+ dst : PlaceRef < ' tcx , & ' ll Value > ,
264
+ ) {
242
265
let mut next = || {
243
266
let val = llvm:: get_param ( bx. llfn ( ) , * idx as c_uint ) ;
244
267
* idx += 1 ;
@@ -259,6 +282,27 @@ impl ArgTypeExt<'ll, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
259
282
}
260
283
}
261
284
285
+ impl ArgTypeMethods < ' tcx > for Builder < ' a , ' ll , ' tcx > {
286
+ fn store_fn_arg (
287
+ & mut self ,
288
+ ty : & ArgType < ' tcx , Ty < ' tcx > > ,
289
+ idx : & mut usize , dst : PlaceRef < ' tcx , Self :: Value >
290
+ ) {
291
+ ty. store_fn_arg ( self , idx, dst)
292
+ }
293
+ fn store_arg_ty (
294
+ & mut self ,
295
+ ty : & ArgType < ' tcx , Ty < ' tcx > > ,
296
+ val : & ' ll Value ,
297
+ dst : PlaceRef < ' tcx , & ' ll Value >
298
+ ) {
299
+ ty. store ( self , val, dst)
300
+ }
301
+ fn memory_ty ( & self , ty : & ArgType < ' tcx , Ty < ' tcx > > ) -> & ' ll Type {
302
+ ty. memory_ty ( self . cx ( ) )
303
+ }
304
+ }
305
+
262
306
pub trait FnTypeExt < ' tcx > {
263
307
fn of_instance ( cx : & CodegenCx < ' ll , ' tcx > , instance : & ty:: Instance < ' tcx > ) -> Self ;
264
308
fn new ( cx : & CodegenCx < ' ll , ' tcx > ,
@@ -280,7 +324,7 @@ pub trait FnTypeExt<'tcx> {
280
324
fn ptr_to_llvm_type ( & self , cx : & CodegenCx < ' ll , ' tcx > ) -> & ' ll Type ;
281
325
fn llvm_cconv ( & self ) -> llvm:: CallConv ;
282
326
fn apply_attrs_llfn ( & self , llfn : & ' ll Value ) ;
283
- fn apply_attrs_callsite ( & self , bx : & Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) ;
327
+ fn apply_attrs_callsite ( & self , bx : & mut Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) ;
284
328
}
285
329
286
330
impl < ' tcx > FnTypeExt < ' tcx > for FnType < ' tcx , Ty < ' tcx > > {
@@ -614,14 +658,14 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
614
658
) ;
615
659
616
660
let llreturn_ty = match self . ret . mode {
617
- PassMode :: Ignore => Type :: void ( cx ) ,
661
+ PassMode :: Ignore => cx . type_void ( ) ,
618
662
PassMode :: Direct ( _) | PassMode :: Pair ( ..) => {
619
663
self . ret . layout . immediate_llvm_type ( cx)
620
664
}
621
665
PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
622
666
PassMode :: Indirect ( ..) => {
623
- llargument_tys. push ( self . ret . memory_ty ( cx) . ptr_to ( ) ) ;
624
- Type :: void ( cx )
667
+ llargument_tys. push ( cx . type_ptr_to ( self . ret . memory_ty ( cx) ) ) ;
668
+ cx . type_void ( )
625
669
}
626
670
} ;
627
671
@@ -647,15 +691,15 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
647
691
continue ;
648
692
}
649
693
PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
650
- PassMode :: Indirect ( _, None ) => arg. memory_ty ( cx) . ptr_to ( ) ,
694
+ PassMode :: Indirect ( _, None ) => cx . type_ptr_to ( arg. memory_ty ( cx) ) ,
651
695
} ;
652
696
llargument_tys. push ( llarg_ty) ;
653
697
}
654
698
655
699
if self . variadic {
656
- Type :: variadic_func ( & llargument_tys, llreturn_ty)
700
+ cx . type_variadic_func ( & llargument_tys, llreturn_ty)
657
701
} else {
658
- Type :: func ( & llargument_tys, llreturn_ty)
702
+ cx . type_func ( & llargument_tys, llreturn_ty)
659
703
}
660
704
}
661
705
@@ -717,7 +761,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
717
761
}
718
762
}
719
763
720
- fn apply_attrs_callsite ( & self , bx : & Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) {
764
+ fn apply_attrs_callsite ( & self , bx : & mut Builder < ' a , ' ll , ' tcx > , callsite : & ' ll Value ) {
721
765
let mut i = 0 ;
722
766
let mut apply = |attrs : & ArgAttributes | {
723
767
attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
@@ -736,7 +780,7 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
736
780
// by the LLVM verifier.
737
781
if let layout:: Int ( ..) = scalar. value {
738
782
if !scalar. is_bool ( ) {
739
- let range = scalar. valid_range_exclusive ( bx. cx ) ;
783
+ let range = scalar. valid_range_exclusive ( bx. cx ( ) ) ;
740
784
if range. start != range. end {
741
785
bx. range_metadata ( callsite, range) ;
742
786
}
@@ -769,3 +813,29 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
769
813
}
770
814
}
771
815
}
816
+
817
+ impl AbiMethods < ' tcx > for CodegenCx < ' ll , ' tcx > {
818
+ fn new_fn_type ( & self , sig : ty:: FnSig < ' tcx > , extra_args : & [ Ty < ' tcx > ] ) -> FnType < ' tcx , Ty < ' tcx > > {
819
+ FnType :: new ( & self , sig, extra_args)
820
+ }
821
+ fn new_vtable (
822
+ & self ,
823
+ sig : ty:: FnSig < ' tcx > ,
824
+ extra_args : & [ Ty < ' tcx > ]
825
+ ) -> FnType < ' tcx , Ty < ' tcx > > {
826
+ FnType :: new_vtable ( & self , sig, extra_args)
827
+ }
828
+ fn fn_type_of_instance ( & self , instance : & Instance < ' tcx > ) -> FnType < ' tcx , Ty < ' tcx > > {
829
+ FnType :: of_instance ( & self , instance)
830
+ }
831
+ }
832
+
833
+ impl AbiBuilderMethods < ' tcx > for Builder < ' a , ' ll , ' tcx > {
834
+ fn apply_attrs_callsite (
835
+ & mut self ,
836
+ ty : & FnType < ' tcx , Ty < ' tcx > > ,
837
+ callsite : Self :: Value
838
+ ) {
839
+ ty. apply_attrs_callsite ( self , callsite)
840
+ }
841
+ }
0 commit comments