@@ -80,69 +80,86 @@ impl PassMode {
80
80
}
81
81
82
82
pub ( super ) fn get_pass_mode < ' tcx > ( tcx : TyCtxt < ' tcx > , layout : TyAndLayout < ' tcx > ) -> PassMode {
83
+ let mut arg_abi = ArgAbi :: new ( & tcx, layout, |_, _, _| ArgAttributes :: new ( ) ) ;
83
84
if layout. is_zst ( ) {
84
85
// WARNING zst arguments must never be passed, as that will break CastKind::ClosureFnPointer
85
- PassMode :: NoPass
86
- } else {
87
- let arg_abi = ArgAbi :: new ( & tcx, layout, |_, _, _| ArgAttributes :: new ( ) ) ;
88
- match arg_abi. mode {
89
- RustcPassMode :: Ignore => PassMode :: NoPass ,
90
- RustcPassMode :: Direct ( _) => match & arg_abi. layout . abi {
91
- Abi :: Scalar ( scalar) => PassMode :: ByVal ( scalar_to_clif_type ( tcx, scalar. clone ( ) ) ) ,
92
- // FIXME implement Vector Abi in a cg_llvm compatible way
93
- Abi :: Vector { .. } => {
94
- if let Some ( vector_ty) = crate :: intrinsics:: clif_vector_type ( tcx, arg_abi. layout ) {
95
- PassMode :: ByVal ( vector_ty)
96
- } else {
97
- PassMode :: ByRef {
98
- size : Some ( arg_abi. layout . size ) ,
99
- }
100
- }
101
- }
102
- _ => unreachable ! ( "{:?}" , arg_abi. layout. abi)
103
- } ,
104
- RustcPassMode :: Pair ( _, _) => match & arg_abi. layout . abi {
105
- Abi :: ScalarPair ( a, b) => {
106
- let a = scalar_to_clif_type ( tcx, a. clone ( ) ) ;
107
- let b = scalar_to_clif_type ( tcx, b. clone ( ) ) ;
108
- if a == types:: I128 && b == types:: I128 {
109
- // Returning (i128, i128) by-val-pair would take 4 regs, while only 3 are
110
- // available on x86_64. Cranelift gets confused when too many return params
111
- // are used.
112
- PassMode :: ByRef {
113
- size : Some ( arg_abi. layout . size ) ,
114
- }
115
- } else {
116
- PassMode :: ByValPair ( a, b)
117
- }
86
+ arg_abi. mode = RustcPassMode :: Ignore ;
87
+ }
88
+ match arg_abi. mode {
89
+ RustcPassMode :: Ignore => { }
90
+ RustcPassMode :: Direct ( _) => match & arg_abi. layout . abi {
91
+ Abi :: Scalar ( _) => { } ,
92
+ // FIXME implement Vector Abi in a cg_llvm compatible way
93
+ Abi :: Vector { .. } => {
94
+ if crate :: intrinsics:: clif_vector_type ( tcx, arg_abi. layout ) . is_none ( ) {
95
+ arg_abi. mode = RustcPassMode :: Indirect {
96
+ attrs : ArgAttributes :: new ( ) ,
97
+ extra_attrs : None ,
98
+ on_stack : false ,
99
+ } ;
118
100
}
119
- _ => unreachable ! ( "{:?}" , arg_abi. layout. abi)
120
- } ,
121
- RustcPassMode :: Cast ( _) | RustcPassMode :: Indirect {
122
- attrs : _,
123
- extra_attrs : None ,
124
- on_stack : false ,
125
- } => PassMode :: ByRef {
126
- size : Some ( arg_abi. layout . size ) ,
127
- } ,
128
- RustcPassMode :: Indirect {
129
- attrs : _,
130
- extra_attrs,
131
- on_stack : true ,
132
- } => {
133
- assert ! ( extra_attrs. is_none( ) ) ;
134
- PassMode :: ByRef {
135
- size : Some ( arg_abi. layout . size )
101
+ }
102
+ _ => unreachable ! ( "{:?}" , arg_abi. layout. abi)
103
+ } ,
104
+ RustcPassMode :: Pair ( _, _) => match & arg_abi. layout . abi {
105
+ Abi :: ScalarPair ( a, b) => {
106
+ let a = scalar_to_clif_type ( tcx, a. clone ( ) ) ;
107
+ let b = scalar_to_clif_type ( tcx, b. clone ( ) ) ;
108
+ if a == types:: I128 && b == types:: I128 {
109
+ arg_abi. mode = RustcPassMode :: Indirect {
110
+ attrs : ArgAttributes :: new ( ) ,
111
+ extra_attrs : None ,
112
+ on_stack : false ,
113
+ } ;
136
114
}
137
115
}
138
- RustcPassMode :: Indirect {
139
- attrs : _,
140
- extra_attrs : Some ( _) ,
141
- on_stack : false ,
142
- } => PassMode :: ByRef {
143
- size : None ,
144
- } ,
116
+ _ => unreachable ! ( "{:?}" , arg_abi. layout. abi)
117
+ } ,
118
+ _ => { }
119
+ }
120
+ match arg_abi. mode {
121
+ RustcPassMode :: Ignore => PassMode :: NoPass ,
122
+ RustcPassMode :: Direct ( _) => match & arg_abi. layout . abi {
123
+ Abi :: Scalar ( scalar) => PassMode :: ByVal ( scalar_to_clif_type ( tcx, scalar. clone ( ) ) ) ,
124
+ // FIXME implement Vector Abi in a cg_llvm compatible way
125
+ Abi :: Vector { .. } => {
126
+ let vector_ty = crate :: intrinsics:: clif_vector_type ( tcx, arg_abi. layout ) . unwrap ( ) ;
127
+ PassMode :: ByVal ( vector_ty)
128
+ }
129
+ _ => unreachable ! ( "{:?}" , arg_abi. layout. abi)
130
+ } ,
131
+ RustcPassMode :: Pair ( _, _) => match & arg_abi. layout . abi {
132
+ Abi :: ScalarPair ( a, b) => {
133
+ let a = scalar_to_clif_type ( tcx, a. clone ( ) ) ;
134
+ let b = scalar_to_clif_type ( tcx, b. clone ( ) ) ;
135
+ PassMode :: ByValPair ( a, b)
136
+ }
137
+ _ => unreachable ! ( "{:?}" , arg_abi. layout. abi)
138
+ } ,
139
+ RustcPassMode :: Cast ( _) | RustcPassMode :: Indirect {
140
+ attrs : _,
141
+ extra_attrs : None ,
142
+ on_stack : false ,
143
+ } => PassMode :: ByRef {
144
+ size : Some ( arg_abi. layout . size ) ,
145
+ } ,
146
+ RustcPassMode :: Indirect {
147
+ attrs : _,
148
+ extra_attrs,
149
+ on_stack : true ,
150
+ } => {
151
+ assert ! ( extra_attrs. is_none( ) ) ;
152
+ PassMode :: ByRef {
153
+ size : Some ( arg_abi. layout . size )
154
+ }
145
155
}
156
+ RustcPassMode :: Indirect {
157
+ attrs : _,
158
+ extra_attrs : Some ( _) ,
159
+ on_stack : false ,
160
+ } => PassMode :: ByRef {
161
+ size : None ,
162
+ } ,
146
163
}
147
164
}
148
165
0 commit comments