]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/interfaces/builder.rs
Beginning of moving all backend-agnostic code to rustc_codegen_ssa
[rust.git] / src / librustc_codegen_llvm / interfaces / builder.rs
1 // Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2 // file at the top-level directory of this distribution and at
3 // http://rust-lang.org/COPYRIGHT.
4 //
5 // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6 // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7 // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8 // option. This file may not be copied, modified, or distributed
9 // except according to those terms.
10
11 use super::abi::AbiBuilderMethods;
12 use super::asm::AsmBuilderMethods;
13 use super::debuginfo::DebugInfoBuilderMethods;
14 use super::intrinsic::IntrinsicCallMethods;
15 use super::type_::ArgTypeMethods;
16 use super::HasCodegen;
17 use builder::MemFlags;
18 use libc::c_char;
19 use mir::operand::OperandRef;
20 use mir::place::PlaceRef;
21 use rustc::ty::layout::{Align, Size};
22 use rustc_codegen_ssa::common::{
23     AtomicOrdering, AtomicRmwBinOp, IntPredicate, RealPredicate, SynchronizationScope,
24 };
25
26 use std::borrow::Cow;
27 use std::ops::Range;
28 use syntax::ast::AsmDialect;
29
30 pub trait BuilderMethods<'a, 'tcx: 'a>:
31     HasCodegen<'tcx>
32     + DebugInfoBuilderMethods<'tcx>
33     + ArgTypeMethods<'tcx>
34     + AbiBuilderMethods<'tcx>
35     + IntrinsicCallMethods<'tcx>
36     + AsmBuilderMethods<'tcx>
37 {
38     fn new_block<'b>(cx: &'a Self::CodegenCx, llfn: Self::Value, name: &'b str) -> Self;
39     fn with_cx(cx: &'a Self::CodegenCx) -> Self;
40     fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
41     fn cx(&self) -> &Self::CodegenCx;
42     fn llfn(&self) -> Self::Value;
43     fn llbb(&self) -> Self::BasicBlock;
44     fn count_insn(&self, category: &str);
45
46     fn set_value_name(&self, value: Self::Value, name: &str);
47     fn position_at_end(&self, llbb: Self::BasicBlock);
48     fn position_at_start(&self, llbb: Self::BasicBlock);
49     fn ret_void(&self);
50     fn ret(&self, v: Self::Value);
51     fn br(&self, dest: Self::BasicBlock);
52     fn cond_br(&self, cond: Self::Value, then_llbb: Self::BasicBlock, else_llbb: Self::BasicBlock);
53     fn switch(&self, v: Self::Value, else_llbb: Self::BasicBlock, num_cases: usize) -> Self::Value;
54     fn invoke(
55         &self,
56         llfn: Self::Value,
57         args: &[Self::Value],
58         then: Self::BasicBlock,
59         catch: Self::BasicBlock,
60         funclet: Option<&Self::Funclet>,
61     ) -> Self::Value;
62     fn unreachable(&self);
63     fn add(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
64     fn fadd(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
65     fn fadd_fast(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
66     fn sub(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
67     fn fsub(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
68     fn fsub_fast(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
69     fn mul(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
70     fn fmul(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
71     fn fmul_fast(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
72     fn udiv(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
73     fn exactudiv(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
74     fn sdiv(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
75     fn exactsdiv(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
76     fn fdiv(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
77     fn fdiv_fast(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
78     fn urem(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
79     fn srem(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
80     fn frem(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
81     fn frem_fast(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
82     fn shl(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
83     fn lshr(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
84     fn ashr(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
85     fn and(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
86     fn or(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
87     fn xor(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
88     fn neg(&self, v: Self::Value) -> Self::Value;
89     fn fneg(&self, v: Self::Value) -> Self::Value;
90     fn not(&self, v: Self::Value) -> Self::Value;
91
92     fn alloca(&self, ty: Self::Type, name: &str, align: Align) -> Self::Value;
93     fn dynamic_alloca(&self, ty: Self::Type, name: &str, align: Align) -> Self::Value;
94     fn array_alloca(
95         &self,
96         ty: Self::Type,
97         len: Self::Value,
98         name: &str,
99         align: Align,
100     ) -> Self::Value;
101
102     fn load(&self, ptr: Self::Value, align: Align) -> Self::Value;
103     fn volatile_load(&self, ptr: Self::Value) -> Self::Value;
104     fn atomic_load(&self, ptr: Self::Value, order: AtomicOrdering, size: Size) -> Self::Value;
105     fn load_operand(&self, place: PlaceRef<'tcx, Self::Value>) -> OperandRef<'tcx, Self::Value>;
106
107     fn range_metadata(&self, load: Self::Value, range: Range<u128>);
108     fn nonnull_metadata(&self, load: Self::Value);
109
110     fn store(&self, val: Self::Value, ptr: Self::Value, align: Align) -> Self::Value;
111     fn store_with_flags(
112         &self,
113         val: Self::Value,
114         ptr: Self::Value,
115         align: Align,
116         flags: MemFlags,
117     ) -> Self::Value;
118     fn atomic_store(&self, val: Self::Value, ptr: Self::Value, order: AtomicOrdering, size: Size);
119
120     fn gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
121     fn inbounds_gep(&self, ptr: Self::Value, indices: &[Self::Value]) -> Self::Value;
122     fn struct_gep(&self, ptr: Self::Value, idx: u64) -> Self::Value;
123
124     fn trunc(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
125     fn sext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
126     fn fptoui(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
127     fn fptosi(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
128     fn uitofp(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
129     fn sitofp(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
130     fn fptrunc(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
131     fn fpext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
132     fn ptrtoint(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
133     fn inttoptr(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
134     fn bitcast(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
135     fn intcast(&self, val: Self::Value, dest_ty: Self::Type, is_signed: bool) -> Self::Value;
136     fn pointercast(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
137
138     fn icmp(&self, op: IntPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
139     fn fcmp(&self, op: RealPredicate, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
140
141     fn empty_phi(&self, ty: Self::Type) -> Self::Value;
142     fn phi(&self, ty: Self::Type, vals: &[Self::Value], bbs: &[Self::BasicBlock]) -> Self::Value;
143     fn inline_asm_call(
144         &self,
145         asm: *const c_char,
146         cons: *const c_char,
147         inputs: &[Self::Value],
148         output: Self::Type,
149         volatile: bool,
150         alignstack: bool,
151         dia: AsmDialect,
152     ) -> Option<Self::Value>;
153
154     fn memcpy(
155         &self,
156         dst: Self::Value,
157         dst_align: Align,
158         src: Self::Value,
159         src_align: Align,
160         size: Self::Value,
161         flags: MemFlags,
162     );
163     fn memmove(
164         &self,
165         dst: Self::Value,
166         dst_align: Align,
167         src: Self::Value,
168         src_align: Align,
169         size: Self::Value,
170         flags: MemFlags,
171     );
172     fn memset(
173         &self,
174         ptr: Self::Value,
175         fill_byte: Self::Value,
176         size: Self::Value,
177         align: Align,
178         flags: MemFlags,
179     );
180
181     fn minnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
182     fn maxnum(&self, lhs: Self::Value, rhs: Self::Value) -> Self::Value;
183     fn select(
184         &self,
185         cond: Self::Value,
186         then_val: Self::Value,
187         else_val: Self::Value,
188     ) -> Self::Value;
189
190     fn va_arg(&self, list: Self::Value, ty: Self::Type) -> Self::Value;
191     fn extract_element(&self, vec: Self::Value, idx: Self::Value) -> Self::Value;
192     fn insert_element(&self, vec: Self::Value, elt: Self::Value, idx: Self::Value) -> Self::Value;
193     fn shuffle_vector(&self, v1: Self::Value, v2: Self::Value, mask: Self::Value) -> Self::Value;
194     fn vector_splat(&self, num_elts: usize, elt: Self::Value) -> Self::Value;
195     fn vector_reduce_fadd_fast(&self, acc: Self::Value, src: Self::Value) -> Self::Value;
196     fn vector_reduce_fmul_fast(&self, acc: Self::Value, src: Self::Value) -> Self::Value;
197     fn vector_reduce_add(&self, src: Self::Value) -> Self::Value;
198     fn vector_reduce_mul(&self, src: Self::Value) -> Self::Value;
199     fn vector_reduce_and(&self, src: Self::Value) -> Self::Value;
200     fn vector_reduce_or(&self, src: Self::Value) -> Self::Value;
201     fn vector_reduce_xor(&self, src: Self::Value) -> Self::Value;
202     fn vector_reduce_fmin(&self, src: Self::Value) -> Self::Value;
203     fn vector_reduce_fmax(&self, src: Self::Value) -> Self::Value;
204     fn vector_reduce_fmin_fast(&self, src: Self::Value) -> Self::Value;
205     fn vector_reduce_fmax_fast(&self, src: Self::Value) -> Self::Value;
206     fn vector_reduce_min(&self, src: Self::Value, is_signed: bool) -> Self::Value;
207     fn vector_reduce_max(&self, src: Self::Value, is_signed: bool) -> Self::Value;
208     fn extract_value(&self, agg_val: Self::Value, idx: u64) -> Self::Value;
209     fn insert_value(&self, agg_val: Self::Value, elt: Self::Value, idx: u64) -> Self::Value;
210
211     fn landing_pad(&self, ty: Self::Type, pers_fn: Self::Value, num_clauses: usize) -> Self::Value;
212     fn add_clause(&self, landing_pad: Self::Value, clause: Self::Value);
213     fn set_cleanup(&self, landing_pad: Self::Value);
214     fn resume(&self, exn: Self::Value) -> Self::Value;
215     fn cleanup_pad(&self, parent: Option<Self::Value>, args: &[Self::Value]) -> Self::Funclet;
216     fn cleanup_ret(&self, funclet: &Self::Funclet, unwind: Option<Self::BasicBlock>)
217         -> Self::Value;
218     fn catch_pad(&self, parent: Self::Value, args: &[Self::Value]) -> Self::Funclet;
219     fn catch_ret(&self, funclet: &Self::Funclet, unwind: Self::BasicBlock) -> Self::Value;
220     fn catch_switch(
221         &self,
222         parent: Option<Self::Value>,
223         unwind: Option<Self::BasicBlock>,
224         num_handlers: usize,
225     ) -> Self::Value;
226     fn add_handler(&self, catch_switch: Self::Value, handler: Self::BasicBlock);
227     fn set_personality_fn(&self, personality: Self::Value);
228
229     fn atomic_cmpxchg(
230         &self,
231         dst: Self::Value,
232         cmp: Self::Value,
233         src: Self::Value,
234         order: AtomicOrdering,
235         failure_order: AtomicOrdering,
236         weak: bool,
237     ) -> Self::Value;
238     fn atomic_rmw(
239         &self,
240         op: AtomicRmwBinOp,
241         dst: Self::Value,
242         src: Self::Value,
243         order: AtomicOrdering,
244     ) -> Self::Value;
245     fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope);
246     fn add_case(&self, s: Self::Value, on_val: Self::Value, dest: Self::BasicBlock);
247     fn add_incoming_to_phi(&self, phi: Self::Value, val: Self::Value, bb: Self::BasicBlock);
248     fn set_invariant_load(&self, load: Self::Value);
249
250     /// Returns the ptr value that should be used for storing `val`.
251     fn check_store(&self, val: Self::Value, ptr: Self::Value) -> Self::Value;
252
253     /// Returns the args that should be used for a call to `llfn`.
254     fn check_call<'b>(
255         &self,
256         typ: &str,
257         llfn: Self::Value,
258         args: &'b [Self::Value],
259     ) -> Cow<'b, [Self::Value]>
260     where
261         [Self::Value]: ToOwned;
262     fn lifetime_start(&self, ptr: Self::Value, size: Size);
263     fn lifetime_end(&self, ptr: Self::Value, size: Size);
264
265     /// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
266     /// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
267     /// and the intrinsic for `lt` and passes them to `emit`, which is in
268     /// charge of generating code to call the passed intrinsic on whatever
269     /// block of generated code is targeted for the intrinsic.
270     ///
271     /// If LLVM lifetime intrinsic support is disabled (i.e.  optimizations
272     /// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
273     fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: Self::Value, size: Size);
274
275     fn call(
276         &self,
277         llfn: Self::Value,
278         args: &[Self::Value],
279         funclet: Option<&Self::Funclet>,
280     ) -> Self::Value;
281     fn zext(&self, val: Self::Value, dest_ty: Self::Type) -> Self::Value;
282
283     fn delete_basic_block(&self, bb: Self::BasicBlock);
284     fn do_not_inline(&self, llret: Self::Value);
285 }