about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDenis Merigoux <denis.merigoux@gmail.com>2018-09-07 15:39:39 -0700
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2018-11-16 14:11:59 +0200
commitd77e34f35ba276b514459b1669818605c9fbf416 (patch)
treef4a1b08094b7dd4f1720ccf99ce3265c2e4fb474
parent0514c7b1b2bbc52cc8f7fe39ef44d0855fddbbdb (diff)
downloadrust-d77e34f35ba276b514459b1669818605c9fbf416.tar.gz
rust-d77e34f35ba276b514459b1669818605c9fbf416.zip
Generalized memset and memcpy
-rw-r--r--src/librustc_codegen_llvm/abi.rs2
-rw-r--r--src/librustc_codegen_llvm/asm.rs2
-rw-r--r--src/librustc_codegen_llvm/base.rs40
-rw-r--r--src/librustc_codegen_llvm/builder.rs5
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/common.rs2
-rw-r--r--src/librustc_codegen_llvm/consts.rs2
-rw-r--r--src/librustc_codegen_llvm/context.rs638
-rw-r--r--src/librustc_codegen_llvm/debuginfo/gdb.rs2
-rw-r--r--src/librustc_codegen_llvm/interfaces/builder.rs3
-rw-r--r--src/librustc_codegen_llvm/interfaces/intrinsic.rs25
-rw-r--r--src/librustc_codegen_llvm/interfaces/mod.rs4
-rw-r--r--src/librustc_codegen_llvm/interfaces/type_.rs32
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs4
-rw-r--r--src/librustc_codegen_llvm/meth.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/block.rs4
-rw-r--r--src/librustc_codegen_llvm/mir/constant.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/mod.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/operand.rs2
-rw-r--r--src/librustc_codegen_llvm/mir/place.rs4
-rw-r--r--src/librustc_codegen_llvm/mir/rvalue.rs2
-rw-r--r--src/librustc_codegen_llvm/type_.rs29
-rw-r--r--src/librustc_codegen_llvm/type_of.rs2
23 files changed, 444 insertions, 368 deletions
diff --git a/src/librustc_codegen_llvm/abi.rs b/src/librustc_codegen_llvm/abi.rs
index 7de657a4918..c990b76eb49 100644
--- a/src/librustc_codegen_llvm/abi.rs
+++ b/src/librustc_codegen_llvm/abi.rs
@@ -18,7 +18,7 @@ use type_::Type;
 use type_of::{LayoutLlvmExt, PointerKind};
 use value::Value;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods};
 
 use rustc_target::abi::{HasDataLayout, LayoutOf, Size, TyLayout, Abi as LayoutAbi};
 use rustc::ty::{self, Ty};
diff --git a/src/librustc_codegen_llvm/asm.rs b/src/librustc_codegen_llvm/asm.rs
index ecd371e8246..11740032664 100644
--- a/src/librustc_codegen_llvm/asm.rs
+++ b/src/librustc_codegen_llvm/asm.rs
@@ -15,7 +15,7 @@ use builder::Builder;
 use value::Value;
 
 use rustc::hir;
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods};
 
 use mir::place::PlaceRef;
 use mir::operand::OperandValue;
diff --git a/src/librustc_codegen_llvm/base.rs b/src/librustc_codegen_llvm/base.rs
index 7575b5f94c4..1578a63efbf 100644
--- a/src/librustc_codegen_llvm/base.rs
+++ b/src/librustc_codegen_llvm/base.rs
@@ -73,7 +73,9 @@ use rustc_data_structures::small_c_str::SmallCStr;
 use rustc_data_structures::sync::Lrc;
 use rustc_data_structures::indexed_vec::Idx;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{
+    BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, DerivedIntrinsicMethods,
+};
 
 use std::any::Any;
 use std::cmp;
@@ -431,13 +433,13 @@ pub fn to_immediate_scalar<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
     val
 }
 
