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