@@ -36,17 +36,17 @@ impl ArgAttributeExt for ArgAttribute {
3636 where
3737 F : FnMut ( llvm:: Attribute ) ,
3838 {
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 )
4040 }
4141}
4242
4343pub 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 ) ;
4646}
4747
4848impl 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 ) {
5050 let mut regular = self . regular ;
5151 unsafe {
5252 let deref = self . pointee_size . bytes ( ) ;
@@ -61,14 +61,20 @@ impl ArgAttributesExt for ArgAttributes {
6161 if let Some ( align) = self . pointee_align {
6262 llvm:: LLVMRustAddAlignmentAttr ( llfn, idx. as_uint ( ) , align. bytes ( ) as u32 ) ;
6363 }
64- if regular. contains ( ArgAttribute :: ByVal ) {
65- llvm:: LLVMRustAddByValAttr ( llfn, idx. as_uint ( ) , ty. unwrap ( ) ) ;
66- }
6764 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+ }
6874 }
6975 }
7076
71- fn apply_callsite ( & self , idx : AttributePlace , callsite : & Value , ty : Option < & Type > ) {
77+ fn apply_attrs_to_callsite ( & self , idx : AttributePlace , callsite : & Value ) {
7278 let mut regular = self . regular ;
7379 unsafe {
7480 let deref = self . pointee_size . bytes ( ) ;
@@ -91,10 +97,16 @@ impl ArgAttributesExt for ArgAttributes {
9197 align. bytes ( ) as u32 ,
9298 ) ;
9399 }
94- if regular. contains ( ArgAttribute :: ByVal ) {
95- llvm:: LLVMRustAddByValCallSiteAttr ( callsite, idx. as_uint ( ) , ty. unwrap ( ) ) ;
96- }
97100 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+ }
98110 }
99111 }
100112}
@@ -146,7 +158,7 @@ impl LlvmType for CastTarget {
146158 . prefix
147159 . iter ( )
148160 . 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) )
150162 } )
151163 . chain ( ( 0 ..rest_count) . map ( |_| rest_ll_unit) )
152164 . collect ( ) ;
@@ -267,10 +279,12 @@ impl ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
267279 PassMode :: Pair ( ..) => {
268280 OperandValue :: Pair ( next ( ) , next ( ) ) . store ( bx, dst) ;
269281 }
270- PassMode :: Indirect ( _, Some ( _) ) => {
282+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
271283 OperandValue :: Ref ( next ( ) , Some ( next ( ) ) , self . layout . align . abi ) . store ( bx, dst) ;
272284 }
273- PassMode :: Direct ( _) | PassMode :: Indirect ( _, None ) | PassMode :: Cast ( _) => {
285+ PassMode :: Direct ( _)
286+ | PassMode :: Indirect { attrs : _, extra_attrs : None , on_stack : _ }
287+ | PassMode :: Cast ( _) => {
274288 let next_arg = next ( ) ;
275289 self . store ( bx, next_arg, dst) ;
276290 }
@@ -315,14 +329,14 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
315329 if let PassMode :: Pair ( _, _) = arg. mode { 2 } else { 1 }
316330 ) . sum ( ) ;
317331 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,
319333 ) ;
320334
321335 let llreturn_ty = match self . ret . mode {
322336 PassMode :: Ignore => cx. type_void ( ) ,
323337 PassMode :: Direct ( _) | PassMode :: Pair ( ..) => self . ret . layout . immediate_llvm_type ( cx) ,
324338 PassMode :: Cast ( cast) => cast. llvm_type ( cx) ,
325- PassMode :: Indirect ( .. ) => {
339+ PassMode :: Indirect { .. } => {
326340 llargument_tys. push ( cx. type_ptr_to ( self . ret . memory_ty ( cx) ) ) ;
327341 cx. type_void ( )
328342 }
@@ -342,15 +356,17 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
342356 llargument_tys. push ( arg. layout . scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
343357 continue ;
344358 }
345- PassMode :: Indirect ( _, Some ( _) ) => {
359+ PassMode :: Indirect { attrs : _, extra_attrs : Some ( _) , on_stack : _ } => {
346360 let ptr_ty = cx. tcx . mk_mut_ptr ( arg. layout . ty ) ;
347361 let ptr_layout = cx. layout_of ( ptr_ty) ;
348362 llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 0 , true ) ) ;
349363 llargument_tys. push ( ptr_layout. scalar_pair_element_llvm_type ( cx, 1 , true ) ) ;
350364 continue ;
351365 }
352366 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+ }
354370 } ;
355371 llargument_tys. push ( llarg_ty) ;
356372 }
@@ -402,35 +418,54 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
402418 }
403419
404420 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) ;
407423 i += 1 ;
424+ i - 1
408425 } ;
409426 match self . ret . mode {
410427 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) ;
412434 }
413- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( cx) ) ) ,
414435 _ => { }
415436 }
416437 for arg in & self . args {
417438 if arg. pad . is_some ( ) {
418- apply ( & ArgAttributes :: new ( ) , None ) ;
439+ apply ( & ArgAttributes :: new ( ) ) ;
419440 }
420441 match arg. mode {
421442 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+ }
424452 }
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) ;
428461 }
429462 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 ( ) ) ;
432468 }
433- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
434469 }
435470 }
436471 }
@@ -439,15 +474,21 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
439474 // FIXME(wesleywiser, eddyb): We should apply `nounwind` and `noreturn` as appropriate to this callsite.
440475
441476 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) ;
444479 i += 1 ;
480+ i - 1
445481 } ;
446482 match self . ret . mode {
447483 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) ;
449491 }
450- PassMode :: Indirect ( ref attrs, _) => apply ( attrs, Some ( self . ret . layout . llvm_type ( bx) ) ) ,
451492 _ => { }
452493 }
453494 if let abi:: Abi :: Scalar ( ref scalar) = self . ret . layout . abi {
@@ -465,22 +506,39 @@ impl<'tcx> FnAbiLlvmExt<'tcx> for FnAbi<'tcx, Ty<'tcx>> {
465506 }
466507 for arg in & self . args {
467508 if arg. pad . is_some ( ) {
468- apply ( & ArgAttributes :: new ( ) , None ) ;
509+ apply ( & ArgAttributes :: new ( ) ) ;
469510 }
470511 match arg. mode {
471512 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+ }
474522 }
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) ;
478534 }
479535 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 ( ) ) ;
482541 }
483- PassMode :: Cast ( _) => apply ( & ArgAttributes :: new ( ) , None ) ,
484542 }
485543 }
486544
0 commit comments