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