Removed genericity over Value in various functions
Prelude to using associated types in traits rather than type parameters
This commit is contained in:
parent
1ca750683e
commit
9c41e1aa10
20 changed files with 165 additions and 194 deletions
|
@ -121,7 +121,7 @@ impl LlvmType for Reg {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RegKind::Vector => {
|
RegKind::Vector => {
|
||||||
Type::vector::<Value>(Type::i8(cx), self.size.bytes())
|
Type::vector(Type::i8(cx), self.size.bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,7 +145,7 @@ impl LlvmType for CastTarget {
|
||||||
|
|
||||||
// Simplify to array when all chunks are the same size and type
|
// Simplify to array when all chunks are the same size and type
|
||||||
if rem_bytes == 0 {
|
if rem_bytes == 0 {
|
||||||
return Type::array::<Value>(rest_ll_unit, rest_count);
|
return Type::array(rest_ll_unit, rest_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -675,9 +675,9 @@ impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.variadic {
|
if self.variadic {
|
||||||
Type::variadic_func::<Value>(&llargument_tys, llreturn_ty)
|
Type::variadic_func(&llargument_tys, llreturn_ty)
|
||||||
} else {
|
} else {
|
||||||
Type::func::<Value>(&llargument_tys, llreturn_ty)
|
Type::func(&llargument_tys, llreturn_ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,7 +127,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {
|
||||||
.filter(|l| !l.is_empty())
|
.filter(|l| !l.is_empty())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_, &'ll Value>, llfn: &'ll Value) {
|
pub fn apply_target_cpu_attr(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
|
||||||
let cpu = llvm_util::target_cpu(cx.tcx.sess);
|
let cpu = llvm_util::target_cpu(cx.tcx.sess);
|
||||||
let target_cpu = CString::new(cpu).unwrap();
|
let target_cpu = CString::new(cpu).unwrap();
|
||||||
llvm::AddFunctionAttrStringValue(
|
llvm::AddFunctionAttrStringValue(
|
||||||
|
|
|
@ -49,7 +49,6 @@ use context::{is_pie_binary, get_reloc_model};
|
||||||
use common::{C_bytes_in_context, val_ty};
|
use common::{C_bytes_in_context, val_ty};
|
||||||
use jobserver::{Client, Acquired};
|
use jobserver::{Client, Acquired};
|
||||||
use rustc_demangle;
|
use rustc_demangle;
|
||||||
use value::Value;
|
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::ffi::{CString, CStr};
|
use std::ffi::{CString, CStr};
|
||||||
|
@ -2575,7 +2574,7 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M
|
||||||
"\x01__imp_"
|
"\x01__imp_"
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
let i8p_ty = Type::i8p_llcx::<Value>(llcx);
|
let i8p_ty = Type::i8p_llcx(llcx);
|
||||||
let globals = base::iter_globals(llmod)
|
let globals = base::iter_globals(llmod)
|
||||||
.filter(|&val| {
|
.filter(|&val| {
|
||||||
llvm::LLVMRustGetLinkage(val) == llvm::Linkage::ExternalLinkage &&
|
llvm::LLVMRustGetLinkage(val) == llvm::Linkage::ExternalLinkage &&
|
||||||
|
|
|
@ -89,7 +89,7 @@ use syntax_pos::symbol::InternedString;
|
||||||
use syntax::attr;
|
use syntax::attr;
|
||||||
use rustc::hir::{self, CodegenFnAttrs};
|
use rustc::hir::{self, CodegenFnAttrs};
|
||||||
|
|
||||||
use value::{Value, ValueTrait};
|
use value::Value;
|
||||||
|
|
||||||
use mir::operand::OperandValue;
|
use mir::operand::OperandValue;
|
||||||
|
|
||||||
|
@ -391,11 +391,10 @@ pub fn call_assume(bx: &Builder<'_, 'll, '_>, val: &'ll Value) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_immediate<'a, 'll: 'a, 'tcx: 'll,
|
pub fn from_immediate<'a, 'll: 'a, 'tcx: 'll,
|
||||||
Value : ?Sized,
|
|
||||||
Builder: BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>>(
|
Builder: BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>>(
|
||||||
bx: &Builder,
|
bx: &Builder,
|
||||||
val: &'ll Value
|
val: &'ll Value
|
||||||
) -> &'ll Value where Value : ValueTrait {
|
) -> &'ll Value {
|
||||||
if val_ty(val) == Type::i1(bx.cx()) {
|
if val_ty(val) == Type::i1(bx.cx()) {
|
||||||
bx.zext(val, Type::i8(bx.cx()))
|
bx.zext(val, Type::i8(bx.cx()))
|
||||||
} else {
|
} else {
|
||||||
|
@ -426,7 +425,6 @@ pub fn to_immediate_scalar(
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_memcpy<'a, 'll: 'a, 'tcx: 'll,
|
pub fn call_memcpy<'a, 'll: 'a, 'tcx: 'll,
|
||||||
Value : ?Sized,
|
|
||||||
Builder: BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>>(
|
Builder: BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>>(
|
||||||
bx: &Builder,
|
bx: &Builder,
|
||||||
dst: &'ll Value,
|
dst: &'ll Value,
|
||||||
|
@ -435,7 +433,7 @@ pub fn call_memcpy<'a, 'll: 'a, 'tcx: 'll,
|
||||||
src_align: Align,
|
src_align: Align,
|
||||||
n_bytes: &'ll Value,
|
n_bytes: &'ll Value,
|
||||||
flags: MemFlags,
|
flags: MemFlags,
|
||||||
) where Value : ValueTrait {
|
) {
|
||||||
if flags.contains(MemFlags::NONTEMPORAL) {
|
if flags.contains(MemFlags::NONTEMPORAL) {
|
||||||
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
|
// HACK(nox): This is inefficient but there is no nontemporal memcpy.
|
||||||
let val = bx.load(src, src_align);
|
let val = bx.load(src, src_align);
|
||||||
|
@ -452,7 +450,6 @@ pub fn call_memcpy<'a, 'll: 'a, 'tcx: 'll,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memcpy_ty<'a, 'll: 'a, 'tcx: 'll,
|
pub fn memcpy_ty<'a, 'll: 'a, 'tcx: 'll,
|
||||||
Value : ?Sized,
|
|
||||||
Builder: BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>>(
|
Builder: BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>>(
|
||||||
bx: &Builder,
|
bx: &Builder,
|
||||||
dst: &'ll Value,
|
dst: &'ll Value,
|
||||||
|
@ -461,7 +458,7 @@ pub fn memcpy_ty<'a, 'll: 'a, 'tcx: 'll,
|
||||||
src_align: Align,
|
src_align: Align,
|
||||||
layout: TyLayout<'tcx>,
|
layout: TyLayout<'tcx>,
|
||||||
flags: MemFlags,
|
flags: MemFlags,
|
||||||
) where Value : ValueTrait {
|
) {
|
||||||
let size = layout.size.bytes();
|
let size = layout.size.bytes();
|
||||||
if size == 0 {
|
if size == 0 {
|
||||||
return;
|
return;
|
||||||
|
@ -558,7 +555,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
|
||||||
use_start_lang_item: bool,
|
use_start_lang_item: bool,
|
||||||
) {
|
) {
|
||||||
let llfty =
|
let llfty =
|
||||||
Type::func::<Value>(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], Type::c_int(cx));
|
Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], Type::c_int(cx));
|
||||||
|
|
||||||
let main_ret_ty = cx.tcx.fn_sig(rust_main_def_id).output();
|
let main_ret_ty = cx.tcx.fn_sig(rust_main_def_id).output();
|
||||||
// Given that `main()` has no arguments,
|
// Given that `main()` has no arguments,
|
||||||
|
|
|
@ -200,7 +200,8 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
||||||
args);
|
args);
|
||||||
|
|
||||||
let args = self.check_call("invoke", llfn, args);
|
let args = self.check_call("invoke", llfn, args);
|
||||||
let bundle = bundle.map(|b| &*(OperandBundleDef::from_generic(b)).raw);
|
let bundle = bundle.map(OperandBundleDef::from_generic);
|
||||||
|
let bundle = bundle.as_ref().map(|b| &*b.raw);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustBuildInvoke(self.llbuilder,
|
llvm::LLVMRustBuildInvoke(self.llbuilder,
|
||||||
|
@ -757,7 +758,7 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
debug!("Asm Output Type: {:?}", output);
|
debug!("Asm Output Type: {:?}", output);
|
||||||
let fty = Type::func::<Value>(&argtys[..], output);
|
let fty = Type::func(&argtys[..], output);
|
||||||
unsafe {
|
unsafe {
|
||||||
// Ask LLVM to verify that the constraints are well-formed.
|
// Ask LLVM to verify that the constraints are well-formed.
|
||||||
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons);
|
let constraints_ok = llvm::LLVMRustInlineAsmVerify(fty, cons);
|
||||||
|
@ -853,9 +854,9 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
||||||
fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
|
fn vector_splat(&self, num_elts: usize, elt: &'ll Value) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
let elt_ty = val_ty(elt);
|
let elt_ty = val_ty(elt);
|
||||||
let undef = llvm::LLVMGetUndef(Type::vector::<Value>(elt_ty, num_elts as u64));
|
let undef = llvm::LLVMGetUndef(Type::vector(elt_ty, num_elts as u64));
|
||||||
let vec = self.insert_element(undef, elt, C_i32(self.cx, 0));
|
let vec = self.insert_element(undef, elt, C_i32(self.cx, 0));
|
||||||
let vec_i32_ty = Type::vector::<Value>(Type::i32(self.cx), num_elts as u64);
|
let vec_i32_ty = Type::vector(Type::i32(self.cx), num_elts as u64);
|
||||||
self.shuffle_vector(vec, undef, C_null(vec_i32_ty))
|
self.shuffle_vector(vec, undef, C_null(vec_i32_ty))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1232,7 +1233,8 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
||||||
args);
|
args);
|
||||||
|
|
||||||
let args = self.check_call("call", llfn, args);
|
let args = self.check_call("call", llfn, args);
|
||||||
let bundle = bundle.map(|b| &*(OperandBundleDef::from_generic(b)).raw);
|
let bundle = bundle.map(OperandBundleDef::from_generic);
|
||||||
|
let bundle = bundle.as_ref().map(|b| &*b.raw);
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustBuildCall(
|
llvm::LLVMRustBuildCall(
|
||||||
|
@ -1260,7 +1262,7 @@ impl BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cx(&self) -> &'a CodegenCx<'ll, 'tcx, &'ll Value> {
|
fn cx(&self) -> &'a CodegenCx<'ll, 'tcx> {
|
||||||
&self.cx
|
&self.cx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ use consts;
|
||||||
use declare;
|
use declare;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use value::{Value, ValueTrait};
|
use value::Value;
|
||||||
|
|
||||||
use rustc::ty::{self, Ty, TyCtxt};
|
use rustc::ty::{self, Ty, TyCtxt};
|
||||||
use rustc::ty::layout::{HasDataLayout, LayoutOf};
|
use rustc::ty::layout::{HasDataLayout, LayoutOf};
|
||||||
|
@ -111,9 +111,9 @@ impl Funclet<'ll> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn val_ty<Value : ?Sized>(v: &'ll Value) -> &'ll Type where Value : ValueTrait {
|
pub fn val_ty(v: &'ll Value) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMTypeOf(v.to_llvm())
|
llvm::LLVMTypeOf(v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,21 +124,21 @@ pub fn C_null(t: &'ll Type) -> &'ll Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_undef<Value : ?Sized>(t: &'ll Type) -> &'ll Value where Value : ValueTrait {
|
pub fn C_undef(t: &'ll Type) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
Value::of_llvm(llvm::LLVMGetUndef(t))
|
llvm::LLVMGetUndef(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_int<Value : ?Sized>(t: &'ll Type, i: i64) -> &'ll Value where Value : ValueTrait {
|
pub fn C_int(t: &'ll Type, i: i64) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
Value::of_llvm(llvm::LLVMConstInt(t, i as u64, True))
|
llvm::LLVMConstInt(t, i as u64, True)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_uint<Value : ?Sized>(t: &'ll Type, i: u64) -> &'ll Value where Value : ValueTrait {
|
pub fn C_uint(t: &'ll Type, i: u64) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
Value::of_llvm(llvm::LLVMConstInt(t, i, False))
|
llvm::LLVMConstInt(t, i, False)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -149,17 +149,11 @@ pub fn C_uint_big(t: &'ll Type, u: u128) -> &'ll Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_bool<Value : ?Sized>(
|
pub fn C_bool(cx: &CodegenCx<'ll, '_>, val: bool) -> &'ll Value {
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
|
||||||
val: bool
|
|
||||||
) -> &'ll Value where Value : ValueTrait {
|
|
||||||
C_uint(Type::i1(cx), val as u64)
|
C_uint(Type::i1(cx), val as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_i32<Value : ?Sized>(
|
pub fn C_i32(cx: &CodegenCx<'ll, '_>, i: i32) -> &'ll Value {
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
|
||||||
i: i32
|
|
||||||
) -> &'ll Value where Value : ValueTrait {
|
|
||||||
C_int(Type::i32(cx), i as i64)
|
C_int(Type::i32(cx), i as i64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -171,10 +165,7 @@ pub fn C_u64(cx: &CodegenCx<'ll, '_>, i: u64) -> &'ll Value {
|
||||||
C_uint(Type::i64(cx), i)
|
C_uint(Type::i64(cx), i)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_usize<Value : ?Sized>(
|
pub fn C_usize(cx: &CodegenCx<'ll, '_>, i: u64) -> &'ll Value {
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
|
||||||
i: u64
|
|
||||||
) -> &'ll Value where Value : ValueTrait {
|
|
||||||
let bit_size = cx.data_layout().pointer_size.bits();
|
let bit_size = cx.data_layout().pointer_size.bits();
|
||||||
if bit_size < 64 {
|
if bit_size < 64 {
|
||||||
// make sure it doesn't overflow
|
// make sure it doesn't overflow
|
||||||
|
|
|
@ -18,7 +18,7 @@ use callee;
|
||||||
use base;
|
use base;
|
||||||
use declare;
|
use declare;
|
||||||
use monomorphize::Instance;
|
use monomorphize::Instance;
|
||||||
use value::{Value, ValueTrait};
|
use value::Value;
|
||||||
|
|
||||||
use monomorphize::partitioning::CodegenUnit;
|
use monomorphize::partitioning::CodegenUnit;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
|
@ -283,7 +283,7 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
let isize_ty = Type::ix_llcx::<Value>(llcx, tcx.data_layout.pointer_size.bits());
|
let isize_ty = Type::ix_llcx(llcx, tcx.data_layout.pointer_size.bits());
|
||||||
|
|
||||||
CodegenCx {
|
CodegenCx {
|
||||||
tcx,
|
tcx,
|
||||||
|
@ -315,7 +315,7 @@ impl<'a, 'tcx> CodegenCx<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'tcx, Value : ?Sized> CodegenCx<'b, 'tcx, &'b Value> where Value : ValueTrait {
|
impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
||||||
pub fn sess<'a>(&'a self) -> &'a Session {
|
pub fn sess<'a>(&'a self) -> &'a Session {
|
||||||
&self.tcx.sess
|
&self.tcx.sess
|
||||||
}
|
}
|
||||||
|
@ -329,7 +329,7 @@ impl<'b, 'tcx, Value : ?Sized> CodegenCx<'b, 'tcx, &'b Value> where Value : Valu
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'b, 'tcx> CodegenCx<'b, 'tcx, &'b Value> {
|
impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
||||||
/// Generate a new symbol name with the given prefix. This symbol name must
|
/// Generate a new symbol name with the given prefix. This symbol name must
|
||||||
/// only be used for definitions with `internal` or `private` linkage.
|
/// only be used for definitions with `internal` or `private` linkage.
|
||||||
pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
|
pub fn generate_local_symbol_name(&self, prefix: &str) -> String {
|
||||||
|
@ -379,7 +379,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx, &'b Value> {
|
||||||
} else {
|
} else {
|
||||||
"rust_eh_personality"
|
"rust_eh_personality"
|
||||||
};
|
};
|
||||||
let fty = Type::variadic_func::<Value>(&[], Type::i32(self));
|
let fty = Type::variadic_func(&[], Type::i32(self));
|
||||||
declare::declare_cfn(self, name, fty)
|
declare::declare_cfn(self, name, fty)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -480,31 +480,31 @@ impl LayoutOf for CodegenCx<'ll, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Declare any llvm intrinsics that you might need
|
/// Declare any llvm intrinsics that you might need
|
||||||
fn declare_intrinsic<Value : ?Sized>(
|
fn declare_intrinsic(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
key: &str
|
key: &str
|
||||||
) -> Option<&'ll Value> where Value : ValueTrait {
|
) -> Option<&'ll Value> {
|
||||||
macro_rules! ifn {
|
macro_rules! ifn {
|
||||||
($name:expr, fn() -> $ret:expr) => (
|
($name:expr, fn() -> $ret:expr) => (
|
||||||
if key == $name {
|
if key == $name {
|
||||||
let f = declare::declare_cfn(cx, $name, Type::func::<Value>(&[], $ret));
|
let f = declare::declare_cfn(cx, $name, Type::func(&[], $ret));
|
||||||
llvm::SetUnnamedAddr(f.to_llvm(), false);
|
llvm::SetUnnamedAddr(f, false);
|
||||||
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||||
return Some(f);
|
return Some(f);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
($name:expr, fn(...) -> $ret:expr) => (
|
($name:expr, fn(...) -> $ret:expr) => (
|
||||||
if key == $name {
|
if key == $name {
|
||||||
let f = declare::declare_cfn(cx, $name, Type::variadic_func::<Value>(&[], $ret));
|
let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], $ret));
|
||||||
llvm::SetUnnamedAddr(f.to_llvm(), false);
|
llvm::SetUnnamedAddr(f, false);
|
||||||
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||||
return Some(f);
|
return Some(f);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
|
($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
|
||||||
if key == $name {
|
if key == $name {
|
||||||
let f = declare::declare_cfn(cx, $name, Type::func::<Value>(&[$($arg),*], $ret));
|
let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], $ret));
|
||||||
llvm::SetUnnamedAddr(f.to_llvm(), false);
|
llvm::SetUnnamedAddr(f, false);
|
||||||
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||||
return Some(f);
|
return Some(f);
|
||||||
}
|
}
|
||||||
|
@ -525,14 +525,14 @@ fn declare_intrinsic<Value : ?Sized>(
|
||||||
let t_f32 = Type::f32(cx);
|
let t_f32 = Type::f32(cx);
|
||||||
let t_f64 = Type::f64(cx);
|
let t_f64 = Type::f64(cx);
|
||||||
|
|
||||||
let t_v2f32 = Type::vector::<Value>(t_f32, 2);
|
let t_v2f32 = Type::vector(t_f32, 2);
|
||||||
let t_v4f32 = Type::vector::<Value>(t_f32, 4);
|
let t_v4f32 = Type::vector(t_f32, 4);
|
||||||
let t_v8f32 = Type::vector::<Value>(t_f32, 8);
|
let t_v8f32 = Type::vector(t_f32, 8);
|
||||||
let t_v16f32 = Type::vector::<Value>(t_f32, 16);
|
let t_v16f32 = Type::vector(t_f32, 16);
|
||||||
|
|
||||||
let t_v2f64 = Type::vector::<Value>(t_f64, 2);
|
let t_v2f64 = Type::vector(t_f64, 2);
|
||||||
let t_v4f64 = Type::vector::<Value>(t_f64, 4);
|
let t_v4f64 = Type::vector(t_f64, 4);
|
||||||
let t_v8f64 = Type::vector::<Value>(t_f64, 8);
|
let t_v8f64 = Type::vector(t_f64, 8);
|
||||||
|
|
||||||
ifn!("llvm.memset.p0i8.i16", fn(i8p, t_i8, t_i16, t_i32, i1) -> void);
|
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.i32", fn(i8p, t_i8, t_i32, t_i32, i1) -> void);
|
||||||
|
|
|
@ -56,7 +56,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx<'ll, '_>)
|
||||||
let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
|
let section_contents = b"\x01gdb_load_rust_pretty_printers.py\0";
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let llvm_type = Type::array::<Value>(Type::i8(cx),
|
let llvm_type = Type::array(Type::i8(cx),
|
||||||
section_contents.len() as u64);
|
section_contents.len() as u64);
|
||||||
|
|
||||||
let section_var = declare::define_global(cx, section_var_name,
|
let section_var = declare::define_global(cx, section_var_name,
|
||||||
|
|
|
@ -31,7 +31,7 @@ use abi::{Abi, FnType, FnTypeExt};
|
||||||
use attributes;
|
use attributes;
|
||||||
use context::CodegenCx;
|
use context::CodegenCx;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use value::{Value, ValueTrait};
|
use value::Value;
|
||||||
|
|
||||||
|
|
||||||
/// Declare a global value.
|
/// Declare a global value.
|
||||||
|
@ -51,12 +51,12 @@ pub fn declare_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> &'l
|
||||||
///
|
///
|
||||||
/// If there’s a value with the same name already declared, the function will
|
/// If there’s a value with the same name already declared, the function will
|
||||||
/// update the declaration and return existing Value instead.
|
/// update the declaration and return existing Value instead.
|
||||||
fn declare_raw_fn<Value : ?Sized>(
|
fn declare_raw_fn(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
name: &str,
|
name: &str,
|
||||||
callconv: llvm::CallConv,
|
callconv: llvm::CallConv,
|
||||||
ty: &'ll Type,
|
ty: &'ll Type,
|
||||||
) -> &'ll Value where Value : ValueTrait {
|
) -> &'ll Value {
|
||||||
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
|
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
|
||||||
let namebuf = SmallCStr::new(name);
|
let namebuf = SmallCStr::new(name);
|
||||||
let llfn = unsafe {
|
let llfn = unsafe {
|
||||||
|
@ -105,7 +105,7 @@ fn declare_raw_fn<Value : ?Sized>(
|
||||||
|
|
||||||
attributes::non_lazy_bind(cx.sess(), llfn);
|
attributes::non_lazy_bind(cx.sess(), llfn);
|
||||||
|
|
||||||
Value::of_llvm(llfn)
|
llfn
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -116,11 +116,11 @@ fn declare_raw_fn<Value : ?Sized>(
|
||||||
///
|
///
|
||||||
/// If there’s a value with the same name already declared, the function will
|
/// If there’s a value with the same name already declared, the function will
|
||||||
/// update the declaration and return existing Value instead.
|
/// update the declaration and return existing Value instead.
|
||||||
pub fn declare_cfn<Value : ?Sized>(
|
pub fn declare_cfn(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
name: &str,
|
name: &str,
|
||||||
fn_type: &'ll Type
|
fn_type: &'ll Type
|
||||||
) -> &'ll Value where Value : ValueTrait {
|
) -> &'ll Value {
|
||||||
declare_raw_fn(cx, name, llvm::CCallConv, fn_type)
|
declare_raw_fn(cx, name, llvm::CCallConv, fn_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ pub fn define_global(cx: &CodegenCx<'ll, '_>, name: &str, ty: &'ll Type) -> Opti
|
||||||
/// Declare a private global
|
/// Declare a private global
|
||||||
///
|
///
|
||||||
/// Use this function when you intend to define a global without a name.
|
/// Use this function when you intend to define a global without a name.
|
||||||
pub fn define_private_global(cx: &CodegenCx<'ll, '_, &'ll Value>, ty: &'ll Type) -> &'ll Value {
|
pub fn define_private_global(cx: &CodegenCx<'ll, '_>, ty: &'ll Type) -> &'ll Value {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustInsertPrivateGlobal(cx.llmod, ty)
|
llvm::LLVMRustInsertPrivateGlobal(cx.llmod, ty)
|
||||||
}
|
}
|
||||||
|
|
|
@ -593,7 +593,7 @@ pub fn codegen_intrinsic_call(
|
||||||
Vector(ref t, ref llvm_elem, length) => {
|
Vector(ref t, ref llvm_elem, length) => {
|
||||||
let t = llvm_elem.as_ref().unwrap_or(t);
|
let t = llvm_elem.as_ref().unwrap_or(t);
|
||||||
let elem = one(ty_to_type(cx, t));
|
let elem = one(ty_to_type(cx, t));
|
||||||
vec![Type::vector::<Value>(elem, length as u64)]
|
vec![Type::vector(elem, length as u64)]
|
||||||
}
|
}
|
||||||
Aggregate(false, ref contents) => {
|
Aggregate(false, ref contents) => {
|
||||||
let elems = contents.iter()
|
let elems = contents.iter()
|
||||||
|
@ -644,7 +644,7 @@ pub fn codegen_intrinsic_call(
|
||||||
let llvm_elem = one(ty_to_type(bx.cx, llvm_elem));
|
let llvm_elem = one(ty_to_type(bx.cx, llvm_elem));
|
||||||
vec![
|
vec![
|
||||||
bx.bitcast(arg.immediate(),
|
bx.bitcast(arg.immediate(),
|
||||||
Type::vector::<Value>(llvm_elem, length as u64))
|
Type::vector(llvm_elem, length as u64))
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => {
|
intrinsics::Type::Integer(_, width, llvm_width) if width != llvm_width => {
|
||||||
|
@ -673,7 +673,7 @@ pub fn codegen_intrinsic_call(
|
||||||
intrinsics::IntrinsicDef::Named(name) => {
|
intrinsics::IntrinsicDef::Named(name) => {
|
||||||
let f = declare::declare_cfn(cx,
|
let f = declare::declare_cfn(cx,
|
||||||
name,
|
name,
|
||||||
Type::func::<Value>(&inputs, outputs));
|
Type::func(&inputs, outputs));
|
||||||
bx.call(f, &llargs, None)
|
bx.call(f, &llargs, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -1160,7 +1160,7 @@ fn generic_simd_intrinsic(
|
||||||
}
|
}
|
||||||
// truncate the mask to a vector of i1s
|
// truncate the mask to a vector of i1s
|
||||||
let i1 = Type::i1(bx.cx);
|
let i1 = Type::i1(bx.cx);
|
||||||
let i1xn = Type::vector::<Value>(i1, m_len as u64);
|
let i1xn = Type::vector(i1, m_len as u64);
|
||||||
let m_i1s = bx.trunc(args[0].immediate(), i1xn);
|
let m_i1s = bx.trunc(args[0].immediate(), i1xn);
|
||||||
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
|
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
|
||||||
}
|
}
|
||||||
|
@ -1301,7 +1301,7 @@ fn generic_simd_intrinsic(
|
||||||
elem_ty = elem_ty.ptr_to();
|
elem_ty = elem_ty.ptr_to();
|
||||||
no_pointers -= 1;
|
no_pointers -= 1;
|
||||||
}
|
}
|
||||||
Type::vector::<Value>(elem_ty, vec_len as u64)
|
Type::vector(elem_ty, vec_len as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1384,7 +1384,7 @@ fn generic_simd_intrinsic(
|
||||||
// Truncate the mask vector to a vector of i1s:
|
// Truncate the mask vector to a vector of i1s:
|
||||||
let (mask, mask_ty) = {
|
let (mask, mask_ty) = {
|
||||||
let i1 = Type::i1(bx.cx);
|
let i1 = Type::i1(bx.cx);
|
||||||
let i1xn = Type::vector::<Value>(i1, in_len as u64);
|
let i1xn = Type::vector(i1, in_len as u64);
|
||||||
(bx.trunc(args[2].immediate(), i1xn), i1xn)
|
(bx.trunc(args[2].immediate(), i1xn), i1xn)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1399,7 +1399,7 @@ fn generic_simd_intrinsic(
|
||||||
let llvm_intrinsic = format!("llvm.masked.gather.{}.{}",
|
let llvm_intrinsic = format!("llvm.masked.gather.{}.{}",
|
||||||
llvm_elem_vec_str, llvm_pointer_vec_str);
|
llvm_elem_vec_str, llvm_pointer_vec_str);
|
||||||
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
|
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
|
||||||
Type::func::<Value>(&[
|
Type::func(&[
|
||||||
llvm_pointer_vec_ty,
|
llvm_pointer_vec_ty,
|
||||||
alignment_ty,
|
alignment_ty,
|
||||||
mask_ty,
|
mask_ty,
|
||||||
|
@ -1484,7 +1484,7 @@ fn generic_simd_intrinsic(
|
||||||
// Truncate the mask vector to a vector of i1s:
|
// Truncate the mask vector to a vector of i1s:
|
||||||
let (mask, mask_ty) = {
|
let (mask, mask_ty) = {
|
||||||
let i1 = Type::i1(bx.cx);
|
let i1 = Type::i1(bx.cx);
|
||||||
let i1xn = Type::vector::<Value>(i1, in_len as u64);
|
let i1xn = Type::vector(i1, in_len as u64);
|
||||||
(bx.trunc(args[2].immediate(), i1xn), i1xn)
|
(bx.trunc(args[2].immediate(), i1xn), i1xn)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1501,7 +1501,7 @@ fn generic_simd_intrinsic(
|
||||||
let llvm_intrinsic = format!("llvm.masked.scatter.{}.{}",
|
let llvm_intrinsic = format!("llvm.masked.scatter.{}.{}",
|
||||||
llvm_elem_vec_str, llvm_pointer_vec_str);
|
llvm_elem_vec_str, llvm_pointer_vec_str);
|
||||||
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
|
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
|
||||||
Type::func::<Value>(&[llvm_elem_vec_ty,
|
Type::func(&[llvm_elem_vec_ty,
|
||||||
llvm_pointer_vec_ty,
|
llvm_pointer_vec_ty,
|
||||||
alignment_ty,
|
alignment_ty,
|
||||||
mask_ty], ret_t));
|
mask_ty], ret_t));
|
||||||
|
@ -1636,7 +1636,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
||||||
|
|
||||||
// boolean reductions operate on vectors of i1s:
|
// boolean reductions operate on vectors of i1s:
|
||||||
let i1 = Type::i1(bx.cx);
|
let i1 = Type::i1(bx.cx);
|
||||||
let i1xn = Type::vector::<Value>(i1, in_len as u64);
|
let i1xn = Type::vector(i1, in_len as u64);
|
||||||
bx.trunc(args[0].immediate(), i1xn)
|
bx.trunc(args[0].immediate(), i1xn)
|
||||||
};
|
};
|
||||||
return match in_elem.sty {
|
return match in_elem.sty {
|
||||||
|
|
|
@ -52,7 +52,7 @@ impl<'a, 'tcx> VirtualIndex {
|
||||||
|
|
||||||
pub fn get_usize(
|
pub fn get_usize(
|
||||||
self,
|
self,
|
||||||
bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
llvtable: &'ll Value
|
llvtable: &'ll Value
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
// Load the data pointer from the object.
|
// Load the data pointer from the object.
|
||||||
|
|
|
@ -101,7 +101,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
};
|
};
|
||||||
|
|
||||||
let funclet_br =
|
let funclet_br =
|
||||||
|this: &mut Self, bx: Builder<'_, 'll, '_, &'ll Value>, target: mir::BasicBlock| {
|
|this: &mut Self, bx: Builder<'_, 'll, '_>, target: mir::BasicBlock| {
|
||||||
let (lltarget, is_cleanupret) = lltarget(this, target);
|
let (lltarget, is_cleanupret) = lltarget(this, target);
|
||||||
if is_cleanupret {
|
if is_cleanupret {
|
||||||
// micro-optimization: generate a `ret` rather than a jump
|
// micro-optimization: generate a `ret` rather than a jump
|
||||||
|
@ -848,7 +848,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
|
|
||||||
fn get_personality_slot(
|
fn get_personality_slot(
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Builder<'a, 'll, 'tcx, &'ll Value>
|
bx: &Builder<'a, 'll, 'tcx>
|
||||||
) -> PlaceRef<'tcx, &'ll Value> {
|
) -> PlaceRef<'tcx, &'ll Value> {
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
if let Some(slot) = self.personality_slot {
|
if let Some(slot) = self.personality_slot {
|
||||||
|
|
|
@ -122,7 +122,7 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
|
|
||||||
pub fn set_debug_loc(
|
pub fn set_debug_loc(
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Builder<'_, 'll, '_, &'ll Value>,
|
bx: &Builder<'_, 'll, '_>,
|
||||||
source_info: mir::SourceInfo
|
source_info: mir::SourceInfo
|
||||||
) {
|
) {
|
||||||
let (scope, span) = self.debug_loc(source_info);
|
let (scope, span) = self.debug_loc(source_info);
|
||||||
|
|
|
@ -16,7 +16,7 @@ use rustc::ty::layout::{self, Align, LayoutOf, TyLayout};
|
||||||
use base;
|
use base;
|
||||||
use common::{CodegenCx, C_undef, C_usize};
|
use common::{CodegenCx, C_undef, C_usize};
|
||||||
use builder::{Builder, MemFlags};
|
use builder::{Builder, MemFlags};
|
||||||
use value::{Value, ValueTrait};
|
use value::Value;
|
||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use glue;
|
use glue;
|
||||||
|
@ -63,7 +63,7 @@ pub struct OperandRef<'tcx, V> {
|
||||||
pub layout: TyLayout<'tcx>,
|
pub layout: TyLayout<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<Value: ?Sized> fmt::Debug for OperandRef<'tcx, &'ll Value> where Value: ValueTrait {
|
impl fmt::Debug for OperandRef<'tcx, &'ll Value> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "OperandRef({:?} @ {:?})", self.val, self.layout)
|
write!(f, "OperandRef({:?} @ {:?})", self.val, self.layout)
|
||||||
}
|
}
|
||||||
|
@ -265,7 +265,7 @@ impl OperandValue<&'ll Value> {
|
||||||
|
|
||||||
pub fn volatile_store(
|
pub fn volatile_store(
|
||||||
self,
|
self,
|
||||||
bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
dest: PlaceRef<'tcx, &'ll Value>
|
dest: PlaceRef<'tcx, &'ll Value>
|
||||||
) {
|
) {
|
||||||
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
|
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
|
||||||
|
@ -280,14 +280,12 @@ impl OperandValue<&'ll Value> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'll: 'a, 'tcx: 'll, Value : ?Sized> OperandValue<&'ll Value> where
|
impl<'a, 'll: 'a, 'tcx: 'll> OperandValue<&'ll Value> where
|
||||||
Value : ValueTrait,
|
Builder<'a, 'll, 'tcx>: BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
||||||
Builder<'a, 'll, 'tcx, &'ll Value>:
|
|
||||||
BuilderMethods<'a, 'll, 'tcx, Value, BasicBlock>
|
|
||||||
{
|
{
|
||||||
pub fn nontemporal_store(
|
pub fn nontemporal_store(
|
||||||
self,
|
self,
|
||||||
bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
dest: PlaceRef<'tcx, &'ll Value>
|
dest: PlaceRef<'tcx, &'ll Value>
|
||||||
) {
|
) {
|
||||||
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
|
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
|
||||||
|
@ -331,7 +329,7 @@ impl<'a, 'll: 'a, 'tcx: 'll, Value : ?Sized> OperandValue<&'ll Value> where
|
||||||
impl OperandValue<&'ll Value> {
|
impl OperandValue<&'ll Value> {
|
||||||
pub fn store_unsized(
|
pub fn store_unsized(
|
||||||
self,
|
self,
|
||||||
bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
indirect_dest: PlaceRef<'tcx, &'ll Value>
|
indirect_dest: PlaceRef<'tcx, &'ll Value>
|
||||||
) {
|
) {
|
||||||
debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest);
|
debug!("OperandRef::store_unsized: operand={:?}, indirect_dest={:?}", self, indirect_dest);
|
||||||
|
|
|
@ -284,7 +284,7 @@ impl PlaceRef<'tcx, &'ll Value> {
|
||||||
/// Obtain the actual discriminant of a value.
|
/// Obtain the actual discriminant of a value.
|
||||||
pub fn codegen_get_discr(
|
pub fn codegen_get_discr(
|
||||||
self,
|
self,
|
||||||
bx: &Builder<'a, 'll, 'tcx, &'ll Value>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
cast_to: Ty<'tcx>
|
cast_to: Ty<'tcx>
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx);
|
let cast_to = bx.cx.layout_of(cast_to).immediate_llvm_type(bx.cx);
|
||||||
|
|
|
@ -180,10 +180,10 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_rvalue_unsized(&mut self,
|
pub fn codegen_rvalue_unsized(&mut self,
|
||||||
bx: Builder<'a, 'll, 'tcx, &'ll Value>,
|
bx: Builder<'a, 'll, 'tcx>,
|
||||||
indirect_dest: PlaceRef<'tcx, &'ll Value>,
|
indirect_dest: PlaceRef<'tcx, &'ll Value>,
|
||||||
rvalue: &mir::Rvalue<'tcx>)
|
rvalue: &mir::Rvalue<'tcx>)
|
||||||
-> Builder<'a, 'll, 'tcx, &'ll Value>
|
-> Builder<'a, 'll, 'tcx>
|
||||||
{
|
{
|
||||||
debug!("codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})",
|
debug!("codegen_rvalue_unsized(indirect_dest.llval={:?}, rvalue={:?})",
|
||||||
indirect_dest.llval, rvalue);
|
indirect_dest.llval, rvalue);
|
||||||
|
@ -201,9 +201,9 @@ impl FunctionCx<'a, 'll, 'tcx, &'ll Value> {
|
||||||
|
|
||||||
pub fn codegen_rvalue_operand(
|
pub fn codegen_rvalue_operand(
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: Builder<'a, 'll, 'tcx, &'ll Value>,
|
bx: Builder<'a, 'll, 'tcx>,
|
||||||
rvalue: &mir::Rvalue<'tcx>
|
rvalue: &mir::Rvalue<'tcx>
|
||||||
) -> (Builder<'a, 'll, 'tcx, &'ll Value>, OperandRef<'tcx, &'ll Value>) {
|
) -> (Builder<'a, 'll, 'tcx>, OperandRef<'tcx, &'ll Value>) {
|
||||||
assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue);
|
assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue);
|
||||||
|
|
||||||
match *rvalue {
|
match *rvalue {
|
||||||
|
@ -753,7 +753,7 @@ enum OverflowOp {
|
||||||
|
|
||||||
fn get_overflow_intrinsic(
|
fn get_overflow_intrinsic(
|
||||||
oop: OverflowOp,
|
oop: OverflowOp,
|
||||||
bx: &Builder<'_, 'll, '_, &'ll Value>,
|
bx: &Builder<'_, 'll, '_>,
|
||||||
ty: Ty
|
ty: Ty
|
||||||
) -> &'ll Value {
|
) -> &'ll Value {
|
||||||
use syntax::ast::IntTy::*;
|
use syntax::ast::IntTy::*;
|
||||||
|
|
|
@ -109,14 +109,14 @@ pub trait BuilderMethods<'a, 'll :'a, 'tcx: 'll,
|
||||||
> {
|
> {
|
||||||
|
|
||||||
fn new_block<'b>(
|
fn new_block<'b>(
|
||||||
cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>,
|
cx: &'a CodegenCx<'ll, 'tcx>,
|
||||||
llfn: &'ll Value,
|
llfn: &'ll Value,
|
||||||
name: &'b str
|
name: &'b str
|
||||||
) -> Self;
|
) -> Self;
|
||||||
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx, &'ll Value>) -> Self;
|
fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self;
|
||||||
fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
|
fn build_sibling_block<'b>(&self, name: &'b str) -> Self;
|
||||||
fn sess(&self) -> &Session;
|
fn sess(&self) -> &Session;
|
||||||
fn cx(&self) -> &'a CodegenCx<'ll, 'tcx, &'ll Value>;
|
fn cx(&self) -> &'a CodegenCx<'ll, 'tcx>;
|
||||||
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
|
fn tcx(&self) -> TyCtxt<'a, 'tcx, 'tcx>;
|
||||||
fn llfn(&self) -> &'ll Value;
|
fn llfn(&self) -> &'ll Value;
|
||||||
fn llbb(&self) -> &'ll BasicBlock;
|
fn llbb(&self) -> &'ll BasicBlock;
|
||||||
|
|
|
@ -16,7 +16,6 @@ use llvm;
|
||||||
use llvm::{Bool, False, True, TypeKind};
|
use llvm::{Bool, False, True, TypeKind};
|
||||||
|
|
||||||
use context::CodegenCx;
|
use context::CodegenCx;
|
||||||
use value::{Value, ValueTrait};
|
|
||||||
|
|
||||||
use syntax::ast;
|
use syntax::ast;
|
||||||
use rustc::ty::layout::{self, Align, Size};
|
use rustc::ty::layout::{self, Align, Size};
|
||||||
|
@ -41,143 +40,143 @@ impl fmt::Debug for Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Type {
|
impl Type {
|
||||||
pub fn void<Value : ?Sized>(
|
pub fn void(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMVoidTypeInContext(cx.llcx)
|
llvm::LLVMVoidTypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metadata<Value : ?Sized>(
|
pub fn metadata(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustMetadataTypeInContext(cx.llcx)
|
llvm::LLVMRustMetadataTypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i1<Value : ?Sized>(
|
pub fn i1(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMInt1TypeInContext(cx.llcx)
|
llvm::LLVMInt1TypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8<Value : ?Sized>(
|
pub fn i8(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMInt8TypeInContext(cx.llcx)
|
llvm::LLVMInt8TypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8_llcx<Value : ?Sized>(llcx: &llvm::Context) -> &Type where Value : ValueTrait {
|
pub fn i8_llcx(llcx: &llvm::Context) -> &Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMInt8TypeInContext(llcx)
|
llvm::LLVMInt8TypeInContext(llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i16<Value : ?Sized>(
|
pub fn i16(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>) -> &'ll Type where Value : ValueTrait {
|
cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
|
|
||||||
llvm::LLVMInt16TypeInContext(cx.llcx)
|
llvm::LLVMInt16TypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i32<Value : ?Sized>(
|
pub fn i32(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMInt32TypeInContext(cx.llcx)
|
llvm::LLVMInt32TypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i64<Value : ?Sized>(
|
pub fn i64(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMInt64TypeInContext(cx.llcx)
|
llvm::LLVMInt64TypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i128<Value : ?Sized>(
|
pub fn i128(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMIntTypeInContext(cx.llcx, 128)
|
llvm::LLVMIntTypeInContext(cx.llcx, 128)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an integer type with the given number of bits, e.g. i24
|
// Creates an integer type with the given number of bits, e.g. i24
|
||||||
pub fn ix<Value : ?Sized>(
|
pub fn ix(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
num_bits: u64
|
num_bits: u64
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)
|
llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creates an integer type with the given number of bits, e.g. i24
|
// Creates an integer type with the given number of bits, e.g. i24
|
||||||
pub fn ix_llcx<Value : ?Sized>(
|
pub fn ix_llcx(
|
||||||
llcx: &llvm::Context,
|
llcx: &llvm::Context,
|
||||||
num_bits: u64
|
num_bits: u64
|
||||||
) -> &Type where Value : ValueTrait {
|
) -> &Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)
|
llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32<Value : ?Sized>(
|
pub fn f32(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMFloatTypeInContext(cx.llcx)
|
llvm::LLVMFloatTypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64<Value : ?Sized>(
|
pub fn f64(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMDoubleTypeInContext(cx.llcx)
|
llvm::LLVMDoubleTypeInContext(cx.llcx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bool<Value : ?Sized>(
|
pub fn bool(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
Type::i8(cx)
|
Type::i8(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn char<Value : ?Sized>(
|
pub fn char(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
Type::i32(cx)
|
Type::i32(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8p<Value : ?Sized>(
|
pub fn i8p(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
Type::i8(cx).ptr_to()
|
Type::i8(cx).ptr_to()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8p_llcx<Value : ?Sized>(llcx: &llvm::Context) -> &Type where Value : ValueTrait {
|
pub fn i8p_llcx(llcx: &llvm::Context) -> &Type {
|
||||||
Type::i8_llcx::<Value>(llcx).ptr_to()
|
Type::i8_llcx(llcx).ptr_to()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isize<Value : ?Sized>(
|
pub fn isize(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
cx.isize_ty
|
cx.isize_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn c_int<Value : ?Sized>(
|
pub fn c_int(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>
|
cx: &CodegenCx<'ll, '_>
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
match &cx.tcx.sess.target.target.target_c_int_width[..] {
|
match &cx.tcx.sess.target.target.target_c_int_width[..] {
|
||||||
"16" => Type::i16(cx),
|
"16" => Type::i16(cx),
|
||||||
"32" => Type::i32(cx),
|
"32" => Type::i32(cx),
|
||||||
|
@ -186,10 +185,10 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn int_from_ty<Value : ?Sized>(
|
pub fn int_from_ty(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
t: ast::IntTy
|
t: ast::IntTy
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
match t {
|
match t {
|
||||||
ast::IntTy::Isize => cx.isize_ty,
|
ast::IntTy::Isize => cx.isize_ty,
|
||||||
ast::IntTy::I8 => Type::i8(cx),
|
ast::IntTy::I8 => Type::i8(cx),
|
||||||
|
@ -200,10 +199,10 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uint_from_ty<Value : ?Sized>(
|
pub fn uint_from_ty(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
t: ast::UintTy
|
t: ast::UintTy
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
match t {
|
match t {
|
||||||
ast::UintTy::Usize => cx.isize_ty,
|
ast::UintTy::Usize => cx.isize_ty,
|
||||||
ast::UintTy::U8 => Type::i8(cx),
|
ast::UintTy::U8 => Type::i8(cx),
|
||||||
|
@ -214,41 +213,41 @@ impl Type {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn float_from_ty<Value : ?Sized>(
|
pub fn float_from_ty(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
t: ast::FloatTy
|
t: ast::FloatTy
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
match t {
|
match t {
|
||||||
ast::FloatTy::F32 => Type::f32(cx),
|
ast::FloatTy::F32 => Type::f32(cx),
|
||||||
ast::FloatTy::F64 => Type::f64(cx),
|
ast::FloatTy::F64 => Type::f64(cx),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn func<Value : ?Sized>(
|
pub fn func(
|
||||||
args: &[&'ll Type],
|
args: &[&'ll Type],
|
||||||
ret: &'ll Type
|
ret: &'ll Type
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
||||||
args.len() as c_uint, False)
|
args.len() as c_uint, False)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variadic_func<Value : ?Sized>(
|
pub fn variadic_func(
|
||||||
args: &[&'ll Type],
|
args: &[&'ll Type],
|
||||||
ret: &'ll Type
|
ret: &'ll Type
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
||||||
args.len() as c_uint, True)
|
args.len() as c_uint, True)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn struct_<Value : ?Sized>(
|
pub fn struct_(
|
||||||
cx: &CodegenCx<'ll, '_, &'ll Value>,
|
cx: &CodegenCx<'ll, '_>,
|
||||||
els: &[&'ll Type],
|
els: &[&'ll Type],
|
||||||
packed: bool
|
packed: bool
|
||||||
) -> &'ll Type where Value : ValueTrait {
|
) -> &'ll Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
|
llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
|
||||||
els.len() as c_uint,
|
els.len() as c_uint,
|
||||||
|
@ -264,13 +263,13 @@ impl Type {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn array<Value : ?Sized>(ty: &Type, len: u64) -> &Type where Value : ValueTrait {
|
pub fn array(ty: &Type, len: u64) -> &Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustArrayType(ty, len)
|
llvm::LLVMRustArrayType(ty, len)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vector<Value : ?Sized>(ty: &Type, len: u64) -> &Type where Value : ValueTrait {
|
pub fn vector(ty: &Type, len: u64) -> &Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMVectorType(ty, len as c_uint)
|
llvm::LLVMVectorType(ty, len as c_uint)
|
||||||
}
|
}
|
||||||
|
@ -363,7 +362,7 @@ impl Type {
|
||||||
let size = size.bytes();
|
let size = size.bytes();
|
||||||
let unit_size = unit.size().bytes();
|
let unit_size = unit.size().bytes();
|
||||||
assert_eq!(size % unit_size, 0);
|
assert_eq!(size % unit_size, 0);
|
||||||
Type::array::<Value>(Type::from_integer(cx, unit), size / unit_size)
|
Type::array(Type::from_integer(cx, unit), size / unit_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
|
|
|
@ -16,7 +16,6 @@ use rustc::ty::layout::{self, Align, LayoutOf, Size, TyLayout};
|
||||||
use rustc_target::abi::FloatTy;
|
use rustc_target::abi::FloatTy;
|
||||||
use rustc_mir::monomorphize::item::DefPathBasedNames;
|
use rustc_mir::monomorphize::item::DefPathBasedNames;
|
||||||
use type_::Type;
|
use type_::Type;
|
||||||
use value::Value;
|
|
||||||
|
|
||||||
use std::fmt::Write;
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
@ -41,7 +40,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
return Type::x86_mmx(cx)
|
return Type::x86_mmx(cx)
|
||||||
} else {
|
} else {
|
||||||
let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO);
|
let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO);
|
||||||
return Type::vector::<Value>(element, count);
|
return Type::vector(element, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layout::Abi::ScalarPair(..) => {
|
layout::Abi::ScalarPair(..) => {
|
||||||
|
@ -94,7 +93,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layout::FieldPlacement::Array { count, .. } => {
|
layout::FieldPlacement::Array { count, .. } => {
|
||||||
Type::array::<Value>(layout.field(cx, 0).llvm_type(cx), count)
|
Type::array(layout.field(cx, 0).llvm_type(cx), count)
|
||||||
}
|
}
|
||||||
layout::FieldPlacement::Arbitrary { .. } => {
|
layout::FieldPlacement::Arbitrary { .. } => {
|
||||||
match name {
|
match name {
|
||||||
|
|
|
@ -15,26 +15,12 @@ use llvm;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::hash::{Hash, Hasher};
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
pub trait ValueTrait: fmt::Debug {
|
|
||||||
fn to_llvm(&self) -> &llvm::Value;
|
|
||||||
fn of_llvm(&llvm::Value) -> &Self;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PartialEq for Value {
|
impl PartialEq for Value {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
self as *const _ == other as *const _
|
self as *const _ == other as *const _
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ValueTrait for Value {
|
|
||||||
fn to_llvm(&self) -> &llvm::Value {
|
|
||||||
&self
|
|
||||||
}
|
|
||||||
fn of_llvm(v: &llvm::Value) -> &Self {
|
|
||||||
&v
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Eq for Value {}
|
impl Eq for Value {}
|
||||||
|
|
||||||
impl Hash for Value {
|
impl Hash for Value {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue