@@ -36,17 +36,17 @@ impl ArgAttributeExt for ArgAttribute {
36
36
where
37
37
F : FnMut ( llvm:: Attribute ) ,
38
38
{
39
- for_each_kind ! ( self , f, NoAlias , NoCapture , NonNull , ReadOnly , SExt , StructRet , ZExt , InReg )
39
+ for_each_kind ! ( self , f, NoAlias , NoCapture , NonNull , ReadOnly , InReg )
40
40
}
41
41
}
42
42
43
43
pub trait ArgAttributesExt {
44
- fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value , ty : Option < & Type > ) ;
45
- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) ;
44
+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , llfn : & Value ) ;
45
+ fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) ;
46
46
}
47
47
48
48
impl ArgAttributesExt for ArgAttributes {
49
- fn apply_llfn ( & self , idx : AttributePlace , llfn : & Value , ty : Option < & Type > ) {
49
+ fn apply_attrs_to_llfn ( & self , idx : AttributePlace , llfn : & Value ) {
50
50
let mut regular = self . regular ;
51
51
unsafe {
52
52
let deref = self . pointee_size . bytes ( ) ;
@@ -61,14 +61,20 @@ impl ArgAttributesExt for ArgAttributes {
61
61
if let Some ( align) = self . pointee_align {
62
62
llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
63
63
}
64
- if regular. contains ( ArgAttribute :: ByVal ) {
65
- llvm:: LLVMRustAddByValAttr ( llfn, idx. as_uint ( ) , ty. unwrap ( ) ) ;
66
- }
67
64
regular. for_each_kind ( |attr| attr. apply_llfn ( idx, llfn) ) ;
65
+ match self . arg_ext {
66
+ ArgExtension :: None => { }
67
+ ArgExtension :: Zext => {
68
+ llvm:: Attribute :: ZExt . apply_llfn ( idx, llfn) ;
69
+ }
70
+ ArgExtension :: Sext => {
71
+ llvm:: Attribute :: SExt . apply_llfn ( idx, llfn) ;
72
+ }
73
+ }
68
74
}
69
75
}
70
76
71
- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) {
77
+ fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
72
78
let mut regular = self . regular ;
73
79
unsafe {
74
80
let deref = self . pointee_size . bytes ( ) ;
@@ -91,10 +97,16 @@ impl ArgAttributesExt for ArgAttributes {
91
97
align. bytes ( ) as u32 ,
92
98
) ;
93
99
}
94
- if regular. contains ( ArgAttribute :: ByVal ) {
95
- llvm:: LLVMRustAddByValCallSiteAttr ( callsite, idx. as_uint ( ) , ty. unwrap ( ) ) ;
96
- }
97
100
regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
101
+ match self . arg_ext {
102
+ ArgExtension :: None => { }
103
+ ArgExtension :: Zext => {
104
+ llvm:: Attribute :: ZExt . apply_callsite ( idx, callsite) ;
105
+ }
106
+ ArgExtension :: Sext => {
107
+ llvm:: Attribute :: SExt . apply_callsite ( idx, callsite) ;
108
+ }
109
+ }
98
110
}
99
111
}
100
112
}
@@ -146,7 +158,7 @@ impl LlvmType for CastTarget {
146
158
. prefix
147
159
. iter ( )
148
160
. flat_map ( |option_kind| {
149
- option_kind. map ( |kind| Reg { kind, size : self . prefix_chunk } . llvm_type ( cx) )
161
+ option_kind. map ( |kind| Reg { kind, size : self . prefix_chunk_size } . llvm_type ( cx) )
150
162
} )
151
163
. chain ( ( 0 ..rest_count) . map ( |_| rest_ll_unit) )
152
164
. collect ( ) ;
@@ -267,10 +279,12 @@ impl ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
267
279
PassMode :: Pair ( ..) => {
268
280
OperandValue :: Pair ( next ( ) , next ( ) ) . store ( bx, dst) ;
269
281
}
270
- PassMode :: Indirect ( _, Some ( _) ) => {
282
+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
271
283
OperandValue :: Ref ( next ( ) , Some ( next ( ) ) , self . layout . align . abi ) . store ( bx, dst) ;
272
284
}
273
- PassMode :: Direct ( _) | PassMode :: Indirect ( _, None ) | PassMode :: Cast ( _) => {
285
+ PassMode :: Direct ( _)
286
+ | PassMode :: Indirect { attrs : _, extra_attrs : None , on_stack : _ }
287
+ | PassMode :: Cast ( _) => {
274
288
let next_arg = next ( ) ;
275
289
self . store ( bx, next_arg, dst) ;
276
290
}
@@ -315,14 +329,14 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
315
329
if let PassMode :: Pair ( _, _) = arg. mode { 2 } else { 1 }
316
330
) . sum ( ) ;
317
331
let mut llargument_tys = Vec :: with_capacity (
318
- if let PassMode :: Indirect ( .. ) = self . ret . mode { 1 } else { 0 } + args_capacity,
332
+ if let PassMode :: Indirect { .. } = self . ret . mode { 1 } else { 0 } + args_capacity,
319
333
) ;
320
334
321
335
let llreturn_ty = match self . ret . mode {
322
336
PassMode :: Ignore => cx. type_void ( ) ,
323
337
PassMode :: Direct ( _) | PassMode :: Pair ( ..) => self . ret . layout . immediate_llvm_type ( cx) ,
324
338
PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
325
- PassMode :: Indirect ( .. ) => {
339
+ PassMode :: Indirect { .. } => {
326
340
llargument_tys. push ( cx. type_ptr_to ( self . ret . memory_ty ( cx) ) ) ;
327
341
cx. type_void ( )
328
342
}
@@ -342,15 +356,17 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
342
356
llargument_tys. push ( arg. layout . scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
343
357
continue ;
344
358
}
345
- PassMode :: Indirect ( _, Some ( _) ) => {
359
+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
346
360
let ptr_ty = cx. tcx . mk_mut_ptr ( arg. layout . ty ) ;
347
361
let ptr_layout = cx. layout_of ( ptr_ty) ;
348
362
llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 0 , true ) ) ;
349
363
llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
350
364
continue ;
351
365
}
352
366
PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
353
- PassMode :: Indirect ( _, None ) => cx. type_ptr_to ( arg. memory_ty ( cx) ) ,
367
+ PassMode :: Indirect { attrs : _, extra_attrs : None , on_stack : _ } => {
368
+ cx. type_ptr_to ( arg. memory_ty ( cx) )
369
+ }
354
370
} ;
355
371
llargument_tys. push ( llarg_ty) ;
356
372
}
@@ -402,35 +418,54 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
402
418
}
403
419
404
420
let mut i = 0 ;
405
- let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
406
- attrs. apply_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn, ty ) ;
421
+ let mut apply = |attrs : & ArgAttributes | {
422
+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn) ;
407
423
i += 1 ;
424
+ i - 1
408
425
} ;
409
426
match self . ret . mode {
410
427
PassMode :: Direct ( ref attrs) => {
411
- attrs. apply_llfn ( llvm:: AttributePlace :: ReturnValue , llfn, None ) ;
428
+ attrs. apply_attrs_to_llfn ( llvm:: AttributePlace :: ReturnValue , llfn) ;
429
+ }
430
+ PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
431
+ assert ! ( !on_stack) ;
432
+ let i = apply ( attrs) ;
433
+ llvm:: Attribute :: StructRet . apply_llfn ( llvm:: AttributePlace :: Argument ( i) , llfn) ;
412
434
}
413
- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( cx) ) ) ,
414
435
_ => { }
415
436
}
416
437
for arg in & self . args {
417
438
if arg. pad . is_some ( ) {
418
- apply ( & ArgAttributes :: new ( ) , None ) ;
439
+ apply ( & ArgAttributes :: new ( ) ) ;
419
440
}
420
441
match arg. mode {
421
442
PassMode :: Ignore => { }
422
- PassMode :: Direct ( ref attrs) | PassMode :: Indirect ( ref attrs, None ) => {
423
- apply ( attrs, Some ( arg. layout . llvm_type ( cx) ) )
443
+ PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
444
+ let i = apply ( attrs) ;
445
+ unsafe {
446
+ llvm:: LLVMRustAddByValAttr (
447
+ llfn,
448
+ llvm:: AttributePlace :: Argument ( i) . as_uint ( ) ,
449
+ arg. layout . llvm_type ( cx) ,
450
+ ) ;
451
+ }
424
452
}
425
- PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
426
- apply ( attrs, None ) ;
427
- apply ( extra_attrs, None ) ;
453
+ PassMode :: Direct ( ref attrs)
454
+ | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
455
+ apply ( attrs) ;
456
+ }
457
+ PassMode :: Indirect { ref attrs, extra_attrs : Some ( ref extra_attrs) , on_stack } => {
458
+ assert ! ( !on_stack) ;
459
+ apply ( attrs) ;
460
+ apply ( extra_attrs) ;
428
461
}
429
462
PassMode :: Pair ( ref a, ref b) => {
430
- apply ( a, None ) ;
431
- apply ( b, None ) ;
463
+ apply ( a) ;
464
+ apply ( b) ;
465
+ }
466
+ PassMode :: Cast ( _) => {
467
+ apply ( & ArgAttributes :: new ( ) ) ;
432
468
}
433
- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
434
469
}
435
470
}
436
471
}
@@ -439,15 +474,21 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
439
474
// FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
440
475
441
476
let mut i = 0 ;
442
- let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
443
- attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite, ty ) ;
477
+ let mut apply = |attrs : & ArgAttributes | {
478
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
444
479
i += 1 ;
480
+ i - 1
445
481
} ;
446
482
match self . ret . mode {
447
483
PassMode :: Direct ( ref attrs) => {
448
- attrs. apply_callsite ( llvm:: AttributePlace :: ReturnValue , callsite, None ) ;
484
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: ReturnValue , callsite) ;
485
+ }
486
+ PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
487
+ assert ! ( !on_stack) ;
488
+ let i = apply ( attrs) ;
489
+ llvm:: Attribute :: StructRet
490
+ . apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
449
491
}
450
- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( bx) ) ) ,
451
492
_ => { }
452
493
}
453
494
if let abi:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
@@ -465,22 +506,39 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
465
506
}
466
507
for arg in & self . args {
467
508
if arg. pad . is_some ( ) {
468
- apply ( & ArgAttributes :: new ( ) , None ) ;
509
+ apply ( & ArgAttributes :: new ( ) ) ;
469
510
}
470
511
match arg. mode {
471
512
PassMode :: Ignore => { }
472
- PassMode :: Direct ( ref attrs) | PassMode :: Indirect ( ref attrs, None ) => {
473
- apply ( attrs, Some ( arg. layout . llvm_type ( bx) ) )
513
+ PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
514
+ let i = apply ( attrs) ;
515
+ unsafe {
516
+ llvm:: LLVMRustAddByValCallSiteAttr (
517
+ callsite,
518
+ llvm:: AttributePlace :: Argument ( i) . as_uint ( ) ,
519
+ arg. layout . llvm_type ( bx) ,
520
+ ) ;
521
+ }
474
522
}
475
- PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
476
- apply ( attrs, None ) ;
477
- apply ( extra_attrs, None ) ;
523
+ PassMode :: Direct ( ref attrs)
524
+ | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
525
+ apply ( attrs) ;
526
+ }
527
+ PassMode :: Indirect {
528
+ ref attrs,
529
+ extra_attrs : Some ( ref extra_attrs) ,
530
+ on_stack : _,
531
+ } => {
532
+ apply ( attrs) ;
533
+ apply ( extra_attrs) ;
478
534
}
479
535
PassMode :: Pair ( ref a, ref b) => {
480
- apply ( a, None ) ;
481
- apply ( b, None ) ;
536
+ apply ( a) ;
537
+ apply ( b) ;
538
+ }
539
+ PassMode :: Cast ( _) => {
540
+ apply ( & ArgAttributes :: new ( ) ) ;
482
541
}
483
- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
484
542
}
485
543
}
486
544
0 commit comments