@@ -41,12 +41,12 @@ impl ArgAttributeExt for ArgAttribute {
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,9 +61,6 @@ 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) ) ;
68
65
match self . arg_ext {
69
66
ArgExtension :: None => { }
@@ -77,7 +74,7 @@ impl ArgAttributesExt for ArgAttributes {
77
74
}
78
75
}
79
76
80
- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) {
77
+ fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
81
78
let mut regular = self . regular ;
82
79
unsafe {
83
80
let deref = self . pointee_size . bytes ( ) ;
@@ -100,9 +97,6 @@ impl ArgAttributesExt for ArgAttributes {
100
97
align. bytes ( ) as u32 ,
101
98
) ;
102
99
}
103
- if regular. contains ( ArgAttribute :: ByVal ) {
104
- llvm:: LLVMRustAddByValCallSiteAttr ( callsite, idx. as_uint ( ) , ty. unwrap ( ) ) ;
105
- }
106
100
regular. for_each_kind ( |attr| attr. apply_callsite ( idx, callsite) ) ;
107
101
match self . arg_ext {
108
102
ArgExtension :: None => { }
@@ -285,10 +279,12 @@ impl ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
285
279
PassMode :: Pair ( ..) => {
286
280
OperandValue :: Pair ( next ( ) , next ( ) ) . store ( bx, dst) ;
287
281
}
288
- PassMode :: Indirect ( _, Some ( _) ) => {
282
+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
289
283
OperandValue :: Ref ( next ( ) , Some ( next ( ) ) , self . layout . align . abi ) . store ( bx, dst) ;
290
284
}
291
- PassMode :: Direct ( _) | PassMode :: Indirect ( _, None ) | PassMode :: Cast ( _) => {
285
+ PassMode :: Direct ( _)
286
+ | PassMode :: Indirect { attrs : _, extra_attrs : None , on_stack : _ }
287
+ | PassMode :: Cast ( _) => {
292
288
let next_arg = next ( ) ;
293
289
self . store ( bx, next_arg, dst) ;
294
290
}
@@ -333,14 +329,14 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
333
329
if let PassMode :: Pair ( _, _) = arg. mode { 2 } else { 1 }
334
330
) . sum ( ) ;
335
331
let mut llargument_tys = Vec :: with_capacity (
336
- 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,
337
333
) ;
338
334
339
335
let llreturn_ty = match self . ret . mode {
340
336
PassMode :: Ignore => cx. type_void ( ) ,
341
337
PassMode :: Direct ( _) | PassMode :: Pair ( ..) => self . ret . layout . immediate_llvm_type ( cx) ,
342
338
PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
343
- PassMode :: Indirect ( .. ) => {
339
+ PassMode :: Indirect { .. } => {
344
340
llargument_tys. push ( cx. type_ptr_to ( self . ret . memory_ty ( cx) ) ) ;
345
341
cx. type_void ( )
346
342
}
@@ -360,15 +356,17 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
360
356
llargument_tys. push ( arg. layout . scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
361
357
continue ;
362
358
}
363
- PassMode :: Indirect ( _, Some ( _) ) => {
359
+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
364
360
let ptr_ty = cx. tcx . mk_mut_ptr ( arg. layout . ty ) ;
365
361
let ptr_layout = cx. layout_of ( ptr_ty) ;
366
362
llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 0 , true ) ) ;
367
363
llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
368
364
continue ;
369
365
}
370
366
PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
371
- 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
+ }
372
370
} ;
373
371
llargument_tys. push ( llarg_ty) ;
374
372
}
@@ -420,35 +418,53 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
420
418
}
421
419
422
420
let mut i = 0 ;
423
- let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
424
- 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) ;
425
423
i += 1 ;
424
+ i - 1
426
425
} ;
427
426
match self . ret . mode {
428
427
PassMode :: Direct ( ref attrs) => {
429
- 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
+ apply ( attrs) ;
430
433
}
431
- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( cx) ) ) ,
432
434
_ => { }
433
435
}
434
436
for arg in & self . args {
435
437
if arg. pad . is_some ( ) {
436
- apply ( & ArgAttributes :: new ( ) , None ) ;
438
+ apply ( & ArgAttributes :: new ( ) ) ;
437
439
}
438
440
match arg. mode {
439
441
PassMode :: Ignore => { }
440
- PassMode :: Direct ( ref attrs) | PassMode :: Indirect ( ref attrs, None ) => {
441
- apply ( attrs, Some ( arg. layout . llvm_type ( cx) ) )
442
+ PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
443
+ let i = apply ( attrs) ;
444
+ unsafe {
445
+ llvm:: LLVMRustAddByValAttr (
446
+ llfn,
447
+ llvm:: AttributePlace :: Argument ( i) . as_uint ( ) ,
448
+ arg. layout . llvm_type ( cx) ,
449
+ ) ;
450
+ }
451
+ }
452
+ PassMode :: Direct ( ref attrs)
453
+ | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
454
+ apply ( attrs) ;
442
455
}
443
- PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
444
- apply ( attrs, None ) ;
445
- apply ( extra_attrs, None ) ;
456
+ PassMode :: Indirect { ref attrs, extra_attrs : Some ( ref extra_attrs) , on_stack } => {
457
+ assert ! ( !on_stack) ;
458
+ apply ( attrs) ;
459
+ apply ( extra_attrs) ;
446
460
}
447
461
PassMode :: Pair ( ref a, ref b) => {
448
- apply ( a, None ) ;
449
- apply ( b, None ) ;
462
+ apply ( a) ;
463
+ apply ( b) ;
464
+ }
465
+ PassMode :: Cast ( _) => {
466
+ apply ( & ArgAttributes :: new ( ) ) ;
450
467
}
451
- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
452
468
}
453
469
}
454
470
}
@@ -457,15 +473,19 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
457
473
// FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
458
474
459
475
let mut i = 0 ;
460
- let mut apply = |attrs : & ArgAttributes , ty : Option < & Type > | {
461
- attrs. apply_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite, ty ) ;
476
+ let mut apply = |attrs : & ArgAttributes | {
477
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: Argument ( i) , callsite) ;
462
478
i += 1 ;
479
+ i - 1
463
480
} ;
464
481
match self . ret . mode {
465
482
PassMode :: Direct ( ref attrs) => {
466
- attrs. apply_callsite ( llvm:: AttributePlace :: ReturnValue , callsite, None ) ;
483
+ attrs. apply_attrs_to_callsite ( llvm:: AttributePlace :: ReturnValue , callsite) ;
484
+ }
485
+ PassMode :: Indirect { ref attrs, extra_attrs : _, on_stack } => {
486
+ assert ! ( !on_stack) ;
487
+ apply ( attrs) ;
467
488
}
468
- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( bx) ) ) ,
469
489
_ => { }
470
490
}
471
491
if let abi:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
@@ -483,22 +503,39 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
483
503
}
484
504
for arg in & self . args {
485
505
if arg. pad . is_some ( ) {
486
- apply ( & ArgAttributes :: new ( ) , None ) ;
506
+ apply ( & ArgAttributes :: new ( ) ) ;
487
507
}
488
508
match arg. mode {
489
509
PassMode :: Ignore => { }
490
- PassMode :: Direct ( ref attrs) | PassMode :: Indirect ( ref attrs, None ) => {
491
- apply ( attrs, Some ( arg. layout . llvm_type ( bx) ) )
510
+ PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : true } => {
511
+ let i = apply ( attrs) ;
512
+ unsafe {
513
+ llvm:: LLVMRustAddByValCallSiteAttr (
514
+ callsite,
515
+ llvm:: AttributePlace :: Argument ( i) . as_uint ( ) ,
516
+ arg. layout . llvm_type ( bx) ,
517
+ ) ;
518
+ }
492
519
}
493
- PassMode :: Indirect ( ref attrs, Some ( ref extra_attrs) ) => {
494
- apply ( attrs, None ) ;
495
- apply ( extra_attrs, None ) ;
520
+ PassMode :: Direct ( ref attrs)
521
+ | PassMode :: Indirect { ref attrs, extra_attrs : None , on_stack : false } => {
522
+ apply ( attrs) ;
523
+ }
524
+ PassMode :: Indirect {
525
+ ref attrs,
526
+ extra_attrs : Some ( ref extra_attrs) ,
527
+ on_stack : _,
528
+ } => {
529
+ apply ( attrs) ;
530
+ apply ( extra_attrs) ;
496
531
}
497
532
PassMode :: Pair ( ref a, ref b) => {
498
- apply ( a, None ) ;
499
- apply ( b, None ) ;
533
+ apply ( a) ;
534
+ apply ( b) ;
535
+ }
536
+ PassMode :: Cast ( _) => {
537
+ apply ( & ArgAttributes :: new ( ) ) ;
500
538
}
501
- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
502
539
}
503
540
}
504
541
0 commit comments