-pub fn call_memcpy(
-    bx: &Builder<'_, 'll, '_>,
-    dst: &'ll Value,
+pub fn call_memcpy<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
+    bx: &Builder,
+    dst: Builder::Value,
     dst_align: Align,
-    src: &'ll Value,
+    src: Builder::Value,
     src_align: Align,
-    n_bytes: &'ll Value,
+    n_bytes: Builder::Value,
     flags: MemFlags,
 ) {
     if flags.contains(MemFlags::NONTEMPORAL) {
@@ -450,16 +452,16 @@ pub fn call_memcpy(
     let cx = bx.cx();
     let src_ptr = bx.pointercast(src, cx.type_i8p());
     let dst_ptr = bx.pointercast(dst, cx.type_i8p());
-    let size = bx.intcast(n_bytes, cx.isize_ty, false);
+    let size = bx.intcast(n_bytes, cx.type_isize(), false);
     let volatile = flags.contains(MemFlags::VOLATILE);
     bx.memcpy(dst_ptr, dst_align.abi(), src_ptr, src_align.abi(), size, volatile);
 }
 
-pub fn memcpy_ty(
-    bx: &Builder<'_, 'll, '_>,
-    dst: &'ll Value,
+pub fn memcpy_ty<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
+    bx: &Builder,
+    dst: Builder::Value,
     dst_align: Align,
-    src: &'ll Value,
+    src: Builder::Value,
     src_align: Align,
     layout: TyLayout<'tcx>,
     flags: MemFlags,
@@ -472,15 +474,15 @@ pub fn memcpy_ty(
     call_memcpy(bx, dst, dst_align, src, src_align, bx.cx().const_usize(size), flags);
 }
 
-pub fn call_memset(
-    bx: &Builder<'_, 'll, '_>,
-    ptr: &'ll Value,
-    fill_byte: &'ll Value,
-    size: &'ll Value,
-    align: &'ll Value,
+pub fn call_memset<'a, 'tcx: 'a, Builder: BuilderMethods<'a, 'tcx>>(
+    bx: &Builder,
+    ptr: Builder::Value,
+    fill_byte: Builder::Value,
+    size: Builder::Value,
+    align: Builder::Value,
     volatile: bool,
-) -> &'ll Value {
-    let ptr_width = &bx.cx().sess().target.target.target_pointer_width;
+) -> Builder::Value {
+    let ptr_width = &bx.sess().target.target.target_pointer_width;
     let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
     let llintrinsicfn = bx.cx().get_intrinsic(&intrinsic_key);
     let volatile = bx.cx().const_bool(volatile);
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 45551669712..3b71502d7c4 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -19,7 +19,10 @@ use rustc::ty::TyCtxt;
 use rustc::ty::layout::{Align, Size};
 use rustc::session::{config, Session};
 use rustc_data_structures::small_c_str::SmallCStr;
-use interfaces::{BuilderMethods, Backend, ConstMethods, TypeMethods};
+use interfaces::{
+    Backend,
+    BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, DerivedIntrinsicMethods,
+};
 use syntax;
 
 use std::borrow::Cow;
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 0d93bd0ce9c..1162573a3f6 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -22,7 +22,7 @@ use llvm;
 use monomorphize::Instance;
 use type_of::LayoutLlvmExt;
 use value::Value;
-use interfaces::TypeMethods;
+use interfaces::BaseTypeMethods;
 
 use rustc::hir::def_id::DefId;
 use rustc::ty::{self, TypeFoldable};
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index ab936f2f7b9..fde834a2481 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -23,7 +23,7 @@ use declare;
 use type_::Type;
 use type_of::LayoutLlvmExt;
 use value::Value;
-use interfaces::{Backend, ConstMethods, TypeMethods};
+use interfaces::{Backend, ConstMethods, BaseTypeMethods};
 
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::layout::{HasDataLayout, LayoutOf};
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 72cb696c54c..d36b790761c 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -24,7 +24,7 @@ use type_::Type;
 use type_of::LayoutLlvmExt;
 use value::Value;
 use rustc::ty::{self, Ty};
-use interfaces::TypeMethods;
+use interfaces::{BaseTypeMethods, DerivedTypeMethods};
 
 use rustc::ty::layout::{Align, LayoutOf};
 
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index 1c25cec35cc..fb0175465b7 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -23,7 +23,8 @@ use value::Value;
 use monomorphize::partitioning::CodegenUnit;
 use type_::Type;
 use type_of::PointeeInfo;
-use interfaces::TypeMethods;
+use interfaces::{BaseTypeMethods, DerivedTypeMethods,
+    IntrinsicMethods, BaseIntrinsicMethods, DerivedIntrinsicMethods};
 
 use rustc_data_structures::base_n;
 use rustc_data_structures::small_c_str::SmallCStr;
@@ -320,16 +321,334 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
     pub fn sess<'a>(&'a self) -> &'a Session {
         &self.tcx.sess
     }
+}
+
+impl BaseIntrinsicMethods for CodegenCx<'_, '_> {}
 
