]> git.lizzy.rs Git - rust.git/blob - src/librustc_codegen_llvm/builder.rs
query-fy type_name
[rust.git] / src / librustc_codegen_llvm / builder.rs
1 use crate::llvm::{AtomicRmwBinOp, AtomicOrdering, SynchronizationScope};
2 use crate::llvm::{self, False, BasicBlock};
3 use crate::common::Funclet;
4 use crate::context::CodegenCx;
5 use crate::type_::Type;
6 use crate::type_of::LayoutLlvmExt;
7 use crate::value::Value;
8 use syntax::symbol::LocalInternedString;
9 use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
10 use rustc_codegen_ssa::MemFlags;
11 use libc::{c_uint, c_char};
12 use rustc::ty::{self, Ty, TyCtxt};
13 use rustc::ty::layout::{self, Align, Size, TyLayout};
14 use rustc::hir::def_id::DefId;
15 use rustc::session::config;
16 use rustc_data_structures::small_c_str::SmallCStr;
17 use rustc_codegen_ssa::traits::*;
18 use rustc_codegen_ssa::base::to_immediate;
19 use rustc_codegen_ssa::mir::operand::{OperandValue, OperandRef};
20 use rustc_codegen_ssa::mir::place::PlaceRef;
21 use rustc_target::spec::{HasTargetSpec, Target};
22 use std::borrow::Cow;
23 use std::ffi::CStr;
24 use std::ops::{Deref, Range};
25 use std::ptr;
26 use std::iter::TrustedLen;
27
28 // All Builders must have an llfn associated with them
29 #[must_use]
30 pub struct Builder<'a, 'll: 'a, 'tcx: 'll> {
31     pub llbuilder: &'ll mut llvm::Builder<'ll>,
32     pub cx: &'a CodegenCx<'ll, 'tcx>,
33 }
34
35 impl Drop for Builder<'a, 'll, 'tcx> {
36     fn drop(&mut self) {
37         unsafe {
38             llvm::LLVMDisposeBuilder(&mut *(self.llbuilder as *mut _));
39         }
40     }
41 }
42
43 // FIXME(eddyb) use a checked constructor when they become `const fn`.
44 const EMPTY_C_STR: &CStr = unsafe {
45     CStr::from_bytes_with_nul_unchecked(b"\0")
46 };
47
48 /// Empty string, to be used where LLVM expects an instruction name, indicating
49 /// that the instruction is to be left unnamed (i.e. numbered, in textual IR).
50 // FIXME(eddyb) pass `&CStr` directly to FFI once it's a thin pointer.
51 const UNNAMED: *const c_char = EMPTY_C_STR.as_ptr();
52
53 impl BackendTypes for Builder<'_, 'll, 'tcx> {
54     type Value = <CodegenCx<'ll, 'tcx> as BackendTypes>::Value;
55     type BasicBlock = <CodegenCx<'ll, 'tcx> as BackendTypes>::BasicBlock;
56     type Type = <CodegenCx<'ll, 'tcx> as BackendTypes>::Type;
57     type Funclet = <CodegenCx<'ll, 'tcx> as BackendTypes>::Funclet;
58
59     type DIScope = <CodegenCx<'ll, 'tcx> as BackendTypes>::DIScope;
60 }
61
62 impl ty::layout::HasDataLayout for Builder<'_, '_, '_> {
63     fn data_layout(&self) -> &ty::layout::TargetDataLayout {
64         self.cx.data_layout()
65     }
66 }
67
68 impl ty::layout::HasTyCtxt<'tcx> for Builder<'_, '_, 'tcx> {
69     fn tcx<'a>(&'a self) -> TyCtxt<'a, 'tcx, 'tcx> {
70         self.cx.tcx
71     }
72 }
73
74 impl ty::layout::HasParamEnv<'tcx> for Builder<'_, '_, 'tcx> {
75     fn param_env(&self) -> ty::ParamEnv<'tcx> {
76         self.cx.param_env()
77     }
78 }
79
80 impl HasTargetSpec for Builder<'_, '_, 'tcx> {
81     fn target_spec(&self) -> &Target {
82         &self.cx.target_spec()
83     }
84 }
85
86 impl ty::layout::LayoutOf for Builder<'_, '_, 'tcx> {
87     type Ty = Ty<'tcx>;
88     type TyLayout = TyLayout<'tcx>;
89
90     fn layout_of(&self, ty: Ty<'tcx>) -> Self::TyLayout {
91         self.cx.layout_of(ty)
92     }
93 }
94
95 impl Deref for Builder<'_, 'll, 'tcx> {
96     type Target = CodegenCx<'ll, 'tcx>;
97
98     fn deref(&self) -> &Self::Target {
99         self.cx
100     }
101 }
102
103 impl HasCodegen<'tcx> for Builder<'_, 'll, 'tcx> {
104     type CodegenCx = CodegenCx<'ll, 'tcx>;
105 }
106
107 macro_rules! builder_methods_for_value_instructions {
108     ($($name:ident($($arg:ident),*) => $llvm_capi:ident),+ $(,)?) => {
109         $(fn $name(&mut self, $($arg: &'ll Value),*) -> &'ll Value {
110             unsafe {
111                 llvm::$llvm_capi(self.llbuilder, $($arg,)* UNNAMED)
112             }
113         })*
114     }
115 }
116
117 impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
118     fn new_block<'b>(
119         cx: &'a CodegenCx<'ll, 'tcx>,
120         llfn: &'ll Value,
121         name: &'b str
122     ) -> Self {
123         let mut bx = Builder::with_cx(cx);
124         let llbb = unsafe {
125             let name = SmallCStr::new(name);
126             llvm::LLVMAppendBasicBlockInContext(
127                 cx.llcx,
128                 llfn,
129                 name.as_ptr()
130             )
131         };
132         bx.position_at_end(llbb);
133         bx
134     }
135
136     fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
137         // Create a fresh builder from the crate context.
138         let llbuilder = unsafe {
139             llvm::LLVMCreateBuilderInContext(cx.llcx)
140         };
141         Builder {
142             llbuilder,
143             cx,
144         }
145     }
146
147     fn build_sibling_block<'b>(&self, name: &'b str) -> Self {
148         Builder::new_block(self.cx, self.llfn(), name)
149     }
150
151     fn llbb(&self) -> &'ll BasicBlock {
152         unsafe {
153             llvm::LLVMGetInsertBlock(self.llbuilder)
154         }
155     }
156
157     fn position_at_end(&mut self, llbb: &'ll BasicBlock) {
158         unsafe {
159             llvm::LLVMPositionBuilderAtEnd(self.llbuilder, llbb);
160         }
161     }
162
163     fn ret_void(&mut self) {
164         unsafe {
165             llvm::LLVMBuildRetVoid(self.llbuilder);
166         }
167     }
168
169     fn ret(&mut self, v: &'ll Value) {
170         unsafe {
171             llvm::LLVMBuildRet(self.llbuilder, v);
172         }
173     }
174
175     fn br(&mut self, dest: &'ll BasicBlock) {
176         unsafe {
177             llvm::LLVMBuildBr(self.llbuilder, dest);
178         }
179     }
180
181     fn cond_br(
182         &mut self,
183         cond: &'ll Value,
184         then_llbb: &'ll BasicBlock,
185         else_llbb: &'ll BasicBlock,
186     ) {
187         unsafe {
188             llvm::LLVMBuildCondBr(self.llbuilder, cond, then_llbb, else_llbb);
189         }
190     }
191
192     fn switch(
193         &mut self,
194         v: &'ll Value,
195         else_llbb: &'ll BasicBlock,
196         cases: impl ExactSizeIterator<Item = (u128, &'ll BasicBlock)> + TrustedLen,
197     ) {
198         let switch = unsafe {
199             llvm::LLVMBuildSwitch(self.llbuilder, v, else_llbb, cases.len() as c_uint)
200         };
201         for (on_val, dest) in cases {
202             let on_val = self.const_uint_big(self.val_ty(v), on_val);
203             unsafe {
204                 llvm::LLVMAddCase(switch, on_val, dest)
205             }
206         }
207     }
208
209     fn invoke(
210         &mut self,
211         llfn: &'ll Value,
212         args: &[&'ll Value],
213         then: &'ll BasicBlock,
214         catch: &'ll BasicBlock,
215         funclet: Option<&Funclet<'ll>>,
216     ) -> &'ll Value {
217
218         debug!("Invoke {:?} with args ({:?})",
219                llfn,
220                args);
221
222         let args = self.check_call("invoke", llfn, args);
223         let bundle = funclet.map(|funclet| funclet.bundle());
224         let bundle = bundle.as_ref().map(|b| &*b.raw);
225
226         unsafe {
227             llvm::LLVMRustBuildInvoke(self.llbuilder,
228                                       llfn,
229                                       args.as_ptr(),
230                                       args.len() as c_uint,
231                                       then,
232                                       catch,
233                                       bundle,
234                                       UNNAMED)
235         }
236     }
237
238     fn unreachable(&mut self) {
239         unsafe {
240             llvm::LLVMBuildUnreachable(self.llbuilder);
241         }
242     }
243
244     builder_methods_for_value_instructions! {
245         add(a, b) => LLVMBuildAdd,
246         fadd(a, b) => LLVMBuildFAdd,
247         sub(a, b) => LLVMBuildSub,
248         fsub(a, b) => LLVMBuildFSub,
249         mul(a, b) => LLVMBuildMul,
250         fmul(a, b) => LLVMBuildFMul,
251         udiv(a, b) => LLVMBuildUDiv,
252         exactudiv(a, b) => LLVMBuildExactUDiv,
253         sdiv(a, b) => LLVMBuildSDiv,
254         exactsdiv(a, b) => LLVMBuildExactSDiv,
255         fdiv(a, b) => LLVMBuildFDiv,
256         urem(a, b) => LLVMBuildURem,
257         srem(a, b) => LLVMBuildSRem,
258         frem(a, b) => LLVMBuildFRem,
259         shl(a, b) => LLVMBuildShl,
260         lshr(a, b) => LLVMBuildLShr,
261         ashr(a, b) => LLVMBuildAShr,
262         and(a, b) => LLVMBuildAnd,
263         or(a, b) => LLVMBuildOr,
264         xor(a, b) => LLVMBuildXor,
265         neg(x) => LLVMBuildNeg,
266         fneg(x) => LLVMBuildFNeg,
267         not(x) => LLVMBuildNot,
268     }
269
270     fn fadd_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
271         unsafe {
272             let instr = llvm::LLVMBuildFAdd(self.llbuilder, lhs, rhs, UNNAMED);
273             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
274             instr
275         }
276     }
277
278     fn fsub_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
279         unsafe {
280             let instr = llvm::LLVMBuildFSub(self.llbuilder, lhs, rhs, UNNAMED);
281             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
282             instr
283         }
284     }
285
286     fn fmul_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
287         unsafe {
288             let instr = llvm::LLVMBuildFMul(self.llbuilder, lhs, rhs, UNNAMED);
289             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
290             instr
291         }
292     }
293
294     fn fdiv_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
295         unsafe {
296             let instr = llvm::LLVMBuildFDiv(self.llbuilder, lhs, rhs, UNNAMED);
297             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
298             instr
299         }
300     }
301
302     fn frem_fast(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
303         unsafe {
304             let instr = llvm::LLVMBuildFRem(self.llbuilder, lhs, rhs, UNNAMED);
305             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
306             instr
307         }
308     }
309
310     fn checked_binop(
311         &mut self,
312         oop: OverflowOp,
313         ty: Ty<'_>,
314         lhs: Self::Value,
315         rhs: Self::Value,
316     ) -> (Self::Value, Self::Value) {
317         use syntax::ast::IntTy::*;
318         use syntax::ast::UintTy::*;
319         use rustc::ty::{Int, Uint};
320
321         let new_sty = match ty.sty {
322             Int(Isize) => Int(self.tcx.sess.target.isize_ty),
323             Uint(Usize) => Uint(self.tcx.sess.target.usize_ty),
324             ref t @ Uint(_) | ref t @ Int(_) => t.clone(),
325             _ => panic!("tried to get overflow intrinsic for op applied to non-int type")
326         };
327
328         let name = match oop {
329             OverflowOp::Add => match new_sty {
330                 Int(I8) => "llvm.sadd.with.overflow.i8",
331                 Int(I16) => "llvm.sadd.with.overflow.i16",
332                 Int(I32) => "llvm.sadd.with.overflow.i32",
333                 Int(I64) => "llvm.sadd.with.overflow.i64",
334                 Int(I128) => "llvm.sadd.with.overflow.i128",
335
336                 Uint(U8) => "llvm.uadd.with.overflow.i8",
337                 Uint(U16) => "llvm.uadd.with.overflow.i16",
338                 Uint(U32) => "llvm.uadd.with.overflow.i32",
339                 Uint(U64) => "llvm.uadd.with.overflow.i64",
340                 Uint(U128) => "llvm.uadd.with.overflow.i128",
341
342                 _ => unreachable!(),
343             },
344             OverflowOp::Sub => match new_sty {
345                 Int(I8) => "llvm.ssub.with.overflow.i8",
346                 Int(I16) => "llvm.ssub.with.overflow.i16",
347                 Int(I32) => "llvm.ssub.with.overflow.i32",
348                 Int(I64) => "llvm.ssub.with.overflow.i64",
349                 Int(I128) => "llvm.ssub.with.overflow.i128",
350
351                 Uint(U8) => "llvm.usub.with.overflow.i8",
352                 Uint(U16) => "llvm.usub.with.overflow.i16",
353                 Uint(U32) => "llvm.usub.with.overflow.i32",
354                 Uint(U64) => "llvm.usub.with.overflow.i64",
355                 Uint(U128) => "llvm.usub.with.overflow.i128",
356
357                 _ => unreachable!(),
358             },
359             OverflowOp::Mul => match new_sty {
360                 Int(I8) => "llvm.smul.with.overflow.i8",
361                 Int(I16) => "llvm.smul.with.overflow.i16",
362                 Int(I32) => "llvm.smul.with.overflow.i32",
363                 Int(I64) => "llvm.smul.with.overflow.i64",
364                 Int(I128) => "llvm.smul.with.overflow.i128",
365
366                 Uint(U8) => "llvm.umul.with.overflow.i8",
367                 Uint(U16) => "llvm.umul.with.overflow.i16",
368                 Uint(U32) => "llvm.umul.with.overflow.i32",
369                 Uint(U64) => "llvm.umul.with.overflow.i64",
370                 Uint(U128) => "llvm.umul.with.overflow.i128",
371
372                 _ => unreachable!(),
373             },
374         };
375
376         let intrinsic = self.get_intrinsic(&name);
377         let res = self.call(intrinsic, &[lhs, rhs], None);
378         (
379             self.extract_value(res, 0),
380             self.extract_value(res, 1),
381         )
382     }
383
384     fn alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
385         let mut bx = Builder::with_cx(self.cx);
386         bx.position_at_start(unsafe {
387             llvm::LLVMGetFirstBasicBlock(self.llfn())
388         });
389         bx.dynamic_alloca(ty, name, align)
390     }
391
392     fn dynamic_alloca(&mut self, ty: &'ll Type, name: &str, align: Align) -> &'ll Value {
393         unsafe {
394             let alloca = if name.is_empty() {
395                 llvm::LLVMBuildAlloca(self.llbuilder, ty, UNNAMED)
396             } else {
397                 let name = SmallCStr::new(name);
398                 llvm::LLVMBuildAlloca(self.llbuilder, ty,
399                                       name.as_ptr())
400             };
401             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
402             alloca
403         }
404     }
405
406     fn array_alloca(&mut self,
407                         ty: &'ll Type,
408                         len: &'ll Value,
409                         name: &str,
410                         align: Align) -> &'ll Value {
411         unsafe {
412             let alloca = if name.is_empty() {
413                 llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len, UNNAMED)
414             } else {
415                 let name = SmallCStr::new(name);
416                 llvm::LLVMBuildArrayAlloca(self.llbuilder, ty, len,
417                                            name.as_ptr())
418             };
419             llvm::LLVMSetAlignment(alloca, align.bytes() as c_uint);
420             alloca
421         }
422     }
423
424     fn load(&mut self, ptr: &'ll Value, align: Align) -> &'ll Value {
425         unsafe {
426             let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, UNNAMED);
427             llvm::LLVMSetAlignment(load, align.bytes() as c_uint);
428             load
429         }
430     }
431
432     fn volatile_load(&mut self, ptr: &'ll Value) -> &'ll Value {
433         unsafe {
434             let load = llvm::LLVMBuildLoad(self.llbuilder, ptr, UNNAMED);
435             llvm::LLVMSetVolatile(load, llvm::True);
436             load
437         }
438     }
439
440     fn atomic_load(
441         &mut self,
442         ptr: &'ll Value,
443         order: rustc_codegen_ssa::common::AtomicOrdering,
444         size: Size,
445     ) -> &'ll Value {
446         unsafe {
447             let load = llvm::LLVMRustBuildAtomicLoad(
448                 self.llbuilder,
449                 ptr,
450                 UNNAMED,
451                 AtomicOrdering::from_generic(order),
452             );
453             // LLVM requires the alignment of atomic loads to be at least the size of the type.
454             llvm::LLVMSetAlignment(load, size.bytes() as c_uint);
455             load
456         }
457     }
458
459     fn load_operand(
460         &mut self,
461         place: PlaceRef<'tcx, &'ll Value>
462     ) -> OperandRef<'tcx, &'ll Value> {
463         debug!("PlaceRef::load: {:?}", place);
464
465         assert_eq!(place.llextra.is_some(), place.layout.is_unsized());
466
467         if place.layout.is_zst() {
468             return OperandRef::new_zst(self, place.layout);
469         }
470
471         fn scalar_load_metadata<'a, 'll, 'tcx>(
472             bx: &mut Builder<'a, 'll, 'tcx>,
473             load: &'ll Value,
474             scalar: &layout::Scalar
475         ) {
476             let vr = scalar.valid_range.clone();
477             match scalar.value {
478                 layout::Int(..) => {
479                     let range = scalar.valid_range_exclusive(bx);
480                     if range.start != range.end {
481                         bx.range_metadata(load, range);
482                     }
483                 }
484                 layout::Pointer if vr.start() < vr.end() && !vr.contains(&0) => {
485                     bx.nonnull_metadata(load);
486                 }
487                 _ => {}
488             }
489         }
490
491         let val = if let Some(llextra) = place.llextra {
492             OperandValue::Ref(place.llval, Some(llextra), place.align)
493         } else if place.layout.is_llvm_immediate() {
494             let mut const_llval = None;
495             unsafe {
496                 if let Some(global) = llvm::LLVMIsAGlobalVariable(place.llval) {
497                     if llvm::LLVMIsGlobalConstant(global) == llvm::True {
498                         const_llval = llvm::LLVMGetInitializer(global);
499                     }
500                 }
501             }
502             let llval = const_llval.unwrap_or_else(|| {
503                 let load = self.load(place.llval, place.align);
504                 if let layout::Abi::Scalar(ref scalar) = place.layout.abi {
505                     scalar_load_metadata(self, load, scalar);
506                 }
507                 load
508             });
509             OperandValue::Immediate(to_immediate(self, llval, place.layout))
510         } else if let layout::Abi::ScalarPair(ref a, ref b) = place.layout.abi {
511             let b_offset = a.value.size(self).align_to(b.value.align(self).abi);
512
513             let mut load = |i, scalar: &layout::Scalar, align| {
514                 let llptr = self.struct_gep(place.llval, i as u64);
515                 let load = self.load(llptr, align);
516                 scalar_load_metadata(self, load, scalar);
517                 if scalar.is_bool() {
518                     self.trunc(load, self.type_i1())
519                 } else {
520                     load
521                 }
522             };
523
524             OperandValue::Pair(
525                 load(0, a, place.align),
526                 load(1, b, place.align.restrict_for_offset(b_offset)),
527             )
528         } else {
529             OperandValue::Ref(place.llval, None, place.align)
530         };
531
532         OperandRef { val, layout: place.layout }
533     }
534
535     fn write_operand_repeatedly(
536         mut self,
537         cg_elem: OperandRef<'tcx, &'ll Value>,
538         count: u64,
539         dest: PlaceRef<'tcx, &'ll Value>,
540     ) -> Self {
541         let zero = self.const_usize(0);
542         let count = self.const_usize(count);
543         let start = dest.project_index(&mut self, zero).llval;
544         let end = dest.project_index(&mut self, count).llval;
545
546         let mut header_bx = self.build_sibling_block("repeat_loop_header");
547         let mut body_bx = self.build_sibling_block("repeat_loop_body");
548         let next_bx = self.build_sibling_block("repeat_loop_next");
549
550         self.br(header_bx.llbb());
551         let current = header_bx.phi(self.val_ty(start), &[start], &[self.llbb()]);
552
553         let keep_going = header_bx.icmp(IntPredicate::IntNE, current, end);
554         header_bx.cond_br(keep_going, body_bx.llbb(), next_bx.llbb());
555
556         let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
557         cg_elem.val.store(&mut body_bx,
558             PlaceRef::new_sized(current, cg_elem.layout, align));
559
560         let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]);
561         body_bx.br(header_bx.llbb());
562         header_bx.add_incoming_to_phi(current, next, body_bx.llbb());
563
564         next_bx
565     }
566
567     fn range_metadata(&mut self, load: &'ll Value, range: Range<u128>) {
568         if self.sess().target.target.arch == "amdgpu" {
569             // amdgpu/LLVM does something weird and thinks a i64 value is
570             // split into a v2i32, halving the bitwidth LLVM expects,
571             // tripping an assertion. So, for now, just disable this
572             // optimization.
573             return;
574         }
575
576         unsafe {
577             let llty = self.cx.val_ty(load);
578             let v = [
579                 self.cx.const_uint_big(llty, range.start),
580                 self.cx.const_uint_big(llty, range.end)
581             ];
582
583             llvm::LLVMSetMetadata(load, llvm::MD_range as c_uint,
584                                   llvm::LLVMMDNodeInContext(self.cx.llcx,
585                                                             v.as_ptr(),
586                                                             v.len() as c_uint));
587         }
588     }
589
590     fn nonnull_metadata(&mut self, load: &'ll Value) {
591         unsafe {
592             llvm::LLVMSetMetadata(load, llvm::MD_nonnull as c_uint,
593                                   llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
594         }
595     }
596
597     fn store(&mut self, val: &'ll Value, ptr: &'ll Value, align: Align) -> &'ll Value {
598         self.store_with_flags(val, ptr, align, MemFlags::empty())
599     }
600
601     fn store_with_flags(
602         &mut self,
603         val: &'ll Value,
604         ptr: &'ll Value,
605         align: Align,
606         flags: MemFlags,
607     ) -> &'ll Value {
608         debug!("Store {:?} -> {:?} ({:?})", val, ptr, flags);
609         let ptr = self.check_store(val, ptr);
610         unsafe {
611             let store = llvm::LLVMBuildStore(self.llbuilder, val, ptr);
612             let align = if flags.contains(MemFlags::UNALIGNED) {
613                 1
614             } else {
615                 align.bytes() as c_uint
616             };
617             llvm::LLVMSetAlignment(store, align);
618             if flags.contains(MemFlags::VOLATILE) {
619                 llvm::LLVMSetVolatile(store, llvm::True);
620             }
621             if flags.contains(MemFlags::NONTEMPORAL) {
622                 // According to LLVM [1] building a nontemporal store must
623                 // *always* point to a metadata value of the integer 1.
624                 //
625                 // [1]: http://llvm.org/docs/LangRef.html#store-instruction
626                 let one = self.cx.const_i32(1);
627                 let node = llvm::LLVMMDNodeInContext(self.cx.llcx, &one, 1);
628                 llvm::LLVMSetMetadata(store, llvm::MD_nontemporal as c_uint, node);
629             }
630             store
631         }
632     }
633
634    fn atomic_store(&mut self, val: &'ll Value, ptr: &'ll Value,
635                    order: rustc_codegen_ssa::common::AtomicOrdering, size: Size) {
636         debug!("Store {:?} -> {:?}", val, ptr);
637         let ptr = self.check_store(val, ptr);
638         unsafe {
639             let store = llvm::LLVMRustBuildAtomicStore(
640                 self.llbuilder,
641                 val,
642                 ptr,
643                 AtomicOrdering::from_generic(order),
644             );
645             // LLVM requires the alignment of atomic stores to be at least the size of the type.
646             llvm::LLVMSetAlignment(store, size.bytes() as c_uint);
647         }
648     }
649
650     fn gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
651         unsafe {
652             llvm::LLVMBuildGEP(self.llbuilder, ptr, indices.as_ptr(),
653                                indices.len() as c_uint, UNNAMED)
654         }
655     }
656
657     fn inbounds_gep(&mut self, ptr: &'ll Value, indices: &[&'ll Value]) -> &'ll Value {
658         unsafe {
659             llvm::LLVMBuildInBoundsGEP(
660                 self.llbuilder, ptr, indices.as_ptr(), indices.len() as c_uint, UNNAMED)
661         }
662     }
663
664     fn struct_gep(&mut self, ptr: &'ll Value, idx: u64) -> &'ll Value {
665         assert_eq!(idx as c_uint as u64, idx);
666         unsafe {
667             llvm::LLVMBuildStructGEP(self.llbuilder, ptr, idx as c_uint, UNNAMED)
668         }
669     }
670
671     /* Casts */
672     fn trunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
673         unsafe {
674             llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, UNNAMED)
675         }
676     }
677
678     fn sext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
679         unsafe {
680             llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, UNNAMED)
681         }
682     }
683
684     fn fptoui(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
685         unsafe {
686             llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, UNNAMED)
687         }
688     }
689
690     fn fptosi(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
691         unsafe {
692             llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,UNNAMED)
693         }
694     }
695
696     fn uitofp(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
697         unsafe {
698             llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, UNNAMED)
699         }
700     }
701
702     fn sitofp(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
703         unsafe {
704             llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, UNNAMED)
705         }
706     }
707
708     fn fptrunc(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
709         unsafe {
710             llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, UNNAMED)
711         }
712     }
713
714     fn fpext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
715         unsafe {
716             llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, UNNAMED)
717         }
718     }
719
720     fn ptrtoint(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
721         unsafe {
722             llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, UNNAMED)
723         }
724     }
725
726     fn inttoptr(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
727         unsafe {
728             llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, UNNAMED)
729         }
730     }
731
732     fn bitcast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
733         unsafe {
734             llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, UNNAMED)
735         }
736     }
737
738
739     fn intcast(&mut self, val: &'ll Value, dest_ty: &'ll Type, is_signed: bool) -> &'ll Value {
740         unsafe {
741             llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed)
742         }
743     }
744
745     fn pointercast(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
746         unsafe {
747             llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, UNNAMED)
748         }
749     }
750
751     /* Comparisons */
752     fn icmp(&mut self, op: IntPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
753         let op = llvm::IntPredicate::from_generic(op);
754         unsafe {
755             llvm::LLVMBuildICmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED)
756         }
757     }
758
759     fn fcmp(&mut self, op: RealPredicate, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
760         unsafe {
761             llvm::LLVMBuildFCmp(self.llbuilder, op as c_uint, lhs, rhs, UNNAMED)
762         }
763     }
764
765     /* Miscellaneous instructions */
766     fn memcpy(&mut self, dst: &'ll Value, dst_align: Align,
767                   src: &'ll Value, src_align: Align,
768                   size: &'ll Value, flags: MemFlags) {
769         if flags.contains(MemFlags::NONTEMPORAL) {
770             // HACK(nox): This is inefficient but there is no nontemporal memcpy.
771             let val = self.load(src, src_align);
772             let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val)));
773             self.store_with_flags(val, ptr, dst_align, flags);
774             return;
775         }
776         let size = self.intcast(size, self.type_isize(), false);
777         let is_volatile = flags.contains(MemFlags::VOLATILE);
778         let dst = self.pointercast(dst, self.type_i8p());
779         let src = self.pointercast(src, self.type_i8p());
780         unsafe {
781             llvm::LLVMRustBuildMemCpy(self.llbuilder, dst, dst_align.bytes() as c_uint,
782                                       src, src_align.bytes() as c_uint, size, is_volatile);
783         }
784     }
785
786     fn memmove(&mut self, dst: &'ll Value, dst_align: Align,
787                   src: &'ll Value, src_align: Align,
788                   size: &'ll Value, flags: MemFlags) {
789         if flags.contains(MemFlags::NONTEMPORAL) {
790             // HACK(nox): This is inefficient but there is no nontemporal memmove.
791             let val = self.load(src, src_align);
792             let ptr = self.pointercast(dst, self.type_ptr_to(self.val_ty(val)));
793             self.store_with_flags(val, ptr, dst_align, flags);
794             return;
795         }
796         let size = self.intcast(size, self.type_isize(), false);
797         let is_volatile = flags.contains(MemFlags::VOLATILE);
798         let dst = self.pointercast(dst, self.type_i8p());
799         let src = self.pointercast(src, self.type_i8p());
800         unsafe {
801             llvm::LLVMRustBuildMemMove(self.llbuilder, dst, dst_align.bytes() as c_uint,
802                                       src, src_align.bytes() as c_uint, size, is_volatile);
803         }
804     }
805
806     fn memset(
807         &mut self,
808         ptr: &'ll Value,
809         fill_byte: &'ll Value,
810         size: &'ll Value,
811         align: Align,
812         flags: MemFlags,
813     ) {
814         let ptr_width = &self.sess().target.target.target_pointer_width;
815         let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
816         let llintrinsicfn = self.get_intrinsic(&intrinsic_key);
817         let ptr = self.pointercast(ptr, self.type_i8p());
818         let align = self.const_u32(align.bytes() as u32);
819         let volatile = self.const_bool(flags.contains(MemFlags::VOLATILE));
820         self.call(llintrinsicfn, &[ptr, fill_byte, size, align, volatile], None);
821     }
822
823     fn select(
824         &mut self, cond: &'ll Value,
825         then_val: &'ll Value,
826         else_val: &'ll Value,
827     ) -> &'ll Value {
828         unsafe {
829             llvm::LLVMBuildSelect(self.llbuilder, cond, then_val, else_val, UNNAMED)
830         }
831     }
832
833     #[allow(dead_code)]
834     fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
835         unsafe {
836             llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED)
837         }
838     }
839
840     fn extract_element(&mut self, vec: &'ll Value, idx: &'ll Value) -> &'ll Value {
841         unsafe {
842             llvm::LLVMBuildExtractElement(self.llbuilder, vec, idx, UNNAMED)
843         }
844     }
845
846     fn vector_splat(&mut self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
847         unsafe {
848             let elt_ty = self.cx.val_ty(elt);
849             let undef = llvm::LLVMGetUndef(self.type_vector(elt_ty, num_elts as u64));
850             let vec = self.insert_element(undef, elt, self.cx.const_i32(0));
851             let vec_i32_ty = self.type_vector(self.type_i32(), num_elts as u64);
852             self.shuffle_vector(vec, undef, self.const_null(vec_i32_ty))
853         }
854     }
855
856     fn extract_value(&mut self, agg_val: &'ll Value, idx: u64) -> &'ll Value {
857         assert_eq!(idx as c_uint as u64, idx);
858         unsafe {
859             llvm::LLVMBuildExtractValue(self.llbuilder, agg_val, idx as c_uint, UNNAMED)
860         }
861     }
862
863     fn insert_value(&mut self, agg_val: &'ll Value, elt: &'ll Value,
864                        idx: u64) -> &'ll Value {
865         assert_eq!(idx as c_uint as u64, idx);
866         unsafe {
867             llvm::LLVMBuildInsertValue(self.llbuilder, agg_val, elt, idx as c_uint,
868                                        UNNAMED)
869         }
870     }
871
872     fn landing_pad(&mut self, ty: &'ll Type, pers_fn: &'ll Value,
873                        num_clauses: usize) -> &'ll Value {
874         unsafe {
875             llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn,
876                                       num_clauses as c_uint, UNNAMED)
877         }
878     }
879
880     fn set_cleanup(&mut self, landing_pad: &'ll Value) {
881         unsafe {
882             llvm::LLVMSetCleanup(landing_pad, llvm::True);
883         }
884     }
885
886     fn resume(&mut self, exn: &'ll Value) -> &'ll Value {
887         unsafe {
888             llvm::LLVMBuildResume(self.llbuilder, exn)
889         }
890     }
891
892     fn cleanup_pad(&mut self,
893                        parent: Option<&'ll Value>,
894                        args: &[&'ll Value]) -> Funclet<'ll> {
895         let name = const_cstr!("cleanuppad");
896         let ret = unsafe {
897             llvm::LLVMRustBuildCleanupPad(self.llbuilder,
898                                           parent,
899                                           args.len() as c_uint,
900                                           args.as_ptr(),
901                                           name.as_ptr())
902         };
903         Funclet::new(ret.expect("LLVM does not have support for cleanuppad"))
904     }
905
906     fn cleanup_ret(
907         &mut self, funclet: &Funclet<'ll>,
908         unwind: Option<&'ll BasicBlock>,
909     ) -> &'ll Value {
910         let ret = unsafe {
911             llvm::LLVMRustBuildCleanupRet(self.llbuilder, funclet.cleanuppad(), unwind)
912         };
913         ret.expect("LLVM does not have support for cleanupret")
914     }
915
916     fn catch_pad(&mut self,
917                      parent: &'ll Value,
918                      args: &[&'ll Value]) -> Funclet<'ll> {
919         let name = const_cstr!("catchpad");
920         let ret = unsafe {
921             llvm::LLVMRustBuildCatchPad(self.llbuilder, parent,
922                                         args.len() as c_uint, args.as_ptr(),
923                                         name.as_ptr())
924         };
925         Funclet::new(ret.expect("LLVM does not have support for catchpad"))
926     }
927
928     fn catch_switch(
929         &mut self,
930         parent: Option<&'ll Value>,
931         unwind: Option<&'ll BasicBlock>,
932         num_handlers: usize,
933     ) -> &'ll Value {
934         let name = const_cstr!("catchswitch");
935         let ret = unsafe {
936             llvm::LLVMRustBuildCatchSwitch(self.llbuilder, parent, unwind,
937                                            num_handlers as c_uint,
938                                            name.as_ptr())
939         };
940         ret.expect("LLVM does not have support for catchswitch")
941     }
942
943     fn add_handler(&mut self, catch_switch: &'ll Value, handler: &'ll BasicBlock) {
944         unsafe {
945             llvm::LLVMRustAddHandler(catch_switch, handler);
946         }
947     }
948
949     fn set_personality_fn(&mut self, personality: &'ll Value) {
950         unsafe {
951             llvm::LLVMSetPersonalityFn(self.llfn(), personality);
952         }
953     }
954
955     // Atomic Operations
956     fn atomic_cmpxchg(
957         &mut self,
958         dst: &'ll Value,
959         cmp: &'ll Value,
960         src: &'ll Value,
961         order: rustc_codegen_ssa::common::AtomicOrdering,
962         failure_order: rustc_codegen_ssa::common::AtomicOrdering,
963         weak: bool,
964     ) -> &'ll Value {
965         let weak = if weak { llvm::True } else { llvm::False };
966         unsafe {
967             llvm::LLVMRustBuildAtomicCmpXchg(
968                 self.llbuilder,
969                 dst,
970                 cmp,
971                 src,
972                 AtomicOrdering::from_generic(order),
973                 AtomicOrdering::from_generic(failure_order),
974                 weak
975             )
976         }
977     }
978     fn atomic_rmw(
979         &mut self,
980         op: rustc_codegen_ssa::common::AtomicRmwBinOp,
981         dst: &'ll Value,
982         src: &'ll Value,
983         order: rustc_codegen_ssa::common::AtomicOrdering,
984     ) -> &'ll Value {
985         unsafe {
986             llvm::LLVMBuildAtomicRMW(
987                 self.llbuilder,
988                 AtomicRmwBinOp::from_generic(op),
989                 dst,
990                 src,
991                 AtomicOrdering::from_generic(order),
992                 False)
993         }
994     }
995
996     fn atomic_fence(
997         &mut self,
998         order: rustc_codegen_ssa::common::AtomicOrdering,
999         scope: rustc_codegen_ssa::common::SynchronizationScope
1000     ) {
1001         unsafe {
1002             llvm::LLVMRustBuildAtomicFence(
1003                 self.llbuilder,
1004                 AtomicOrdering::from_generic(order),
1005                 SynchronizationScope::from_generic(scope)
1006             );
1007         }
1008     }
1009
1010     fn set_invariant_load(&mut self, load: &'ll Value) {
1011         unsafe {
1012             llvm::LLVMSetMetadata(load, llvm::MD_invariant_load as c_uint,
1013                                   llvm::LLVMMDNodeInContext(self.cx.llcx, ptr::null(), 0));
1014         }
1015     }
1016
1017     fn lifetime_start(&mut self, ptr: &'ll Value, size: Size) {
1018         self.call_lifetime_intrinsic("llvm.lifetime.start", ptr, size);
1019     }
1020
1021     fn lifetime_end(&mut self, ptr: &'ll Value, size: Size) {
1022         self.call_lifetime_intrinsic("llvm.lifetime.end", ptr, size);
1023     }
1024
1025     fn call(
1026         &mut self,
1027         llfn: &'ll Value,
1028         args: &[&'ll Value],
1029         funclet: Option<&Funclet<'ll>>,
1030     ) -> &'ll Value {
1031
1032         debug!("Call {:?} with args ({:?})",
1033                llfn,
1034                args);
1035
1036         let args = self.check_call("call", llfn, args);
1037         let bundle = funclet.map(|funclet| funclet.bundle());
1038         let bundle = bundle.as_ref().map(|b| &*b.raw);
1039
1040         unsafe {
1041             llvm::LLVMRustBuildCall(
1042                 self.llbuilder,
1043                 llfn,
1044                 args.as_ptr() as *const &llvm::Value,
1045                 args.len() as c_uint,
1046                 bundle, UNNAMED
1047             )
1048         }
1049     }
1050
1051     fn zext(&mut self, val: &'ll Value, dest_ty: &'ll Type) -> &'ll Value {
1052         unsafe {
1053             llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, UNNAMED)
1054         }
1055     }
1056
1057
1058     fn cx(&self) -> &CodegenCx<'ll, 'tcx> {
1059         self.cx
1060     }
1061
1062     unsafe fn delete_basic_block(&mut self, bb: &'ll BasicBlock) {
1063         llvm::LLVMDeleteBasicBlock(bb);
1064     }
1065
1066     fn do_not_inline(&mut self, llret: &'ll Value) {
1067         llvm::Attribute::NoInline.apply_callsite(llvm::AttributePlace::Function, llret);
1068     }
1069 }
1070
1071 impl StaticBuilderMethods<'tcx> for Builder<'a, 'll, 'tcx> {
1072 fn get_static(&mut self, def_id: DefId) -> &'ll Value {
1073         // Forward to the `get_static` method of `CodegenCx`
1074         self.cx().get_static(def_id)
1075     }
1076
1077     fn static_panic_msg(
1078         &mut self,
1079         msg: Option<LocalInternedString>,
1080         filename: LocalInternedString,
1081         line: Self::Value,
1082         col: Self::Value,
1083         kind: &str,
1084     ) -> Self::Value {
1085         let align = self.tcx.data_layout.aggregate_align.abi
1086             .max(self.tcx.data_layout.i32_align.abi)
1087             .max(self.tcx.data_layout.pointer_align.abi);
1088
1089         let filename = self.const_str_slice(filename);
1090
1091         let with_msg_components;
1092         let without_msg_components;
1093
1094         let components = if let Some(msg) = msg {
1095             let msg = self.const_str_slice(msg);
1096             with_msg_components = [msg, filename, line, col];
1097             &with_msg_components as &[_]
1098         } else {
1099             without_msg_components = [filename, line, col];
1100             &without_msg_components as &[_]
1101         };
1102
1103         let struct_ = self.const_struct(&components, false);
1104         self.static_addr_of(struct_, align, Some(kind))
1105     }
1106 }
1107
1108 impl Builder<'a, 'll, 'tcx> {
1109     pub fn llfn(&self) -> &'ll Value {
1110         unsafe {
1111             llvm::LLVMGetBasicBlockParent(self.llbb())
1112         }
1113     }
1114
1115     fn position_at_start(&mut self, llbb: &'ll BasicBlock) {
1116         unsafe {
1117             llvm::LLVMRustPositionBuilderAtStart(self.llbuilder, llbb);
1118         }
1119     }
1120
1121     pub fn minnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
1122         unsafe { llvm::LLVMRustBuildMinNum(self.llbuilder, lhs, rhs) }
1123     }
1124
1125     pub fn maxnum(&mut self, lhs: &'ll Value, rhs: &'ll Value) -> &'ll Value {
1126         unsafe { llvm::LLVMRustBuildMaxNum(self.llbuilder, lhs, rhs) }
1127     }
1128
1129     pub fn insert_element(
1130         &mut self, vec: &'ll Value,
1131         elt: &'ll Value,
1132         idx: &'ll Value,
1133     ) -> &'ll Value {
1134         unsafe {
1135             llvm::LLVMBuildInsertElement(self.llbuilder, vec, elt, idx, UNNAMED)
1136         }
1137     }
1138
1139     pub fn shuffle_vector(
1140         &mut self,
1141         v1: &'ll Value,
1142         v2: &'ll Value,
1143         mask: &'ll Value,
1144     ) -> &'ll Value {
1145         unsafe {
1146             llvm::LLVMBuildShuffleVector(self.llbuilder, v1, v2, mask, UNNAMED)
1147         }
1148     }
1149
1150     pub fn vector_reduce_fadd_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1151         unsafe {
1152             // FIXME: add a non-fast math version once
1153             // https://bugs.llvm.org/show_bug.cgi?id=36732
1154             // is fixed.
1155             let instr = llvm::LLVMRustBuildVectorReduceFAdd(self.llbuilder, acc, src);
1156             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1157             instr
1158         }
1159     }
1160     pub fn vector_reduce_fmul_fast(&mut self, acc: &'ll Value, src: &'ll Value) -> &'ll Value {
1161         unsafe {
1162             // FIXME: add a non-fast math version once
1163             // https://bugs.llvm.org/show_bug.cgi?id=36732
1164             // is fixed.
1165             let instr = llvm::LLVMRustBuildVectorReduceFMul(self.llbuilder, acc, src);
1166             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1167             instr
1168         }
1169     }
1170     pub fn vector_reduce_add(&mut self, src: &'ll Value) -> &'ll Value {
1171         unsafe { llvm::LLVMRustBuildVectorReduceAdd(self.llbuilder, src) }
1172     }
1173     pub fn vector_reduce_mul(&mut self, src: &'ll Value) -> &'ll Value {
1174         unsafe { llvm::LLVMRustBuildVectorReduceMul(self.llbuilder, src) }
1175     }
1176     pub fn vector_reduce_and(&mut self, src: &'ll Value) -> &'ll Value {
1177         unsafe { llvm::LLVMRustBuildVectorReduceAnd(self.llbuilder, src) }
1178     }
1179     pub fn vector_reduce_or(&mut self, src: &'ll Value) -> &'ll Value {
1180         unsafe { llvm::LLVMRustBuildVectorReduceOr(self.llbuilder, src) }
1181     }
1182     pub fn vector_reduce_xor(&mut self, src: &'ll Value) -> &'ll Value {
1183         unsafe { llvm::LLVMRustBuildVectorReduceXor(self.llbuilder, src) }
1184     }
1185     pub fn vector_reduce_fmin(&mut self, src: &'ll Value) -> &'ll Value {
1186         unsafe { llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ false) }
1187     }
1188     pub fn vector_reduce_fmax(&mut self, src: &'ll Value) -> &'ll Value {
1189         unsafe { llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ false) }
1190     }
1191     pub fn vector_reduce_fmin_fast(&mut self, src: &'ll Value) -> &'ll Value {
1192         unsafe {
1193             let instr = llvm::LLVMRustBuildVectorReduceFMin(self.llbuilder, src, /*NoNaNs:*/ true);
1194             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1195             instr
1196         }
1197     }
1198     pub fn vector_reduce_fmax_fast(&mut self, src: &'ll Value) -> &'ll Value {
1199         unsafe {
1200             let instr = llvm::LLVMRustBuildVectorReduceFMax(self.llbuilder, src, /*NoNaNs:*/ true);
1201             llvm::LLVMRustSetHasUnsafeAlgebra(instr);
1202             instr
1203         }
1204     }
1205     pub fn vector_reduce_min(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
1206         unsafe { llvm::LLVMRustBuildVectorReduceMin(self.llbuilder, src, is_signed) }
1207     }
1208     pub fn vector_reduce_max(&mut self, src: &'ll Value, is_signed: bool) -> &'ll Value {
1209         unsafe { llvm::LLVMRustBuildVectorReduceMax(self.llbuilder, src, is_signed) }
1210     }
1211
1212     pub fn add_clause(&mut self, landing_pad: &'ll Value, clause: &'ll Value) {
1213         unsafe {
1214             llvm::LLVMAddClause(landing_pad, clause);
1215         }
1216     }
1217
1218     pub fn catch_ret(&mut self, funclet: &Funclet<'ll>, unwind: &'ll BasicBlock) -> &'ll Value {
1219         let ret = unsafe {
1220             llvm::LLVMRustBuildCatchRet(self.llbuilder, funclet.cleanuppad(), unwind)
1221         };
1222         ret.expect("LLVM does not have support for catchret")
1223     }
1224
1225     fn check_store<'b>(&mut self,
1226                        val: &'ll Value,
1227                        ptr: &'ll Value) -> &'ll Value {
1228         let dest_ptr_ty = self.cx.val_ty(ptr);
1229         let stored_ty = self.cx.val_ty(val);
1230         let stored_ptr_ty = self.cx.type_ptr_to(stored_ty);
1231
1232         assert_eq!(self.cx.type_kind(dest_ptr_ty), TypeKind::Pointer);
1233
1234         if dest_ptr_ty == stored_ptr_ty {
1235             ptr
1236         } else {
1237             debug!("Type mismatch in store. \
1238                     Expected {:?}, got {:?}; inserting bitcast",
1239                    dest_ptr_ty, stored_ptr_ty);
1240             self.bitcast(ptr, stored_ptr_ty)
1241         }
1242     }
1243
1244     fn check_call<'b>(&mut self,
1245                       typ: &str,
1246                       llfn: &'ll Value,
1247                       args: &'b [&'ll Value]) -> Cow<'b, [&'ll Value]> {
1248         let mut fn_ty = self.cx.val_ty(llfn);
1249         // Strip off pointers
1250         while self.cx.type_kind(fn_ty) == TypeKind::Pointer {
1251             fn_ty = self.cx.element_type(fn_ty);
1252         }
1253
1254         assert!(self.cx.type_kind(fn_ty) == TypeKind::Function,
1255                 "builder::{} not passed a function, but {:?}", typ, fn_ty);
1256
1257         let param_tys = self.cx.func_params_types(fn_ty);
1258
1259         let all_args_match = param_tys.iter()
1260             .zip(args.iter().map(|&v| self.val_ty(v)))
1261             .all(|(expected_ty, actual_ty)| *expected_ty == actual_ty);
1262
1263         if all_args_match {
1264             return Cow::Borrowed(args);
1265         }
1266
1267         let casted_args: Vec<_> = param_tys.into_iter()
1268             .zip(args.iter())
1269             .enumerate()
1270             .map(|(i, (expected_ty, &actual_val))| {
1271                 let actual_ty = self.val_ty(actual_val);
1272                 if expected_ty != actual_ty {
1273                     debug!("Type mismatch in function call of {:?}. \
1274                             Expected {:?} for param {}, got {:?}; injecting bitcast",
1275                            llfn, expected_ty, i, actual_ty);
1276                     self.bitcast(actual_val, expected_ty)
1277                 } else {
1278                     actual_val
1279                 }
1280             })
1281             .collect();
1282
1283         Cow::Owned(casted_args)
1284     }
1285
1286     pub fn va_arg(&mut self, list: &'ll Value, ty: &'ll Type) -> &'ll Value {
1287         unsafe {
1288             llvm::LLVMBuildVAArg(self.llbuilder, list, ty, UNNAMED)
1289         }
1290     }
1291
1292     fn call_lifetime_intrinsic(&mut self, intrinsic: &str, ptr: &'ll Value, size: Size) {
1293         if self.cx.sess().opts.optimize == config::OptLevel::No {
1294             return;
1295         }
1296
1297         let size = size.bytes();
1298         if size == 0 {
1299             return;
1300         }
1301
1302         let lifetime_intrinsic = self.cx.get_intrinsic(intrinsic);
1303
1304         let ptr = self.pointercast(ptr, self.cx.type_i8p());
1305         self.call(lifetime_intrinsic, &[self.cx.const_u64(size), ptr], None);
1306     }
1307
1308     fn phi(&mut self, ty: &'ll Type, vals: &[&'ll Value], bbs: &[&'ll BasicBlock]) -> &'ll Value {
1309         assert_eq!(vals.len(), bbs.len());
1310         let phi = unsafe {
1311             llvm::LLVMBuildPhi(self.llbuilder, ty, UNNAMED)
1312         };
1313         unsafe {
1314             llvm::LLVMAddIncoming(phi, vals.as_ptr(),
1315                                   bbs.as_ptr(),
1316                                   vals.len() as c_uint);
1317             phi
1318         }
1319     }
1320
1321     fn add_incoming_to_phi(&mut self, phi: &'ll Value, val: &'ll Value, bb: &'ll BasicBlock) {
1322         unsafe {
1323             llvm::LLVMAddIncoming(phi, &val, &bb, 1 as c_uint);
1324         }
1325     }
1326 }