]>
Commit | Line | Data |
---|---|---|
a1dfa0c6 XL |
1 | use super::abi::AbiBuilderMethods; |
2 | use super::asm::AsmBuilderMethods; | |
f035d41b | 3 | use super::coverageinfo::CoverageInfoBuilderMethods; |
a1dfa0c6 XL |
4 | use super::debuginfo::DebugInfoBuilderMethods; |
5 | use super::intrinsic::IntrinsicCallMethods; | |
5099ac24 FG |
6 | use super::misc::MiscMethods; |
7 | use super::type_::{ArgAbiMethods, BaseTypeMethods}; | |
a1dfa0c6 | 8 | use super::{HasCodegen, StaticBuilderMethods}; |
60c5eb7d | 9 | |
dfeec247 | 10 | use crate::common::{ |
5099ac24 | 11 | AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope, TypeKind, |
dfeec247 | 12 | }; |
9fa01778 XL |
13 | use crate::mir::operand::OperandRef; |
14 | use crate::mir::place::PlaceRef; | |
15 | use crate::MemFlags; | |
60c5eb7d | 16 | |
1b1a35ee | 17 | use rustc_middle::ty::layout::{HasParamEnv, TyAndLayout}; |
ba9703b0 | 18 | use rustc_middle::ty::Ty; |
29967ef6 | 19 | use rustc_span::Span; |
2b03887a | 20 | use rustc_target::abi::call::FnAbi; |
c295e0f8 | 21 | use rustc_target::abi::{Abi, Align, Scalar, Size, WrappingRange}; |
60c5eb7d XL |
22 | use rustc_target::spec::HasTargetSpec; |
23 | ||
a1dfa0c6 XL |
24 | #[derive(Copy, Clone)] |
25 | pub enum OverflowOp { | |
26 | Add, | |
27 | Sub, | |
28 | Mul, | |
29 | } | |
30 | ||
dc9dc135 | 31 | pub trait BuilderMethods<'a, 'tcx>: |
a1dfa0c6 | 32 | HasCodegen<'tcx> |
f035d41b | 33 | + CoverageInfoBuilderMethods<'tcx> |
74b04a01 | 34 | + DebugInfoBuilderMethods |
60c5eb7d | 35 | + ArgAbiMethods<'tcx> |
a1dfa0c6 XL |
36 | + AbiBuilderMethods<'tcx> |
37 | + IntrinsicCallMethods<'tcx> | |
38 | + AsmBuilderMethods<'tcx> | |
dc9dc135 | 39 | + StaticBuilderMethods |
48663c56 XL |
40 | + HasParamEnv<'tcx> |
41 | + HasTargetSpec | |
a1dfa0c6 | 42 | { |
17df50a5 XL |
43 | fn build(cx: &'a Self::CodegenCx, llbb: Self::BasicBlock) -> Self; |
44 | ||
a1dfa0c6 | 45 | fn cx(&self) -> &Self::CodegenCx; |
a1dfa0c6 | 46 | fn llbb(&self) -> Self::BasicBlock; |
17df50a5 | 47 | |
29967ef6 | 48 | fn set_span(&mut self, span: Span); |
a1dfa0c6 | 49 | |
17df50a5 XL |
50 | // FIXME(eddyb) replace uses of this with `append_sibling_block`. |
51 | fn append_block(cx: &'a Self::CodegenCx, llfn: Self::Function, name: &str) -> Self::BasicBlock; | |
52 | ||
53 | fn append_sibling_block(&mut self, name: &str) -> Self::BasicBlock; | |
54 | ||
5e7ed085 | 55 | fn switch_to_block(&mut self, llbb: Self::BasicBlock); |
17df50a5 | 56 | |
a1dfa0c6 XL |
57 | fn ret_void(&mut self); |
58 | fn ret(&mut self, v: Self::Value); | |
59 | fn br(&mut self, dest: Self::BasicBlock); | |
60 | fn cond_br( | |
61 | &mut self, | |
62 | cond: Self::Value, | |
63 | then_llbb: Self::BasicBlock, | |
64 | else_llbb: Self::BasicBlock, | |
65 | ); | |
66 | fn switch( | |
67 | &mut self, | |
68 | v: Self::Value, | |
69 | else_llbb: Self::BasicBlock, | |
1b1a35ee | 70 | cases: impl ExactSizeIterator<Item = (u128, Self::BasicBlock)>, |
532ac7d7 | 71 | ); |
a1dfa0c6 XL |
72 | fn invoke( |
73 | &mut self, | |
94222f64 | 74 | llty: Self::Type, |
2b03887a | 75 | fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, |
a1dfa0c6 XL |
76 | llfn: Self::Value, |
77 | args: &[Self::Value], | |
78 | then: Self::BasicBlock, | |
79 | catch: Self::BasicBlock, | |
80 | funclet: Option<&Self::Funclet>, | |
81 | ) -> Self::Value; | |
82 | fn unreachable(&mut self); | |
532ac7d7 | 83 | |
a1dfa0c6 XL |
84 | fn add(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; |
85 | fn fadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
86 | fn fadd_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
87 | fn sub(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
88 | fn fsub(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
89 | fn fsub_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
90 | fn mul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
91 | fn fmul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
92 | fn fmul_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
93 | fn udiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
94 | fn exactudiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
95 | fn sdiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
96 | fn exactsdiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
97 | fn fdiv(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
98 | fn fdiv_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
99 | fn urem(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
100 | fn srem(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
101 | fn frem(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
102 | fn frem_fast(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
103 | fn shl(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
104 | fn lshr(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
105 | fn ashr(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
dc9dc135 XL |
106 | fn unchecked_sadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; |
107 | fn unchecked_uadd(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
108 | fn unchecked_ssub(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
109 | fn unchecked_usub(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
110 | fn unchecked_smul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
111 | fn unchecked_umul(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
a1dfa0c6 XL |
112 | fn and(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; |
113 | fn or(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
114 | fn xor(&mut self, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
115 | fn neg(&mut self, v: Self::Value) -> Self::Value; | |
116 | fn fneg(&mut self, v: Self::Value) -> Self::Value; | |
117 | fn not(&mut self, v: Self::Value) -> Self::Value; | |
118 | ||
119 | fn checked_binop( | |
120 | &mut self, | |
121 | oop: OverflowOp, | |
9fa01778 | 122 | ty: Ty<'_>, |
a1dfa0c6 XL |
123 | lhs: Self::Value, |
124 | rhs: Self::Value, | |
125 | ) -> (Self::Value, Self::Value); | |
126 | ||
1b1a35ee XL |
127 | fn from_immediate(&mut self, val: Self::Value) -> Self::Value; |
128 | fn to_immediate(&mut self, val: Self::Value, layout: TyAndLayout<'_>) -> Self::Value { | |
c295e0f8 | 129 | if let Abi::Scalar(scalar) = layout.abi { |
1b1a35ee XL |
130 | self.to_immediate_scalar(val, scalar) |
131 | } else { | |
132 | val | |
133 | } | |
134 | } | |
c295e0f8 | 135 | fn to_immediate_scalar(&mut self, val: Self::Value, scalar: Scalar) -> Self::Value; |
1b1a35ee | 136 | |
e1599b0c | 137 | fn alloca(&mut self, ty: Self::Type, align: Align) -> Self::Value; |
2b03887a | 138 | fn byte_array_alloca(&mut self, len: Self::Value, align: Align) -> Self::Value; |
a1dfa0c6 | 139 | |
136023e0 XL |
140 | fn load(&mut self, ty: Self::Type, ptr: Self::Value, align: Align) -> Self::Value; |
141 | fn volatile_load(&mut self, ty: Self::Type, ptr: Self::Value) -> Self::Value; | |
142 | fn atomic_load( | |
143 | &mut self, | |
144 | ty: Self::Type, | |
145 | ptr: Self::Value, | |
146 | order: AtomicOrdering, | |
147 | size: Size, | |
148 | ) -> Self::Value; | |
a1dfa0c6 | 149 | fn load_operand(&mut self, place: PlaceRef<'tcx, Self::Value>) |
dfeec247 | 150 | -> OperandRef<'tcx, Self::Value>; |
a1dfa0c6 | 151 | |
dfeec247 | 152 | /// Called for Rvalue::Repeat when the elem is neither a ZST nor optimizable using memset. |
532ac7d7 | 153 | fn write_operand_repeatedly( |
487cf647 | 154 | &mut self, |
532ac7d7 XL |
155 | elem: OperandRef<'tcx, Self::Value>, |
156 | count: u64, | |
157 | dest: PlaceRef<'tcx, Self::Value>, | |
487cf647 | 158 | ); |
532ac7d7 | 159 | |
c295e0f8 | 160 | fn range_metadata(&mut self, load: Self::Value, range: WrappingRange); |
a1dfa0c6 XL |
161 | fn nonnull_metadata(&mut self, load: Self::Value); |
162 | ||
163 | fn store(&mut self, val: Self::Value, ptr: Self::Value, align: Align) -> Self::Value; | |
164 | fn store_with_flags( | |
165 | &mut self, | |
166 | val: Self::Value, | |
167 | ptr: Self::Value, | |
168 | align: Align, | |
169 | flags: MemFlags, | |
170 | ) -> Self::Value; | |
171 | fn atomic_store( | |
172 | &mut self, | |
173 | val: Self::Value, | |
174 | ptr: Self::Value, | |
175 | order: AtomicOrdering, | |
176 | size: Size, | |
177 | ); | |
178 | ||
94222f64 XL |
179 | fn gep(&mut self, ty: Self::Type, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value; |
180 | fn inbounds_gep( | |
181 | &mut self, | |
182 | ty: Self::Type, | |
183 | ptr: Self::Value, | |
184 | indices: &[Self::Value], | |
185 | ) -> Self::Value; | |
186 | fn struct_gep(&mut self, ty: Self::Type, ptr: Self::Value, idx: u64) -> Self::Value; | |
a1dfa0c6 XL |
187 | |
188 | fn trunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
189 | fn sext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
f2b60f7d FG |
190 | fn fptoui_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; |
191 | fn fptosi_sat(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
a1dfa0c6 XL |
192 | fn fptoui(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; |
193 | fn fptosi(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
194 | fn uitofp(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
195 | fn sitofp(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
196 | fn fptrunc(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
197 | fn fpext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
198 | fn ptrtoint(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
199 | fn inttoptr(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
200 | fn bitcast(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
201 | fn intcast(&mut self, val: Self::Value, dest_ty: Self::Type, is_signed: bool) -> Self::Value; | |
202 | fn pointercast(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
203 | ||
5099ac24 FG |
204 | fn cast_float_to_int( |
205 | &mut self, | |
206 | signed: bool, | |
207 | x: Self::Value, | |
208 | dest_ty: Self::Type, | |
209 | ) -> Self::Value { | |
210 | let in_ty = self.cx().val_ty(x); | |
211 | let (float_ty, int_ty) = if self.cx().type_kind(dest_ty) == TypeKind::Vector | |
212 | && self.cx().type_kind(in_ty) == TypeKind::Vector | |
213 | { | |
214 | (self.cx().element_type(in_ty), self.cx().element_type(dest_ty)) | |
215 | } else { | |
216 | (in_ty, dest_ty) | |
217 | }; | |
218 | assert!(matches!(self.cx().type_kind(float_ty), TypeKind::Float | TypeKind::Double)); | |
219 | assert_eq!(self.cx().type_kind(int_ty), TypeKind::Integer); | |
220 | ||
064997fb | 221 | if let Some(false) = self.cx().sess().opts.unstable_opts.saturating_float_casts { |
5099ac24 FG |
222 | return if signed { self.fptosi(x, dest_ty) } else { self.fptoui(x, dest_ty) }; |
223 | } | |
224 | ||
f2b60f7d | 225 | if signed { self.fptosi_sat(x, dest_ty) } else { self.fptoui_sat(x, dest_ty) } |
5099ac24 FG |
226 | } |
227 | ||
a1dfa0c6 XL |
228 | fn icmp(&mut self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; |
229 | fn fcmp(&mut self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value; | |
230 | ||
a1dfa0c6 XL |
231 | fn memcpy( |
232 | &mut self, | |
233 | dst: Self::Value, | |
234 | dst_align: Align, | |
235 | src: Self::Value, | |
236 | src_align: Align, | |
237 | size: Self::Value, | |
238 | flags: MemFlags, | |
239 | ); | |
240 | fn memmove( | |
241 | &mut self, | |
242 | dst: Self::Value, | |
243 | dst_align: Align, | |
244 | src: Self::Value, | |
245 | src_align: Align, | |
246 | size: Self::Value, | |
247 | flags: MemFlags, | |
248 | ); | |
249 | fn memset( | |
250 | &mut self, | |
251 | ptr: Self::Value, | |
252 | fill_byte: Self::Value, | |
253 | size: Self::Value, | |
254 | align: Align, | |
255 | flags: MemFlags, | |
256 | ); | |
257 | ||
a1dfa0c6 XL |
258 | fn select( |
259 | &mut self, | |
260 | cond: Self::Value, | |
261 | then_val: Self::Value, | |
262 | else_val: Self::Value, | |
263 | ) -> Self::Value; | |
264 | ||
265 | fn va_arg(&mut self, list: Self::Value, ty: Self::Type) -> Self::Value; | |
266 | fn extract_element(&mut self, vec: Self::Value, idx: Self::Value) -> Self::Value; | |
a1dfa0c6 | 267 | fn vector_splat(&mut self, num_elts: usize, elt: Self::Value) -> Self::Value; |
a1dfa0c6 XL |
268 | fn extract_value(&mut self, agg_val: Self::Value, idx: u64) -> Self::Value; |
269 | fn insert_value(&mut self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value; | |
270 | ||
5099ac24 FG |
271 | fn set_personality_fn(&mut self, personality: Self::Value); |
272 | ||
273 | // These are used by everyone except msvc | |
f25598a0 FG |
274 | fn cleanup_landing_pad(&mut self, pers_fn: Self::Value) -> (Self::Value, Self::Value); |
275 | fn resume(&mut self, exn0: Self::Value, exn1: Self::Value); | |
5099ac24 FG |
276 | |
277 | // These are used only by msvc | |
a1dfa0c6 | 278 | fn cleanup_pad(&mut self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet; |
5099ac24 | 279 | fn cleanup_ret(&mut self, funclet: &Self::Funclet, unwind: Option<Self::BasicBlock>); |
a1dfa0c6 | 280 | fn catch_pad(&mut self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet; |
a1dfa0c6 XL |
281 | fn catch_switch( |
282 | &mut self, | |
283 | parent: Option<Self::Value>, | |
284 | unwind: Option<Self::BasicBlock>, | |
5099ac24 | 285 | handlers: &[Self::BasicBlock], |
a1dfa0c6 | 286 | ) -> Self::Value; |
a1dfa0c6 XL |
287 | |
288 | fn atomic_cmpxchg( | |
289 | &mut self, | |
290 | dst: Self::Value, | |
291 | cmp: Self::Value, | |
292 | src: Self::Value, | |
293 | order: AtomicOrdering, | |
294 | failure_order: AtomicOrdering, | |
295 | weak: bool, | |
296 | ) -> Self::Value; | |
297 | fn atomic_rmw( | |
298 | &mut self, | |
299 | op: AtomicRmwBinOp, | |
300 | dst: Self::Value, | |
301 | src: Self::Value, | |
302 | order: AtomicOrdering, | |
303 | ) -> Self::Value; | |
304 | fn atomic_fence(&mut self, order: AtomicOrdering, scope: SynchronizationScope); | |
a1dfa0c6 XL |
305 | fn set_invariant_load(&mut self, load: Self::Value); |
306 | ||
a1dfa0c6 XL |
307 | /// Called for `StorageLive` |
308 | fn lifetime_start(&mut self, ptr: Self::Value, size: Size); | |
309 | ||
310 | /// Called for `StorageDead` | |
311 | fn lifetime_end(&mut self, ptr: Self::Value, size: Size); | |
312 | ||
f035d41b XL |
313 | fn instrprof_increment( |
314 | &mut self, | |
315 | fn_name: Self::Value, | |
316 | hash: Self::Value, | |
317 | num_counters: Self::Value, | |
318 | index: Self::Value, | |
3dfed10e | 319 | ); |
f035d41b | 320 | |
a1dfa0c6 XL |
321 | fn call( |
322 | &mut self, | |
94222f64 | 323 | llty: Self::Type, |
2b03887a | 324 | fn_abi: Option<&FnAbi<'tcx, Ty<'tcx>>>, |
a1dfa0c6 XL |
325 | llfn: Self::Value, |
326 | args: &[Self::Value], | |
327 | funclet: Option<&Self::Funclet>, | |
328 | ) -> Self::Value; | |
329 | fn zext(&mut self, val: Self::Value, dest_ty: Self::Type) -> Self::Value; | |
330 | ||
5e7ed085 | 331 | fn do_not_inline(&mut self, llret: Self::Value); |
a1dfa0c6 | 332 | } |