-    pub fn get_intrinsic(&self, key: &str) -> &'b Value {
+impl DerivedIntrinsicMethods for CodegenCx<'b, 'tcx> {
+    fn get_intrinsic(&self, key: &str) -> &'b Value {
         if let Some(v) = self.intrinsics.borrow().get(key).cloned() {
             return v;
         }
 
-        declare_intrinsic(self, key).unwrap_or_else(|| bug!("unknown intrinsic '{}'", key))
+        self.declare_intrinsic(key).unwrap_or_else(|| bug!("unknown intrinsic '{}'", key))
+    }
+
+    /// Declare any llvm intrinsics that you might need
+    fn declare_intrinsic(
+        &self,
+        key: &str
+    ) -> Option<&'b Value> {
+        macro_rules! ifn {
+            ($name:expr, fn() -> $ret:expr) => (
+                if key == $name {
+                    let f = declare::declare_cfn(&self, $name, &self.type_func(&[], $ret));
+                    llvm::SetUnnamedAddr(f, false);
+                    &self.intrinsics.borrow_mut().insert($name, f.clone());
+                    return Some(f);
+                }
+            );
+            ($name:expr, fn(...) -> $ret:expr) => (
+                if key == $name {
+                    let f = declare::declare_cfn(&self, $name, &self.type_variadic_func(&[], $ret));
+                    llvm::SetUnnamedAddr(f, false);
+                    &self.intrinsics.borrow_mut().insert($name, f.clone());
+                    return Some(f);
+                }
+            );
+            ($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
+                if key == $name {
+                    let f = declare::declare_cfn(&self, $name, &self.type_func(&[$($arg),*], $ret));
+                    llvm::SetUnnamedAddr(f, false);
+                    &self.intrinsics.borrow_mut().insert($name, f.clone());
+                    return Some(f);
+                }
+            );
+        }
+        macro_rules! mk_struct {
+            ($($field_ty:expr),*) => (&self.type_struct( &[$($field_ty),*], false))
+        }
+
+        let i8p = &self.type_i8p();
+        let void = &self.type_void();
+        let i1 = &self.type_i1();
+        let t_i8 = &self.type_i8();
+        let t_i16 = &self.type_i16();
+        let t_i32 = &self.type_i32();
+        let t_i64 = &self.type_i64();
+        let t_i128 = &self.type_i128();
+        let t_f32 = &self.type_f32();
+        let t_f64 = &self.type_f64();
+
+        let t_v2f32 = &self.type_vector(t_f32, 2);
+        let t_v4f32 = &self.type_vector(t_f32, 4);
+        let t_v8f32 = &self.type_vector(t_f32, 8);
+        let t_v16f32 = &self.type_vector(t_f32, 16);
+
+        let t_v2f64 = &self.type_vector(t_f64, 2);
+        let t_v4f64 = &self.type_vector(t_f64, 4);
+        let t_v8f64 = &self.type_vector(t_f64, 8);
+
+        ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
+        ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
+        ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
+
+        ifn!("llvm.trap", fn() -> void);
+        ifn!("llvm.debugtrap", fn() -> void);
+        ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
+
+        ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
+        ifn!("llvm.powi.v2f32", fn(t_v2f32, t_i32) -> t_v2f32);
+        ifn!("llvm.powi.v4f32", fn(t_v4f32, t_i32) -> t_v4f32);
+        ifn!("llvm.powi.v8f32", fn(t_v8f32, t_i32) -> t_v8f32);
+        ifn!("llvm.powi.v16f32", fn(t_v16f32, t_i32) -> t_v16f32);
+        ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
+        ifn!("llvm.powi.v2f64", fn(t_v2f64, t_i32) -> t_v2f64);
+        ifn!("llvm.powi.v4f64", fn(t_v4f64, t_i32) -> t_v4f64);
+        ifn!("llvm.powi.v8f64", fn(t_v8f64, t_i32) -> t_v8f64);
+
+        ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
+        ifn!("llvm.pow.v2f32", fn(t_v2f32, t_v2f32) -> t_v2f32);
+        ifn!("llvm.pow.v4f32", fn(t_v4f32, t_v4f32) -> t_v4f32);
+        ifn!("llvm.pow.v8f32", fn(t_v8f32, t_v8f32) -> t_v8f32);
+        ifn!("llvm.pow.v16f32", fn(t_v16f32, t_v16f32) -> t_v16f32);
+        ifn!("llvm.pow.f64", fn(t_f64, t_f64) -> t_f64);
+        ifn!("llvm.pow.v2f64", fn(t_v2f64, t_v2f64) -> t_v2f64);
+        ifn!("llvm.pow.v4f64", fn(t_v4f64, t_v4f64) -> t_v4f64);
+        ifn!("llvm.pow.v8f64", fn(t_v8f64, t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.sqrt.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.sqrt.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.sqrt.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.sqrt.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.sqrt.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.sqrt.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.sqrt.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.sqrt.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.sqrt.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.sin.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.sin.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.sin.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.sin.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.sin.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.sin.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.sin.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.sin.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.sin.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.cos.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.cos.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.cos.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.cos.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.cos.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.cos.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.cos.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.cos.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.cos.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.exp.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.exp.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.exp.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.exp.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.exp.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.exp.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.exp.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.exp.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.exp.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.exp2.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.exp2.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.exp2.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.exp2.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.exp2.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.exp2.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.exp2.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.exp2.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.exp2.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.log.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.log.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.log.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.log.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.log.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.log.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.log.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.log.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.log.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.log10.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.log10.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.log10.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.log10.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.log10.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.log10.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.log10.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.log10.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.log10.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.log2.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.log2.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.log2.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.log2.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.log2.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.log2.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.log2.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.log2.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.log2.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.fma.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
+        ifn!("llvm.fma.v2f32", fn(t_v2f32, t_v2f32, t_v2f32) -> t_v2f32);
+        ifn!("llvm.fma.v4f32", fn(t_v4f32, t_v4f32, t_v4f32) -> t_v4f32);
+        ifn!("llvm.fma.v8f32", fn(t_v8f32, t_v8f32, t_v8f32) -> t_v8f32);
+        ifn!("llvm.fma.v16f32", fn(t_v16f32, t_v16f32, t_v16f32) -> t_v16f32);
+        ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
+        ifn!("llvm.fma.v2f64", fn(t_v2f64, t_v2f64, t_v2f64) -> t_v2f64);
+        ifn!("llvm.fma.v4f64", fn(t_v4f64, t_v4f64, t_v4f64) -> t_v4f64);
+        ifn!("llvm.fma.v8f64", fn(t_v8f64, t_v8f64, t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.fabs.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.fabs.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.fabs.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.fabs.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.fabs.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.fabs.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.fabs.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.fabs.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.fabs.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.floor.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.floor.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.floor.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.floor.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.floor.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.floor.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.floor.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.ceil.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.ceil.v2f32", fn(t_v2f32) -> t_v2f32);
+        ifn!("llvm.ceil.v4f32", fn(t_v4f32) -> t_v4f32);
+        ifn!("llvm.ceil.v8f32", fn(t_v8f32) -> t_v8f32);
+        ifn!("llvm.ceil.v16f32", fn(t_v16f32) -> t_v16f32);
+        ifn!("llvm.ceil.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.ceil.v2f64", fn(t_v2f64) -> t_v2f64);
+        ifn!("llvm.ceil.v4f64", fn(t_v4f64) -> t_v4f64);
+        ifn!("llvm.ceil.v8f64", fn(t_v8f64) -> t_v8f64);
+
+        ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
+
+        ifn!("llvm.copysign.f32", fn(t_f32, t_f32) -> t_f32);
+        ifn!("llvm.copysign.f64", fn(t_f64, t_f64) -> t_f64);
+        ifn!("llvm.round.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.round.f64", fn(t_f64) -> t_f64);
+
+        ifn!("llvm.rint.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.rint.f64", fn(t_f64) -> t_f64);
+        ifn!("llvm.nearbyint.f32", fn(t_f32) -> t_f32);
+        ifn!("llvm.nearbyint.f64", fn(t_f64) -> t_f64);
+
+        ifn!("llvm.ctpop.i8", fn(t_i8) -> t_i8);
+        ifn!("llvm.ctpop.i16", fn(t_i16) -> t_i16);
+        ifn!("llvm.ctpop.i32", fn(t_i32) -> t_i32);
+        ifn!("llvm.ctpop.i64", fn(t_i64) -> t_i64);
+        ifn!("llvm.ctpop.i128", fn(t_i128) -> t_i128);
+
+        ifn!("llvm.ctlz.i8", fn(t_i8 , i1) -> t_i8);
+        ifn!("llvm.ctlz.i16", fn(t_i16, i1) -> t_i16);
+        ifn!("llvm.ctlz.i32", fn(t_i32, i1) -> t_i32);
+        ifn!("llvm.ctlz.i64", fn(t_i64, i1) -> t_i64);
+        ifn!("llvm.ctlz.i128", fn(t_i128, i1) -> t_i128);
+
+        ifn!("llvm.cttz.i8", fn(t_i8 , i1) -> t_i8);
+        ifn!("llvm.cttz.i16", fn(t_i16, i1) -> t_i16);
+        ifn!("llvm.cttz.i32", fn(t_i32, i1) -> t_i32);
+        ifn!("llvm.cttz.i64", fn(t_i64, i1) -> t_i64);
+        ifn!("llvm.cttz.i128", fn(t_i128, i1) -> t_i128);
+
+        ifn!("llvm.bswap.i16", fn(t_i16) -> t_i16);
+        ifn!("llvm.bswap.i32", fn(t_i32) -> t_i32);
+        ifn!("llvm.bswap.i64", fn(t_i64) -> t_i64);
+        ifn!("llvm.bswap.i128", fn(t_i128) -> t_i128);
+
+        ifn!("llvm.bitreverse.i8", fn(t_i8) -> t_i8);
+        ifn!("llvm.bitreverse.i16", fn(t_i16) -> t_i16);
+        ifn!("llvm.bitreverse.i32", fn(t_i32) -> t_i32);
+        ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
+        ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
+
+    ifn!("llvm.fshl.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+    ifn!("llvm.fshl.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+    ifn!("llvm.fshl.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+    ifn!("llvm.fshl.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+    ifn!("llvm.fshl.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
+    ifn!("llvm.fshr.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
+    ifn!("llvm.fshr.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
+    ifn!("llvm.fshr.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
+    ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
+    ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
+
+        ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+        ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+        ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+        ifn!("llvm.sadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+        ifn!("llvm.sadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
+
+        ifn!("llvm.uadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+        ifn!("llvm.uadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+        ifn!("llvm.uadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+        ifn!("llvm.uadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+        ifn!("llvm.uadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
+
+        ifn!("llvm.ssub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+        ifn!("llvm.ssub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+        ifn!("llvm.ssub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+        ifn!("llvm.ssub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+        ifn!("llvm.ssub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
+
+        ifn!("llvm.usub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+        ifn!("llvm.usub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+        ifn!("llvm.usub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+        ifn!("llvm.usub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+        ifn!("llvm.usub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
+
+        ifn!("llvm.smul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+        ifn!("llvm.smul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+        ifn!("llvm.smul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+        ifn!("llvm.smul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+        ifn!("llvm.smul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
+
+        ifn!("llvm.umul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
+        ifn!("llvm.umul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
+        ifn!("llvm.umul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
+        ifn!("llvm.umul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
+        ifn!("llvm.umul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
+
+        ifn!("llvm.lifetime.start", fn(t_i64,i8p) -> void);
+        ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> void);
+
+        ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
+        ifn!("llvm.eh.typeid.for", fn(i8p) -> t_i32);
+        ifn!("llvm.localescape", fn(...) -> void);
+        ifn!("llvm.localrecover", fn(i8p, i8p, t_i32) -> i8p);
+        ifn!("llvm.x86.seh.recoverfp", fn(i8p, i8p) -> i8p);
+
+        ifn!("llvm.assume", fn(i1) -> void);
+        ifn!("llvm.prefetch", fn(i8p, t_i32, t_i32, t_i32) -> void);
+
+        if self.sess().opts.debuginfo != DebugInfo::None {
+            ifn!("llvm.dbg.declare", fn(&self.type_metadata(), &self.type_metadata()) -> void);
+            ifn!("llvm.dbg.value", fn(&self.type_metadata(), t_i64, &self.type_metadata()) -> void);
+        }
+        return None;
     }
 }
 
+impl IntrinsicMethods for CodegenCx<'a, 'tcx> {}
+
 impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
     /// Generate a new symbol name with the given prefix. This symbol name must
     /// only be used for definitions with `internal` or `private` linkage.
@@ -479,316 +798,3 @@ impl LayoutOf for CodegenCx<'ll, 'tcx> {
             })
     }
 }
-
-/// Declare any llvm intrinsics that you might need
-fn declare_intrinsic(
-    cx: &CodegenCx<'ll, '_>,
-    key: &str
-) -> Option<&'ll Value> {
-    macro_rules! ifn {
-        ($name:expr, fn() -> $ret:expr) => (
-            if key == $name {
-                let f = declare::declare_cfn(cx, $name, cx.type_func(&[], $ret));
-                llvm::SetUnnamedAddr(f, false);
-                cx.intrinsics.borrow_mut().insert($name, f.clone());
-                return Some(f);
-            }
-        );
-        ($name:expr, fn(...) -> $ret:expr) => (
-            if key == $name {
-                let f = declare::declare_cfn(cx, $name, cx.type_variadic_func(&[], $ret));
-                llvm::SetUnnamedAddr(f, false);
-                cx.intrinsics.borrow_mut().insert($name, f.clone());
-                return Some(f);
-            }
-        );
-        ($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
-            if key == $name {
-                let f = declare::declare_cfn(cx, $name, cx.type_func(&[$($arg),*], $ret));
-                llvm::SetUnnamedAddr(f, false);
-                cx.intrinsics.borrow_mut().insert($name, f.clone());
-                return Some(f);
-            }
-        );
-    }
-    macro_rules! mk_struct {
-        ($($field_ty:expr),*) => (cx.type_struct( &[$($field_ty),*], false))
-    }
-
-    let i8p = cx.type_i8p();
-    let void = cx.type_void();
-    let i1 = cx.type_i1();
-    let t_i8 = cx.type_i8();
-    let t_i16 = cx.type_i16();
-    let t_i32 = cx.type_i32();
-    let t_i64 = cx.type_i64();
-    let t_i128 = cx.type_i128();
-    let t_f32 = cx.type_f32();
-    let t_f64 = cx.type_f64();
-
-    let t_v2f32 = cx.type_vector(t_f32, 2);
-    let t_v4f32 = cx.type_vector(t_f32, 4);
-    let t_v8f32 = cx.type_vector(t_f32, 8);
-    let t_v16f32 = cx.type_vector(t_f32, 16);
-
-    let t_v2f64 = cx.type_vector(t_f64, 2);
-    let t_v4f64 = cx.type_vector(t_f64, 4);
-    let t_v8f64 = cx.type_vector(t_f64, 8);
-
-    ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
-    ifn!("llvm.memset.p0i8.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
-    ifn!("llvm.memset.p0i8.i64", fn(i8p, t_i8, t_i64, t_i32, i1) -> void);
-
-    ifn!("llvm.trap", fn() -> void);
-    ifn!("llvm.debugtrap", fn() -> void);
-    ifn!("llvm.frameaddress", fn(t_i32) -> i8p);
-
-    ifn!("llvm.powi.f32", fn(t_f32, t_i32) -> t_f32);
-    ifn!("llvm.powi.v2f32", fn(t_v2f32, t_i32) -> t_v2f32);
-    ifn!("llvm.powi.v4f32", fn(t_v4f32, t_i32) -> t_v4f32);
-    ifn!("llvm.powi.v8f32", fn(t_v8f32, t_i32) -> t_v8f32);
-    ifn!("llvm.powi.v16f32", fn(t_v16f32, t_i32) -> t_v16f32);
-    ifn!("llvm.powi.f64", fn(t_f64, t_i32) -> t_f64);
-    ifn!("llvm.powi.v2f64", fn(t_v2f64, t_i32) -> t_v2f64);
-    ifn!("llvm.powi.v4f64", fn(t_v4f64, t_i32) -> t_v4f64);
-    ifn!("llvm.powi.v8f64", fn(t_v8f64, t_i32) -> t_v8f64);
-
-    ifn!("llvm.pow.f32", fn(t_f32, t_f32) -> t_f32);
-    ifn!("llvm.pow.v2f32", fn(t_v2f32, t_v2f32) -> t_v2f32);
-    ifn!("llvm.pow.v4f32", fn(t_v4f32, t_v4f32) -> t_v4f32);
-    ifn!("llvm.pow.v8f32", fn(t_v8f32, t_v8f32) -> t_v8f32);
-    ifn!("llvm.pow.v16f32", fn(t_v16f32, t_v16f32) -> t_v16f32);
-    ifn!("llvm.pow.f64", fn(t_f64, t_f64) -> t_f64);
-    ifn!("llvm.pow.v2f64", fn(t_v2f64, t_v2f64) -> t_v2f64);
-    ifn!("llvm.pow.v4f64", fn(t_v4f64, t_v4f64) -> t_v4f64);
-    ifn!("llvm.pow.v8f64", fn(t_v8f64, t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.sqrt.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.sqrt.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.sqrt.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.sqrt.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.sqrt.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.sqrt.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.sqrt.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.sqrt.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.sqrt.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.sin.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.sin.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.sin.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.sin.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.sin.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.sin.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.sin.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.sin.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.sin.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.cos.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.cos.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.cos.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.cos.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.cos.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.cos.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.cos.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.cos.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.cos.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.exp.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.exp.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.exp.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.exp.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.exp.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.exp.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.exp.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.exp.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.exp.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.exp2.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.exp2.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.exp2.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.exp2.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.exp2.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.exp2.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.exp2.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.exp2.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.exp2.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.log.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.log.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.log.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.log.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.log.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.log.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.log.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.log.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.log.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.log10.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.log10.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.log10.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.log10.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.log10.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.log10.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.log10.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.log10.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.log10.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.log2.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.log2.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.log2.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.log2.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.log2.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.log2.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.log2.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.log2.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.log2.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.fma.f32", fn(t_f32, t_f32, t_f32) -> t_f32);
-    ifn!("llvm.fma.v2f32", fn(t_v2f32, t_v2f32, t_v2f32) -> t_v2f32);
-    ifn!("llvm.fma.v4f32", fn(t_v4f32, t_v4f32, t_v4f32) -> t_v4f32);
-    ifn!("llvm.fma.v8f32", fn(t_v8f32, t_v8f32, t_v8f32) -> t_v8f32);
-    ifn!("llvm.fma.v16f32", fn(t_v16f32, t_v16f32, t_v16f32) -> t_v16f32);
-    ifn!("llvm.fma.f64", fn(t_f64, t_f64, t_f64) -> t_f64);
-    ifn!("llvm.fma.v2f64", fn(t_v2f64, t_v2f64, t_v2f64) -> t_v2f64);
-    ifn!("llvm.fma.v4f64", fn(t_v4f64, t_v4f64, t_v4f64) -> t_v4f64);
-    ifn!("llvm.fma.v8f64", fn(t_v8f64, t_v8f64, t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.fabs.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.fabs.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.fabs.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.fabs.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.fabs.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.fabs.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.fabs.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.fabs.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.fabs.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.floor.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.floor.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.floor.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.floor.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.floor.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.floor.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.floor.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.floor.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.floor.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.ceil.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.ceil.v2f32", fn(t_v2f32) -> t_v2f32);
-    ifn!("llvm.ceil.v4f32", fn(t_v4f32) -> t_v4f32);
-    ifn!("llvm.ceil.v8f32", fn(t_v8f32) -> t_v8f32);
-    ifn!("llvm.ceil.v16f32", fn(t_v16f32) -> t_v16f32);
-    ifn!("llvm.ceil.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.ceil.v2f64", fn(t_v2f64) -> t_v2f64);
-    ifn!("llvm.ceil.v4f64", fn(t_v4f64) -> t_v4f64);
-    ifn!("llvm.ceil.v8f64", fn(t_v8f64) -> t_v8f64);
-
-    ifn!("llvm.trunc.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.trunc.f64", fn(t_f64) -> t_f64);
-
-    ifn!("llvm.copysign.f32", fn(t_f32, t_f32) -> t_f32);
-    ifn!("llvm.copysign.f64", fn(t_f64, t_f64) -> t_f64);
-    ifn!("llvm.round.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.round.f64", fn(t_f64) -> t_f64);
-
-    ifn!("llvm.rint.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.rint.f64", fn(t_f64) -> t_f64);
-    ifn!("llvm.nearbyint.f32", fn(t_f32) -> t_f32);
-    ifn!("llvm.nearbyint.f64", fn(t_f64) -> t_f64);
-
-    ifn!("llvm.ctpop.i8", fn(t_i8) -> t_i8);
-    ifn!("llvm.ctpop.i16", fn(t_i16) -> t_i16);
-    ifn!("llvm.ctpop.i32", fn(t_i32) -> t_i32);
-    ifn!("llvm.ctpop.i64", fn(t_i64) -> t_i64);
-    ifn!("llvm.ctpop.i128", fn(t_i128) -> t_i128);
-
-    ifn!("llvm.ctlz.i8", fn(t_i8 , i1) -> t_i8);
-    ifn!("llvm.ctlz.i16", fn(t_i16, i1) -> t_i16);
-    ifn!("llvm.ctlz.i32", fn(t_i32, i1) -> t_i32);
-    ifn!("llvm.ctlz.i64", fn(t_i64, i1) -> t_i64);
-    ifn!("llvm.ctlz.i128", fn(t_i128, i1) -> t_i128);
-
-    ifn!("llvm.cttz.i8", fn(t_i8 , i1) -> t_i8);
-    ifn!("llvm.cttz.i16", fn(t_i16, i1) -> t_i16);
-    ifn!("llvm.cttz.i32", fn(t_i32, i1) -> t_i32);
-    ifn!("llvm.cttz.i64", fn(t_i64, i1) -> t_i64);
-    ifn!("llvm.cttz.i128", fn(t_i128, i1) -> t_i128);
-
-    ifn!("llvm.bswap.i16", fn(t_i16) -> t_i16);
-    ifn!("llvm.bswap.i32", fn(t_i32) -> t_i32);
-    ifn!("llvm.bswap.i64", fn(t_i64) -> t_i64);
-    ifn!("llvm.bswap.i128", fn(t_i128) -> t_i128);
-
-    ifn!("llvm.bitreverse.i8", fn(t_i8) -> t_i8);
-    ifn!("llvm.bitreverse.i16", fn(t_i16) -> t_i16);
-    ifn!("llvm.bitreverse.i32", fn(t_i32) -> t_i32);
-    ifn!("llvm.bitreverse.i64", fn(t_i64) -> t_i64);
-    ifn!("llvm.bitreverse.i128", fn(t_i128) -> t_i128);
-
-    ifn!("llvm.fshl.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
-    ifn!("llvm.fshl.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
-    ifn!("llvm.fshl.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
-    ifn!("llvm.fshl.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
-    ifn!("llvm.fshl.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
-
-    ifn!("llvm.fshr.i8", fn(t_i8, t_i8, t_i8) -> t_i8);
-    ifn!("llvm.fshr.i16", fn(t_i16, t_i16, t_i16) -> t_i16);
-    ifn!("llvm.fshr.i32", fn(t_i32, t_i32, t_i32) -> t_i32);
-    ifn!("llvm.fshr.i64", fn(t_i64, t_i64, t_i64) -> t_i64);
-    ifn!("llvm.fshr.i128", fn(t_i128, t_i128, t_i128) -> t_i128);
-
-    ifn!("llvm.sadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.sadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.sadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.sadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-    ifn!("llvm.sadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
-
-    ifn!("llvm.uadd.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.uadd.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.uadd.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.uadd.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-    ifn!("llvm.uadd.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
-
-    ifn!("llvm.ssub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.ssub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.ssub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.ssub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-    ifn!("llvm.ssub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
-
-    ifn!("llvm.usub.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.usub.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.usub.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.usub.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-    ifn!("llvm.usub.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
-
-    ifn!("llvm.smul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.smul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.smul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.smul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-    ifn!("llvm.smul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
-
-    ifn!("llvm.umul.with.overflow.i8", fn(t_i8, t_i8) -> mk_struct!{t_i8, i1});
-    ifn!("llvm.umul.with.overflow.i16", fn(t_i16, t_i16) -> mk_struct!{t_i16, i1});
-    ifn!("llvm.umul.with.overflow.i32", fn(t_i32, t_i32) -> mk_struct!{t_i32, i1});
-    ifn!("llvm.umul.with.overflow.i64", fn(t_i64, t_i64) -> mk_struct!{t_i64, i1});
-    ifn!("llvm.umul.with.overflow.i128", fn(t_i128, t_i128) -> mk_struct!{t_i128, i1});
-
-    ifn!("llvm.lifetime.start", fn(t_i64,i8p) -> void);
-    ifn!("llvm.lifetime.end", fn(t_i64, i8p) -> void);
-
-    ifn!("llvm.expect.i1", fn(i1, i1) -> i1);
-    ifn!("llvm.eh.typeid.for", fn(i8p) -> t_i32);
-    ifn!("llvm.localescape", fn(...) -> void);
-    ifn!("llvm.localrecover", fn(i8p, i8p, t_i32) -> i8p);
-    ifn!("llvm.x86.seh.recoverfp", fn(i8p, i8p) -> i8p);
-
-    ifn!("llvm.assume", fn(i1) -> void);
-    ifn!("llvm.prefetch", fn(i8p, t_i32, t_i32, t_i32) -> void);
-
-    if cx.sess().opts.debuginfo != DebugInfo::None {
-        ifn!("llvm.dbg.declare", fn(cx.type_metadata(), cx.type_metadata()) -> void);
-        ifn!("llvm.dbg.value", fn(cx.type_metadata(), t_i64, cx.type_metadata()) -> void);
-    }
-
-    None
-}
diff --git a/src/librustc_codegen_llvm/debuginfo/gdb.rs b/src/librustc_codegen_llvm/debuginfo/gdb.rs
index 45c692c6250..f0ff8cd188f 100644
--- a/src/librustc_codegen_llvm/debuginfo/gdb.rs
+++ b/src/librustc_codegen_llvm/debuginfo/gdb.rs
@@ -17,7 +17,7 @@ use builder::Builder;
 use declare;
 use rustc::session::config::DebugInfo;
 use value::Value;
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods};
 
 use syntax::attr;
 
diff --git a/src/librustc_codegen_llvm/interfaces/builder.rs b/src/librustc_codegen_llvm/interfaces/builder.rs
index fc089bfc83e..65ce0ac4efb 100644
--- a/src/librustc_codegen_llvm/interfaces/builder.rs
+++ b/src/librustc_codegen_llvm/interfaces/builder.rs
@@ -17,6 +17,7 @@ use builder::MemFlags;
 use super::backend::Backend;
 use super::type_::TypeMethods;
 use super::consts::ConstMethods;
+use super::intrinsic::IntrinsicMethods;
 
 use std::borrow::Cow;
 use std::ops::Range;
@@ -24,7 +25,7 @@ use syntax::ast::AsmDialect;
 
 
 pub trait BuilderMethods<'a, 'tcx: 'a>: Backend {
-    type CodegenCx: 'a + TypeMethods + ConstMethods + Backend<
+    type CodegenCx: 'a + TypeMethods + ConstMethods + IntrinsicMethods + Backend<
         Value = Self::Value,
         BasicBlock = Self::BasicBlock,
         Type = Self::Type,
diff --git a/src/librustc_codegen_llvm/interfaces/intrinsic.rs b/src/librustc_codegen_llvm/interfaces/intrinsic.rs
new file mode 100644
index 00000000000..2d4f4c3028d
--- /dev/null
+++ b/src/librustc_codegen_llvm/interfaces/intrinsic.rs
@@ -0,0 +1,25 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use super::backend::Backend;
+
+pub trait BaseIntrinsicMethods: Backend {
+
+}
+
+pub trait DerivedIntrinsicMethods: Backend {
+    fn get_intrinsic(&self, key: &str) -> Self::Value;
+    fn declare_intrinsic(
+        &self,
+        key: &str
+    ) -> Option<Self::Value>;
+}
+
+pub trait IntrinsicMethods: BaseIntrinsicMethods + DerivedIntrinsicMethods {}
diff --git a/src/librustc_codegen_llvm/interfaces/mod.rs b/src/librustc_codegen_llvm/interfaces/mod.rs
index 93c46aed4ac..def4b49f27d 100644
--- a/src/librustc_codegen_llvm/interfaces/mod.rs
+++ b/src/librustc_codegen_llvm/interfaces/mod.rs
@@ -12,8 +12,10 @@ mod builder;
 mod backend;
 mod consts;
 mod type_;
+mod intrinsic;
 
 pub use self::builder::BuilderMethods;
 pub use self::backend::Backend;
 pub use self::consts::ConstMethods;
-pub use self::type_::TypeMethods;
+pub use self::type_::{TypeMethods, BaseTypeMethods, DerivedTypeMethods};
+pub use self::intrinsic::{IntrinsicMethods, BaseIntrinsicMethods, DerivedIntrinsicMethods};
diff --git a/src/librustc_codegen_llvm/interfaces/type_.rs b/src/librustc_codegen_llvm/interfaces/type_.rs
index f7a3af49ec9..ff594c40095 100644
--- a/src/librustc_codegen_llvm/interfaces/type_.rs
+++ b/src/librustc_codegen_llvm/interfaces/type_.rs
@@ -10,8 +10,10 @@
 
 use super::backend::Backend;
 use common::TypeKind;
+use syntax::ast;
+use rustc::ty::layout::{self, Align, Size};
 
-pub trait TypeMethods: Backend {
+pub trait BaseTypeMethods: Backend {
     fn type_void(&self) -> Self::Type;
     fn type_metadata(&self) -> Self::Type;
     fn type_i1(&self) -> Self::Type;
@@ -42,3 +44,31 @@ pub trait TypeMethods: Backend {
 
     fn val_ty(&self, v: Self::Value) -> Self::Type;
 }
+
+pub trait DerivedTypeMethods: Backend {
+    fn type_bool(&self) -> Self::Type;
+    fn type_i8p(&self) -> Self::Type;
+    fn type_isize(&self) -> Self::Type;
+    fn type_int(&self) -> Self::Type;
+    fn type_int_from_ty(
+        &self,
+        t: ast::IntTy
+    ) -> Self::Type;
+    fn type_uint_from_ty(
+        &self,
+        t: ast::UintTy
+    ) -> Self::Type;
+    fn type_float_from_ty(
+        &self,
+        t: ast::FloatTy
+    ) -> Self::Type;
+    fn type_from_integer(&self, i: layout::Integer) -> Self::Type;
+    fn type_pointee_for_abi_align(&self, align: Align) -> Self::Type;
+    fn type_padding_filler(
+        &self,
+        size: Size,
+        align: Align
+    ) -> Self::Type;
+}
+
+pub trait TypeMethods: BaseTypeMethods + DerivedTypeMethods {}
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 91a139316a2..b1709f96d10 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -32,7 +32,9 @@ use syntax::symbol::Symbol;
 use builder::Builder;
 use value::Value;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{
+    BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, DerivedIntrinsicMethods,
+};
 
 use rustc::session::Session;
 use syntax_pos::Span;
diff --git a/src/librustc_codegen_llvm/meth.rs b/src/librustc_codegen_llvm/meth.rs
index 5cc106a2255..466f8b8ac52 100644
--- a/src/librustc_codegen_llvm/meth.rs
+++ b/src/librustc_codegen_llvm/meth.rs
@@ -16,7 +16,7 @@ use consts;
 use monomorphize;
 use value::Value;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods};
 
 use rustc::ty::{self, Ty};
 use rustc::ty::layout::HasDataLayout;
diff --git a/src/librustc_codegen_llvm/mir/block.rs b/src/librustc_codegen_llvm/mir/block.rs
index 5d7eab6d3be..0fd1e28d5a6 100644
--- a/src/librustc_codegen_llvm/mir/block.rs
+++ b/src/librustc_codegen_llvm/mir/block.rs
@@ -26,7 +26,9 @@ use type_of::LayoutLlvmExt;
 use type_::Type;
 use value::Value;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{
+    BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, DerivedIntrinsicMethods,
+};
 
 use syntax::symbol::Symbol;
 use syntax_pos::Pos;
diff --git a/src/librustc_codegen_llvm/mir/constant.rs b/src/librustc_codegen_llvm/mir/constant.rs
index deb10b03ba5..d9be3fbfb2a 100644
--- a/src/librustc_codegen_llvm/mir/constant.rs
+++ b/src/librustc_codegen_llvm/mir/constant.rs
@@ -25,7 +25,7 @@ use type_::Type;
 use syntax::ast::Mutability;
 use syntax::source_map::Span;
 use value::Value;
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods};
 
 use super::super::callee;
 use super::FunctionCx;
diff --git a/src/librustc_codegen_llvm/mir/mod.rs b/src/librustc_codegen_llvm/mir/mod.rs
index fd379de95ec..94f25aa082b 100644
--- a/src/librustc_codegen_llvm/mir/mod.rs
+++ b/src/librustc_codegen_llvm/mir/mod.rs
@@ -24,7 +24,7 @@ use debuginfo::{self, declare_local, VariableAccess, VariableKind, FunctionDebug
 use monomorphize::Instance;
 use abi::{ArgTypeExt, FnType, FnTypeExt, PassMode};
 use value::Value;
-use interfaces::{BuilderMethods, ConstMethods};
+use interfaces::{BuilderMethods, ConstMethods, DerivedTypeMethods};
 
 use syntax_pos::{DUMMY_SP, NO_EXPANSION, BytePos, Span};
 use syntax::symbol::keywords;
diff --git a/src/librustc_codegen_llvm/mir/operand.rs b/src/librustc_codegen_llvm/mir/operand.rs
index 508ba263ce8..81d2b02263e 100644
--- a/src/librustc_codegen_llvm/mir/operand.rs
+++ b/src/librustc_codegen_llvm/mir/operand.rs
@@ -20,7 +20,7 @@ use value::Value;
 use type_of::LayoutLlvmExt;
 use glue;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedIntrinsicMethods};
 
 use std::fmt;
 
diff --git a/src/librustc_codegen_llvm/mir/place.rs b/src/librustc_codegen_llvm/mir/place.rs
index aa4ecc1df89..1c119f6a0a3 100644
--- a/src/librustc_codegen_llvm/mir/place.rs
+++ b/src/librustc_codegen_llvm/mir/place.rs
@@ -22,7 +22,9 @@ use value::Value;
 use glue;
 use mir::constant::const_alloc_to_llvm;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{
+    BuilderMethods, ConstMethods, BaseTypeMethods, DerivedTypeMethods, DerivedIntrinsicMethods,
+};
 
 use super::{FunctionCx, LocalRef};
 use super::operand::{OperandRef, OperandValue};
diff --git a/src/librustc_codegen_llvm/mir/rvalue.rs b/src/librustc_codegen_llvm/mir/rvalue.rs
index abd197bf434..56e3aa56e60 100644
--- a/src/librustc_codegen_llvm/mir/rvalue.rs
+++ b/src/librustc_codegen_llvm/mir/rvalue.rs
@@ -26,7 +26,7 @@ use type_::Type;
 use type_of::LayoutLlvmExt;
 use value::Value;
 
-use interfaces::{BuilderMethods, ConstMethods, TypeMethods};
+use interfaces::{BuilderMethods, ConstMethods, BaseTypeMethods, DerivedIntrinsicMethods};
 
 use super::{FunctionCx, LocalRef};
 use super::operand::{OperandRef, OperandValue};
diff --git a/src/librustc_codegen_llvm/type_.rs b/src/librustc_codegen_llvm/type_.rs
index 33ab0159909..21c815784a4 100644
--- a/src/librustc_codegen_llvm/type_.rs
+++ b/src/librustc_codegen_llvm/type_.rs
@@ -15,7 +15,7 @@ pub use llvm::Type;
 use llvm;
 use llvm::{Bool, False, True};
 use context::CodegenCx;
-use interfaces::TypeMethods;
+use interfaces::{BaseTypeMethods, DerivedTypeMethods, TypeMethods};
 use value::Value;
 
 
@@ -42,8 +42,7 @@ impl fmt::Debug for Type {
     }
 }
 
-impl TypeMethods for CodegenCx<'ll, 'tcx> {
-
+impl BaseTypeMethods for CodegenCx<'ll, 'tcx> {
     fn type_void(&self) -> &'ll Type {
         unsafe {
             llvm::LLVMVoidTypeInContext(self.llcx)
@@ -265,20 +264,20 @@ impl Type {
     }
 }
 
-impl CodegenCx<'ll, 'tcx> {
-    pub fn type_bool(&self) -> &'ll Type {
+impl DerivedTypeMethods for CodegenCx<'ll, 'tcx> {
+    fn type_bool(&self) -> &'ll Type {
         self.type_i8()
     }
 
-    pub fn type_i8p(&self) -> &'ll Type {
+    fn type_i8p(&self) -> &'ll Type {
         self.type_ptr_to(self.type_i8())
     }
 
-    pub fn type_isize(&self) -> &'ll Type {
+    fn type_isize(&self) -> &'ll Type {
         self.isize_ty
     }
 
-    pub fn type_int(&self) -> &'ll Type {
+    fn type_int(&self) -> &'ll Type {
         match &self.sess().target.target.target_c_int_width[..] {
             "16" => self.type_i16(),
             "32" => self.type_i32(),
@@ -287,7 +286,7 @@ impl CodegenCx<'ll, 'tcx> {
         }
     }
 
-    pub fn type_int_from_ty(
+    fn type_int_from_ty(
         &self,
         t: ast::IntTy
     ) -> &'ll Type {
@@ -301,7 +300,7 @@ impl CodegenCx<'ll, 'tcx> {
         }
     }
 
-    pub fn type_uint_from_ty(
+    fn type_uint_from_ty(
         &self,
         t: ast::UintTy
     ) -> &'ll Type {
@@ -315,7 +314,7 @@ impl CodegenCx<'ll, 'tcx> {
         }
     }
 
-    pub fn type_float_from_ty(
+    fn type_float_from_ty(
         &self,
         t: ast::FloatTy
     ) -> &'ll Type {
@@ -325,7 +324,7 @@ impl CodegenCx<'ll, 'tcx> {
         }
     }
 
-    pub fn type_from_integer(&self, i: layout::Integer) -> &'ll Type {
+    fn type_from_integer(&self, i: layout::Integer) -> &'ll Type {
         use rustc::ty::layout::Integer::*;
         match i {
             I8 => self.type_i8(),
@@ -338,7 +337,7 @@ impl CodegenCx<'ll, 'tcx> {
 
     /// Return a LLVM type that has at most the required alignment,
     /// as a conservative approximation for unknown pointee types.
-    pub fn type_pointee_for_abi_align(&self, align: Align) -> &'ll Type {
+    fn type_pointee_for_abi_align(&self, align: Align) -> &'ll Type {
         // FIXME(eddyb) We could find a better approximation if ity.align < align.
         let ity = layout::Integer::approximate_abi_align(self, align);
         self.type_from_integer(ity)
@@ -346,7 +345,7 @@ impl CodegenCx<'ll, 'tcx> {
 
     /// Return a LLVM type that has at most the required alignment,
     /// and exactly the required size, as a best-effort padding array.
-    pub fn type_padding_filler(
+    fn type_padding_filler(
         &self,
         size: Size,
         align: Align
@@ -358,3 +357,5 @@ impl CodegenCx<'ll, 'tcx> {
         self.type_array(self.type_from_integer(unit), size / unit_size)
     }
 }
+
+impl TypeMethods for CodegenCx<'ll, 'tcx> {}
diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs
index 5f961cf125f..e3be6c991d5 100644
--- a/src/librustc_codegen_llvm/type_of.rs
+++ b/src/librustc_codegen_llvm/type_of.rs
@@ -16,7 +16,7 @@ use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
 use rustc_target::abi::FloatTy;
 use rustc_mir::monomorphize::item::DefPathBasedNames;
 use type_::Type;
-use interfaces::TypeMethods;
+use interfaces::{BaseTypeMethods, DerivedTypeMethods};
 
 use std::fmt::Write;