]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/builder.rs
Reduced line length to pass tidy
[rust.git] / src / librustc_codegen_llvm / builder.rs
1 // Copyright 2013 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 llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope, AsmDialect};
12 use llvm::{IntPredicate, RealPredicate, False, OperandBundleDef};
13 use llvm::{self, BasicBlock};
14 use common::*;
15 use type_::Type;
16 use value::Value;
17 use libc::{c_uint, c_char};
18 use rustc::ty::TyCtxt;
19 use rustc::ty::layout::{Align, Size};
20 use rustc::session::{config, Session};
21 use rustc_data_structures::small_c_str::SmallCStr;
22
23 use std::borrow::Cow;
24 use std::ops::Range;
25 use std::ptr;
26
27 // All Builders must have an llfn associated with them
28 #[must_use]
29 pub struct Builder<'a, 'll: 'a, 'tcx: 'll, V: 'll = &'ll Value> {
30     pub llbuilder: &'ll mut llvm::Builder<'ll>,
31     pub cx: &'a CodegenCx<'ll, 'tcx, V>,
32 }
33
34 impl<V> Drop for Builder<'_, '_, '_, V> {
35     fn drop(&mut self) {
36         unsafe {
37             llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
38         }
39     }
40 }
41
42 // This is a really awful way to get a zero-length c-string, but better (and a
43 // lot more efficient) than doing str::as_c_str("", ...) every time.
44 fn noname() -> *const c_char {
45     static CNULL: c_char = 0;
46     &CNULL
47 }
48
49 bitflags! {
50     pub struct MemFlags: u8 {
51         const VOLATILE = 1 << 0;
52         const NONTEMPORAL = 1 << 1;
53         const UNALIGNED = 1 << 2;
54     }
55 }
56
57 impl Builder<'a, 'll, 'tcx> {
58     pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: &'ll Value, name: &'b str) -> Self {
59         let bx = Builder::with_cx(cx);
60         let llbb = unsafe {
61             let name = SmallCStr::new(name);
62             llvm::LLVMAppendBasicBlockInContext(
63                 cx.llcx,
64                 llfn,
65                 name.as_ptr()
66             )
67         };
68         bx.position_at_end(llbb);
69         bx
70     }
71
72     pub fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
73         // Create a fresh builder from the crate context.
74         let llbuilder = unsafe {
75             llvm::LLVMCreateBuilderInContext(cx.llcx)
76         };
77         Builder {
78             llbuilder,
79             cx,
80         }
81     }
82
83     pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'll, 'tcx> {
84         Builder::new_block(self.cx, self.llfn(), name)
85     }
86
87     pub fn sess(&self) -> &Session {
88         self.cx.sess()
89     }
90
91     pub fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx> {
92         self.cx.tcx
93     }
94
95     pub fn llfn(&self) -> &'ll Value {
96         unsafe {
97             llvm::LLVMGetBasicBlockParent(self.llbb())
98         }
99     }
100
101     pub fn llbb(&self) -> &'ll BasicBlock {
102         unsafe {
103             llvm::LLVMGetInsertBlock(self.llbuilder)
104         }
105     }
106
107     fn count_insn(&self, category: &str) {
108         if self.cx.sess().codegen_stats() {
109             self.cx.stats.borrow_mut().n_llvm_insns += 1;
110         }
111         if self.cx.sess().count_llvm_insns() {
112             *self.cx.stats
113                     .borrow_mut()
114                     .llvm_insns
115                     .entry(category.to_string())
116                     .or_insert(0) += 1;
117         }
118     }
119
120     pub fn set_value_name(&self, value: &'ll Value, name: &str) {
121         let cname = SmallCStr::new(name);
122         unsafe {
123             llvm::LLVMSetValueName(value, cname.as_ptr());
124         }
125     }
126
127     pub fn position_at_end(&self, llbb: &'ll BasicBlock) {
128         unsafe {
129             llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
130         }
131     }
132
133     pub fn position_at_start(&self, llbb: &'ll BasicBlock) {
134         unsafe {
135             llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
136         }
137     }
138
139     pub fn ret_void(&self) {
140         self.count_insn("retvoid");
141         unsafe {
142             llvm::LLVMBuildRetVoid(self.llbuilder);
143         }
144     }
145
146     pub fn ret(&self, v: &'ll Value) {
147         self.count_insn("ret");
148         unsafe {
149             llvm::LLVMBuildRet(self.llbuilder, v);
150         }
151     }
152
153     pub fn br(&self, dest: &'ll BasicBlock) {
154         self.count_insn("br");
155         unsafe {
156             llvm::LLVMBuildBr(self.llbuilder, dest);
157         }
158     }
159
160     pub fn cond_br(
161         &self,
162         cond: &'ll Value,
163         then_llbb: &'ll BasicBlock,
164         else_llbb: &'ll BasicBlock,
165     ) {
166         self.count_insn("condbr");
167         unsafe {
168             llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb);
169         }
170     }
171
172     pub fn switch(
173         &self,
174         v: &'ll Value,
175         else_llbb: &'ll BasicBlock,
176         num_cases: usize,
177     ) -> &'ll Value {
178         unsafe {
179             llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, num_cases as c_uint)
180         }
181     }
182
183     pub fn invoke(&self,
184                   llfn: &'ll Value,
185                   args: &[&'ll Value],
186                   then: &'ll BasicBlock,
187                   catch: &'ll BasicBlock,
188                   bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
189         self.count_insn("invoke");
190
191         debug!("Invoke {:?} with args ({:?})",
192                llfn,
193                args);
194
195         let args = self.check_call("invoke", llfn, args);
196         let bundle = bundle.map(|b| &*b.raw);
197
198         unsafe {
199             llvm::LLVMRustBuildInvoke(self.llbuilder,
200                                       llfn,
201                                       args.as_ptr(),
202                                       args.len() as c_uint,
203                                       then,
204                                       catch,
205                                       bundle,
206                                       noname())
207         }
208     }
209
210     pub fn unreachable(&self) {
211         self.count_insn("unreachable");
212         unsafe {
213             llvm::LLVMBuildUnreachable(self.llbuilder);
214         }
215     }
216
217     /* Arithmetic */
218     pub fn add(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
219         self.count_insn("add");
220         unsafe {
221             llvm::LLVMBuildAdd(self.llbuilder, lhs, rhs, noname())
222         }
223     }
224
225     pub fn fadd(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
226         self.count_insn("fadd");
227         unsafe {
228             llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname())
229         }
230     }
231
232     pub fn fadd_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
233         self.count_insn("fadd");
234         unsafe {
235             let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, noname());
236             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
237             instr
238         }
239     }
240
241     pub fn sub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
242         self.count_insn("sub");
243         unsafe {
244             llvm::LLVMBuildSub(self.llbuilder, lhs, rhs, noname())
245         }
246     }
247
248     pub fn fsub(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
249         self.count_insn("fsub");
250         unsafe {
251             llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname())
252         }
253     }
254
255     pub fn fsub_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
256         self.count_insn("fsub");
257         unsafe {
258             let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, noname());
259             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
260             instr
261         }
262     }
263
264     pub fn mul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
265         self.count_insn("mul");
266         unsafe {
267             llvm::LLVMBuildMul(self.llbuilder, lhs, rhs, noname())
268         }
269     }
270
271     pub fn fmul(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
272         self.count_insn("fmul");
273         unsafe {
274             llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname())
275         }
276     }
277
278     pub fn fmul_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
279         self.count_insn("fmul");
280         unsafe {
281             let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, noname());
282             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
283             instr
284         }
285     }
286
287
288     pub fn udiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
289         self.count_insn("udiv");
290         unsafe {
291             llvm::LLVMBuildUDiv(self.llbuilder, lhs, rhs, noname())
292         }
293     }
294
295     pub fn exactudiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
296         self.count_insn("exactudiv");
297         unsafe {
298             llvm::LLVMBuildExactUDiv(self.llbuilder, lhs, rhs, noname())
299         }
300     }
301
302     pub fn sdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
303         self.count_insn("sdiv");
304         unsafe {
305             llvm::LLVMBuildSDiv(self.llbuilder, lhs, rhs, noname())
306         }
307     }
308
309     pub fn exactsdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
310         self.count_insn("exactsdiv");
311         unsafe {
312             llvm::LLVMBuildExactSDiv(self.llbuilder, lhs, rhs, noname())
313         }
314     }
315
316     pub fn fdiv(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
317         self.count_insn("fdiv");
318         unsafe {
319             llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname())
320         }
321     }
322
323     pub fn fdiv_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
324         self.count_insn("fdiv");
325         unsafe {
326             let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, noname());
327             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
328             instr
329         }
330     }
331
332     pub fn urem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
333         self.count_insn("urem");
334         unsafe {
335             llvm::LLVMBuildURem(self.llbuilder, lhs, rhs, noname())
336         }
337     }
338
339     pub fn srem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
340         self.count_insn("srem");
341         unsafe {
342             llvm::LLVMBuildSRem(self.llbuilder, lhs, rhs, noname())
343         }
344     }
345
346     pub fn frem(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
347         self.count_insn("frem");
348         unsafe {
349             llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname())
350         }
351     }
352
353     pub fn frem_fast(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
354         self.count_insn("frem");
355         unsafe {
356             let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, noname());
357             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
358             instr
359         }
360     }
361
362     pub fn shl(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
363         self.count_insn("shl");
364         unsafe {
365             llvm::LLVMBuildShl(self.llbuilder, lhs, rhs, noname())
366         }
367     }
368
369     pub fn lshr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
370         self.count_insn("lshr");
371         unsafe {
372             llvm::LLVMBuildLShr(self.llbuilder, lhs, rhs, noname())
373         }
374     }
375
376     pub fn ashr(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
377         self.count_insn("ashr");
378         unsafe {
379             llvm::LLVMBuildAShr(self.llbuilder, lhs, rhs, noname())
380         }
381     }
382
383     pub fn and(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
384         self.count_insn("and");
385         unsafe {
386             llvm::LLVMBuildAnd(self.llbuilder, lhs, rhs, noname())
387         }
388     }
389
390     pub fn or(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
391         self.count_insn("or");
392         unsafe {
393             llvm::LLVMBuildOr(self.llbuilder, lhs, rhs, noname())
394         }
395     }
396
397     pub fn xor(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
398         self.count_insn("xor");
399         unsafe {
400             llvm::LLVMBuildXor(self.llbuilder, lhs, rhs, noname())
401         }
402     }
403
404     pub fn neg(&self, v: &'ll Value) -> &'ll Value {
405         self.count_insn("neg");
406         unsafe {
407             llvm::LLVMBuildNeg(self.llbuilder, v, noname())
408         }
409     }
410
411     pub fn fneg(&self, v: &'ll Value) -> &'ll Value {
412         self.count_insn("fneg");
413         unsafe {
414             llvm::LLVMBuildFNeg(self.llbuilder, v, noname())
415         }
416     }
417
418     pub fn not(&self, v: &'ll Value) -> &'ll Value {
419         self.count_insn("not");
420         unsafe {
421             llvm::LLVMBuildNot(self.llbuilder, v, noname())
422         }
423     }
424
425     pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
426         let bx = Builder::with_cx(self.cx);
427         bx.position_at_start(unsafe {
428             llvm::LLVMGetFirstBasicBlock(self.llfn())
429         });
430         bx.dynamic_alloca(ty, name, align)
431     }
432
433     pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
434         self.count_insn("alloca");
435         unsafe {
436             let alloca = if name.is_empty() {
437                 llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
438             } else {
439                 let name = SmallCStr::new(name);
440                 llvm::LLVMBuildAlloca(self.llbuilder, ty,
441                                       name.as_ptr())
442             };
443             llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
444             alloca
445         }
446     }
447
448     pub fn array_alloca(&self,
449                         ty: &'ll Type,
450                         len: &'ll Value,
451                         name: &str,
452                         align: Align) -> &'ll Value {
453         self.count_insn("alloca");
454         unsafe {
455             let alloca = if name.is_empty() {
456                 llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, noname())
457             } else {
458                 let name = SmallCStr::new(name);
459                 llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len,
460                                            name.as_ptr())
461             };
462             llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
463             alloca
464         }
465     }
466
467     pub fn load(&self, ptr: &'ll Value, align: Align) -> &'ll Value {
468         self.count_insn("load");
469         unsafe {
470             let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
471             llvm::LLVMSetAlignment(load, align.abi() as c_uint);
472             load
473         }
474     }
475
476     pub fn volatile_load(&self, ptr: &'ll Value) -> &'ll Value {
477         self.count_insn("load.volatile");
478         unsafe {
479             let insn = llvm::LLVMBuildLoad(self.llbuilder, ptr, noname());
480             llvm::LLVMSetVolatile(insn, llvm::True);
481             insn
482         }
483     }
484
485     pub fn atomic_load(&self, ptr: &'ll Value, order: AtomicOrdering, size: Size) -> &'ll Value {
486         self.count_insn("load.atomic");
487         unsafe {
488             let load = llvm::LLVMRustBuildAtomicLoad(self.llbuilder, ptr, noname(), order);
489             // LLVM requires the alignment of atomic loads to be at least the size of the type.
490             llvm::LLVMSetAlignment(load, size.bytes() as c_uint);
491             load
492         }
493     }
494
495
496     pub fn range_metadata(&self, load: &'ll Value, range: Range<u128>) {
497         if self.sess().target.target.arch == "amdgpu" {
498             // amdgpu/LLVM does something weird and thinks a i64 value is
499             // split into a v2i32, halving the bitwidth LLVM expects,
500             // tripping an assertion. So, for now, just disable this
501             // optimization.
502             return;
503         }
504
505         unsafe {
506             let llty = val_ty(load);
507             let v = [
508                 C_uint_big(llty, range.start),
509                 C_uint_big(llty, range.end)
510             ];
511
512             llvm::LLVMSetMetadata(load, llvm::MD_range as c_uint,
513                                   llvm::LLVMMDNodeInContext(self.cx.llcx,
514                                                             v.as_ptr(),
515                                                             v.len() as c_uint));
516         }
517     }
518
519     pub fn nonnull_metadata(&self, load: &'ll Value) {
520         unsafe {
521             llvm::LLVMSetMetadata(load, llvm::MD_nonnull as c_uint,
522                                   llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
523         }
524     }
525
526     pub fn store(&self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
527         self.store_with_flags(val, ptr, align, MemFlags::empty())
528     }
529
530     pub fn store_with_flags(
531         &self,
532         val: &'ll Value,
533         ptr: &'ll Value,
534         align: Align,
535         flags: MemFlags,
536     ) -> &'ll Value {
537         debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags);
538         self.count_insn("store");
539         let ptr = self.check_store(val, ptr);
540         unsafe {
541             let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
542             let align = if flags.contains(MemFlags::UNALIGNED) {
543                 1
544             } else {
545                 align.abi() as c_uint
546             };
547             llvm::LLVMSetAlignment(store, align);
548             if flags.contains(MemFlags::VOLATILE) {
549                 llvm::LLVMSetVolatile(store, llvm::True);
550             }
551             if flags.contains(MemFlags::NONTEMPORAL) {
552                 // According to LLVM [1] building a nontemporal store must
553                 // *always* point to a metadata value of the integer 1.
554                 //
555                 // [1]: http://llvm.org/docs/LangRef.html#store-instruction
556                 let one = C_i32(self.cx, 1);
557                 let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
558                 llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
559             }
560             store
561         }
562     }
563
564     pub fn atomic_store(&self, val: &'ll Value, ptr: &'ll Value,
565                         order: AtomicOrdering, size: Size) {
566         debug!("Store {:?} -> {:?}", val, ptr);
567         self.count_insn("store.atomic");
568         let ptr = self.check_store(val, ptr);
569         unsafe {
570             let store = llvm::LLVMRustBuildAtomicStore(self.llbuilder, val, ptr, order);
571             // LLVM requires the alignment of atomic stores to be at least the size of the type.
572             llvm::LLVMSetAlignment(store, size.bytes() as c_uint);
573         }
574     }
575
576     pub fn gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
577         self.count_insn("gep");
578         unsafe {
579             llvm::LLVMBuildGEP(self.llbuilder, ptr, indices.as_ptr(),
580                                indices.len() as c_uint, noname())
581         }
582     }
583
584     pub fn inbounds_gep(&self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
585         self.count_insn("inboundsgep");
586         unsafe {
587             llvm::LLVMBuildInBoundsGEP(
588                 self.llbuilder, ptr, indices.as_ptr(), indices.len() as c_uint, noname())
589         }
590     }
591
592     pub fn struct_gep(&self, ptr: &'ll Value, idx: u64) -> &'ll Value {
593         self.count_insn("structgep");
594         assert_eq!(idx as c_uint as u64, idx);
595         unsafe {
596             llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, noname())
597         }
598     }
599
600     /* Casts */
601     pub fn trunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
602         self.count_insn("trunc");
603         unsafe {
604             llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, noname())
605         }
606     }
607
608     pub fn zext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
609         self.count_insn("zext");
610         unsafe {
611             llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname())
612         }
613     }
614
615     pub fn sext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
616         self.count_insn("sext");
617         unsafe {
618             llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, noname())
619         }
620     }
621
622     pub fn fptoui(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
623         self.count_insn("fptoui");
624         unsafe {
625             llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, noname())
626         }
627     }
628
629     pub fn fptosi(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
630         self.count_insn("fptosi");
631         unsafe {
632             llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,noname())
633         }
634     }
635
636     pub fn uitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
637         self.count_insn("uitofp");
638         unsafe {
639             llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, noname())
640         }
641     }
642
643     pub fn sitofp(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
644         self.count_insn("sitofp");
645         unsafe {
646             llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, noname())
647         }
648     }
649
650     pub fn fptrunc(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
651         self.count_insn("fptrunc");
652         unsafe {
653             llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, noname())
654         }
655     }
656
657     pub fn fpext(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
658         self.count_insn("fpext");
659         unsafe {
660             llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, noname())
661         }
662     }
663
664     pub fn ptrtoint(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
665         self.count_insn("ptrtoint");
666         unsafe {
667             llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, noname())
668         }
669     }
670
671     pub fn inttoptr(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
672         self.count_insn("inttoptr");
673         unsafe {
674             llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, noname())
675         }
676     }
677
678     pub fn bitcast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
679         self.count_insn("bitcast");
680         unsafe {
681             llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, noname())
682         }
683     }
684
685     pub fn pointercast(&self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
686         self.count_insn("pointercast");
687         unsafe {
688             llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname())
689         }
690     }
691
692     pub fn intcast(&self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
693         self.count_insn("intcast");
694         unsafe {
695             llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed)
696         }
697     }
698
699     /* Comparisons */
700     pub fn icmp(&self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
701         self.count_insn("icmp");
702         unsafe {
703             llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
704         }
705     }
706
707     pub fn fcmp(&self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
708         self.count_insn("fcmp");
709         unsafe {
710             llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, noname())
711         }
712     }
713
714     /* Miscellaneous instructions */
715     pub fn empty_phi(&self, ty: &'ll Type) -> &'ll Value {
716         self.count_insn("emptyphi");
717         unsafe {
718             llvm::LLVMBuildPhi(self.llbuilder, ty, noname())
719         }
720     }
721
722     pub fn phi(&self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
723         assert_eq!(vals.len(), bbs.len());
724         let phi = self.empty_phi(ty);
725         self.count_insn("addincoming");
726         unsafe {
727             llvm::LLVMAddIncoming(phi, vals.as_ptr(),
728                                   bbs.as_ptr(),
729                                   vals.len() as c_uint);
730             phi
731         }
732     }
733
734     pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
735                            inputs: &[&'ll Value], output: &'ll Type,
736                            volatile: bool, alignstack: bool,
737                            dia: AsmDialect) -> Option<&'ll Value> {
738         self.count_insn("inlineasm");
739
740         let volatile = if volatile { llvm::True }
741                        else        { llvm::False };
742         let alignstack = if alignstack { llvm::True }
743                          else          { llvm::False };
744
745         let argtys = inputs.iter().map(|v| {
746             debug!("Asm Input Type: {:?}", *v);
747             val_ty(*v)
748         }).collect::<Vec<_>>();
749
750         debug!("Asm Output Type: {:?}", output);
751         let fty = Type::func(&argtys[..], output);
752         unsafe {
753             // Ask LLVM to verify that the constraints are well-formed.
754             let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons);
755             debug!("Constraint verification result: {:?}", constraints_ok);
756             if constraints_ok {
757                 let v = llvm::LLVMRustInlineAsm(
758                     fty, asm, cons, volatile, alignstack, dia);
759                 Some(self.call(v, inputs, None))
760             } else {
761                 // LLVM has detected an issue with our constraints, bail out
762                 None
763             }
764         }
765     }
766
767     pub fn call(&self, llfn: &'ll Value, args: &[&'ll Value],
768                 bundle: Option<&OperandBundleDef<'ll>>) -> &'ll Value {
769         self.count_insn("call");
770
771         debug!("Call {:?} with args ({:?})",
772                llfn,
773                args);
774
775         let args = self.check_call("call", llfn, args);
776         let bundle = bundle.map(|b| &*b.raw);
777
778         unsafe {
779             llvm::LLVMRustBuildCall(self.llbuilder, llfn, args.as_ptr(),
780                                     args.len() as c_uint, bundle, noname())
781         }
782     }
783
784     pub fn memcpy(&self, dst: &'ll Value, dst_align: u64,
785                   src: &'ll Value, src_align: u64,
786                   size: &'ll Value, is_volatile: bool) -> &'ll Value {
787         unsafe {
788             llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align as c_uint,
789                                       src, src_align as c_uint, size, is_volatile)
790         }
791     }
792
793     pub fn memmove(&self, dst: &'ll Value, dst_align: u64,
794                   src: &'ll Value, src_align: u64,
795                   size: &'ll Value, is_volatile: bool) -> &'ll Value {
796         unsafe {
797             llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align as c_uint,
798                                       src, src_align as c_uint, size, is_volatile)
799         }
800     }
801
802     pub fn minnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
803         self.count_insn("minnum");
804         unsafe {
805             let instr = llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs);
806             instr.expect("LLVMRustBuildMinNum is not available in LLVM version < 6.0")
807         }
808     }
809     pub fn maxnum(&self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
810         self.count_insn("maxnum");
811         unsafe {
812             let instr = llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs);
813             instr.expect("LLVMRustBuildMaxNum is not available in LLVM version < 6.0")
814         }
815     }
816
817     pub fn select(
818         &self, cond: &'ll Value,
819         then_val: &'ll Value,
820         else_val: &'ll Value,
821     ) -> &'ll Value {
822         self.count_insn("select");
823         unsafe {
824             llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, noname())
825         }
826     }
827
828     #[allow(dead_code)]
829     pub fn va_arg(&self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
830         self.count_insn("vaarg");
831         unsafe {
832             llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
833         }
834     }
835
836     pub fn extract_element(&self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
837         self.count_insn("extractelement");
838         unsafe {
839             llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, noname())
840         }
841     }
842
843     pub fn insert_element(
844         &self, vec: &'ll Value,
845         elt: &'ll Value,
846         idx: &'ll Value,
847     ) -> &'ll Value {
848         self.count_insn("insertelement");
849         unsafe {
850             llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, noname())
851         }
852     }
853
854     pub fn shuffle_vector(&self, v1: &'ll Value, v2: &'ll Value, mask: &'ll Value) -> &'ll Value {
855         self.count_insn("shufflevector");
856         unsafe {
857             llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, noname())
858         }
859     }
860
861     pub fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
862         unsafe {
863             let elt_ty = val_ty(elt);
864             let undef = llvm::LLVMGetUndef(Type::vector(elt_ty, num_elts as u64));
865             let vec = self.insert_element(undef, elt, C_i32(self.cx, 0));
866             let vec_i32_ty = Type::vector(Type::i32(self.cx), num_elts as u64);
867             self.shuffle_vector(vec, undef, C_null(vec_i32_ty))
868         }
869     }
870
871     pub fn vector_reduce_fadd_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
872         self.count_insn("vector.reduce.fadd_fast");
873         unsafe {
874             // FIXME: add a non-fast math version once
875             // https://bugs.llvm.org/show_bug.cgi?id=36732
876             // is fixed.
877             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
878             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
879             instr
880         }
881     }
882     pub fn vector_reduce_fmul_fast(&self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
883         self.count_insn("vector.reduce.fmul_fast");
884         unsafe {
885             // FIXME: add a non-fast math version once
886             // https://bugs.llvm.org/show_bug.cgi?id=36732
887             // is fixed.
888             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
889             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
890             instr
891         }
892     }
893     pub fn vector_reduce_add(&self, src: &'ll Value) -> &'ll Value {
894         self.count_insn("vector.reduce.add");
895         unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
896     }
897     pub fn vector_reduce_mul(&self, src: &'ll Value) -> &'ll Value {
898         self.count_insn("vector.reduce.mul");
899         unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
900     }
901     pub fn vector_reduce_and(&self, src: &'ll Value) -> &'ll Value {
902         self.count_insn("vector.reduce.and");
903         unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
904     }
905     pub fn vector_reduce_or(&self, src: &'ll Value) -> &'ll Value {
906         self.count_insn("vector.reduce.or");
907         unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
908     }
909     pub fn vector_reduce_xor(&self, src: &'ll Value) -> &'ll Value {
910         self.count_insn("vector.reduce.xor");
911         unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
912     }
913     pub fn vector_reduce_fmin(&self, src: &'ll Value) -> &'ll Value {
914         self.count_insn("vector.reduce.fmin");
915         unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) }
916     }
917     pub fn vector_reduce_fmax(&self, src: &'ll Value) -> &'ll Value {
918         self.count_insn("vector.reduce.fmax");
919         unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) }
920     }
921     pub fn vector_reduce_fmin_fast(&self, src: &'ll Value) -> &'ll Value {
922         self.count_insn("vector.reduce.fmin_fast");
923         unsafe {
924             let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
925             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
926             instr
927         }
928     }
929     pub fn vector_reduce_fmax_fast(&self, src: &'ll Value) -> &'ll Value {
930         self.count_insn("vector.reduce.fmax_fast");
931         unsafe {
932             let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
933             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
934             instr
935         }
936     }
937     pub fn vector_reduce_min(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
938         self.count_insn("vector.reduce.min");
939         unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
940     }
941     pub fn vector_reduce_max(&self, src: &'ll Value, is_signed: bool) -> &'ll Value {
942         self.count_insn("vector.reduce.max");
943         unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
944     }
945
946     pub fn extract_value(&self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
947         self.count_insn("extractvalue");
948         assert_eq!(idx as c_uint as u64, idx);
949         unsafe {
950             llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, noname())
951         }
952     }
953
954     pub fn insert_value(&self, agg_val: &'ll Value, elt: &'ll Value,
955                        idx: u64) -> &'ll Value {
956         self.count_insn("insertvalue");
957         assert_eq!(idx as c_uint as u64, idx);
958         unsafe {
959             llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint,
960                                        noname())
961         }
962     }
963
964     pub fn landing_pad(&self, ty: &'ll Type, pers_fn: &'ll Value,
965                        num_clauses: usize) -> &'ll Value {
966         self.count_insn("landingpad");
967         unsafe {
968             llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn,
969                                       num_clauses as c_uint, noname())
970         }
971     }
972
973     pub fn add_clause(&self, landing_pad: &'ll Value, clause: &'ll Value) {
974         unsafe {
975             llvm::LLVMAddClause(landing_pad, clause);
976         }
977     }
978
979     pub fn set_cleanup(&self, landing_pad: &'ll Value) {
980         self.count_insn("setcleanup");
981         unsafe {
982             llvm::LLVMSetCleanup(landing_pad, llvm::True);
983         }
984     }
985
986     pub fn resume(&self, exn: &'ll Value) -> &'ll Value {
987         self.count_insn("resume");
988         unsafe {
989             llvm::LLVMBuildResume(self.llbuilder, exn)
990         }
991     }
992
993     pub fn cleanup_pad(&self,
994                        parent: Option<&'ll Value>,
995                        args: &[&'ll Value]) -> &'ll Value {
996         self.count_insn("cleanuppad");
997         let name = const_cstr!("cleanuppad");
998         let ret = unsafe {
999             llvm::LLVMRustBuildCleanupPad(self.llbuilder,
1000                                           parent,
1001                                           args.len() as c_uint,
1002                                           args.as_ptr(),
1003                                           name.as_ptr())
1004         };
1005         ret.expect("LLVM does not have support for cleanuppad")
1006     }
1007
1008     pub fn cleanup_ret(
1009         &self, cleanup: &'ll Value,
1010         unwind: Option<&'ll BasicBlock>,
1011     ) -> &'ll Value {
1012         self.count_insn("cleanupret");
1013         let ret = unsafe {
1014             llvm::LLVMRustBuildCleanupRet(self.llbuilder, cleanup, unwind)
1015         };
1016         ret.expect("LLVM does not have support for cleanupret")
1017     }
1018
1019     pub fn catch_pad(&self,
1020                      parent: &'ll Value,
1021                      args: &[&'ll Value]) -> &'ll Value {
1022         self.count_insn("catchpad");
1023         let name = const_cstr!("catchpad");
1024         let ret = unsafe {
1025             llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
1026                                         args.len() as c_uint, args.as_ptr(),
1027                                         name.as_ptr())
1028         };
1029         ret.expect("LLVM does not have support for catchpad")
1030     }
1031
1032     pub fn catch_ret(&self, pad: &'ll Value, unwind: &'ll BasicBlock) -> &'ll Value {
1033         self.count_insn("catchret");
1034         let ret = unsafe {
1035             llvm::LLVMRustBuildCatchRet(self.llbuilder, pad, unwind)
1036         };
1037         ret.expect("LLVM does not have support for catchret")
1038     }
1039
1040     pub fn catch_switch(
1041         &self,
1042         parent: Option<&'ll Value>,
1043         unwind: Option<&'ll BasicBlock>,
1044         num_handlers: usize,
1045     ) -> &'ll Value {
1046         self.count_insn("catchswitch");
1047         let name = const_cstr!("catchswitch");
1048         let ret = unsafe {
1049             llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
1050                                            num_handlers as c_uint,
1051                                            name.as_ptr())
1052         };
1053         ret.expect("LLVM does not have support for catchswitch")
1054     }
1055
1056     pub fn add_handler(&self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
1057         unsafe {
1058             llvm::LLVMRustAddHandler(catch_switch, handler);
1059         }
1060     }
1061
1062     pub fn set_personality_fn(&self, personality: &'ll Value) {
1063         unsafe {
1064             llvm::LLVMSetPersonalityFn(self.llfn(), personality);
1065         }
1066     }
1067
1068     // Atomic Operations
1069     pub fn atomic_cmpxchg(
1070         &self,
1071         dst: &'ll Value,
1072         cmp: &'ll Value,
1073         src: &'ll Value,
1074         order: AtomicOrdering,
1075         failure_order: AtomicOrdering,
1076         weak: llvm::Bool,
1077     ) -> &'ll Value {
1078         unsafe {
1079             llvm::LLVMRustBuildAtomicCmpXchg(self.llbuilder, dst, cmp, src,
1080                                              order, failure_order, weak)
1081         }
1082     }
1083     pub fn atomic_rmw(
1084         &self,
1085         op: AtomicRmwBinOp,
1086         dst: &'ll Value,
1087         src: &'ll Value,
1088         order: AtomicOrdering,
1089     ) -> &'ll Value {
1090         unsafe {
1091             llvm::LLVMBuildAtomicRMW(self.llbuilder, op, dst, src, order, False)
1092         }
1093     }
1094
1095     pub fn atomic_fence(&self, order: AtomicOrdering, scope: SynchronizationScope) {
1096         unsafe {
1097             llvm::LLVMRustBuildAtomicFence(self.llbuilder, order, scope);
1098         }
1099     }
1100
1101     pub fn add_case(&self, s: &'ll Value, on_val: &'ll Value, dest: &'ll BasicBlock) {
1102         unsafe {
1103             llvm::LLVMAddCase(s, on_val, dest)
1104         }
1105     }
1106
1107     pub fn add_incoming_to_phi(&self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) {
1108         self.count_insn("addincoming");
1109         unsafe {
1110             llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
1111         }
1112     }
1113
1114     pub fn set_invariant_load(&self, load: &'ll Value) {
1115         unsafe {
1116             llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint,
1117                                   llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
1118         }
1119     }
1120
1121     /// Returns the ptr value that should be used for storing `val`.
1122     fn check_store<'b>(&self,
1123                        val: &'ll Value,
1124                        ptr: &'ll Value) -> &'ll Value {
1125         let dest_ptr_ty = val_ty(ptr);
1126         let stored_ty = val_ty(val);
1127         let stored_ptr_ty = stored_ty.ptr_to();
1128
1129         assert_eq!(dest_ptr_ty.kind(), llvm::TypeKind::Pointer);
1130
1131         if dest_ptr_ty == stored_ptr_ty {
1132             ptr
1133         } else {
1134             debug!("Type mismatch in store. \
1135                     Expected {:?}, got {:?}; inserting bitcast",
1136                    dest_ptr_ty, stored_ptr_ty);
1137             self.bitcast(ptr, stored_ptr_ty)
1138         }
1139     }
1140
1141     /// Returns the args that should be used for a call to `llfn`.
1142     fn check_call<'b>(&self,
1143                       typ: &str,
1144                       llfn: &'ll Value,
1145                       args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> {
1146         let mut fn_ty = val_ty(llfn);
1147         // Strip off pointers
1148         while fn_ty.kind() == llvm::TypeKind::Pointer {
1149             fn_ty = fn_ty.element_type();
1150         }
1151
1152         assert!(fn_ty.kind() == llvm::TypeKind::Function,
1153                 "builder::{} not passed a function, but {:?}", typ, fn_ty);
1154
1155         let param_tys = fn_ty.func_params();
1156
1157         let all_args_match = param_tys.iter()
1158             .zip(args.iter().map(|&v| val_ty(v)))
1159             .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
1160
1161         if all_args_match {
1162             return Cow::Borrowed(args);
1163         }
1164
1165         let casted_args: Vec<_> = param_tys.into_iter()
1166             .zip(args.iter())
1167             .enumerate()
1168             .map(|(i, (expected_ty, &actual_val))| {
1169                 let actual_ty = val_ty(actual_val);
1170                 if expected_ty != actual_ty {
1171                     debug!("Type mismatch in function call of {:?}. \
1172                             Expected {:?} for param {}, got {:?}; injecting bitcast",
1173                            llfn, expected_ty, i, actual_ty);
1174                     self.bitcast(actual_val, expected_ty)
1175                 } else {
1176                     actual_val
1177                 }
1178             })
1179             .collect();
1180
1181         Cow::Owned(casted_args)
1182     }
1183
1184     pub fn lifetime_start(&self, ptr: &'ll Value, size: Size) {
1185         self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size);
1186     }
1187
1188     pub fn lifetime_end(&self, ptr: &'ll Value, size: Size) {
1189         self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size);
1190     }
1191
1192     /// If LLVM lifetime intrinsic support is enabled (i.e. optimizations
1193     /// on), and `ptr` is nonzero-sized, then extracts the size of `ptr`
1194     /// and the intrinsic for `lt` and passes them to `emit`, which is in
1195     /// charge of generating code to call the passed intrinsic on whatever
1196     /// block of generated code is targeted for the intrinsic.
1197     ///
1198     /// If LLVM lifetime intrinsic support is disabled (i.e.  optimizations
1199     /// off) or `ptr` is zero-sized, then no-op (does not call `emit`).
1200     fn call_lifetime_intrinsic(&self, intrinsic: &str, ptr: &'ll Value, size: Size) {
1201         if self.cx.sess().opts.optimize == config::OptLevel::No {
1202             return;
1203         }
1204
1205         let size = size.bytes();
1206         if size == 0 {
1207             return;
1208         }
1209
1210         let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
1211
1212         let ptr = self.pointercast(ptr, Type::i8p(self.cx));
1213         self.call(lifetime_intrinsic, &[C_u64(self.cx, size), ptr], None);
1214     }
1215 }