mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-05 03:38:29 +00:00
rustc_codegen_llvm: use safe references for Type.
This commit is contained in:
parent
249d5acaec
commit
d04e66d114
@ -103,11 +103,11 @@ impl ArgAttributesExt for ArgAttributes {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait LlvmType {
|
pub trait LlvmType {
|
||||||
fn llvm_type(&self, cx: &CodegenCx) -> Type;
|
fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LlvmType for Reg {
|
impl LlvmType for Reg {
|
||||||
fn llvm_type(&self, cx: &CodegenCx) -> Type {
|
fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
match self.kind {
|
match self.kind {
|
||||||
RegKind::Integer => Type::ix(cx, self.size.bits()),
|
RegKind::Integer => Type::ix(cx, self.size.bits()),
|
||||||
RegKind::Float => {
|
RegKind::Float => {
|
||||||
@ -118,14 +118,14 @@ impl LlvmType for Reg {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
RegKind::Vector => {
|
RegKind::Vector => {
|
||||||
Type::vector(&Type::i8(cx), self.size.bytes())
|
Type::vector(Type::i8(cx), self.size.bytes())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl LlvmType for CastTarget {
|
impl LlvmType for CastTarget {
|
||||||
fn llvm_type(&self, cx: &CodegenCx) -> Type {
|
fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
let rest_ll_unit = self.rest.unit.llvm_type(cx);
|
let rest_ll_unit = self.rest.unit.llvm_type(cx);
|
||||||
let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
|
let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
|
||||||
(0, 0)
|
(0, 0)
|
||||||
@ -142,7 +142,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(&rest_ll_unit, rest_count);
|
return Type::array(rest_ll_unit, rest_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -165,15 +165,15 @@ impl LlvmType for CastTarget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub trait ArgTypeExt<'a, 'tcx> {
|
pub trait ArgTypeExt<'a, 'tcx> {
|
||||||
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
|
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
|
||||||
fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>);
|
fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>);
|
||||||
fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>);
|
fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
|
impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
|
||||||
/// Get the LLVM type for a place of the original Rust type of
|
/// Get the LLVM type for a place of the original Rust type of
|
||||||
/// this argument/return, i.e. the result of `type_of::type_of`.
|
/// this argument/return, i.e. the result of `type_of::type_of`.
|
||||||
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
|
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
|
||||||
self.layout.llvm_type(cx)
|
self.layout.llvm_type(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -181,7 +181,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
|
|||||||
/// place for the original Rust type of this argument/return.
|
/// place for the original Rust type of this argument/return.
|
||||||
/// Can be used for both storing formal arguments into Rust variables
|
/// Can be used for both storing formal arguments into Rust variables
|
||||||
/// or results of call/invoke instructions into their destinations.
|
/// or results of call/invoke instructions into their destinations.
|
||||||
fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) {
|
fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>) {
|
||||||
if self.is_ignore() {
|
if self.is_ignore() {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -234,7 +234,7 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) {
|
fn store_fn_arg(&self, bx: &Builder<'a, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>) {
|
||||||
let mut next = || {
|
let mut next = || {
|
||||||
let val = llvm::get_param(bx.llfn(), *idx as c_uint);
|
let val = llvm::get_param(bx.llfn(), *idx as c_uint);
|
||||||
*idx += 1;
|
*idx += 1;
|
||||||
@ -270,10 +270,10 @@ pub trait FnTypeExt<'a, 'tcx> {
|
|||||||
fn adjust_for_abi(&mut self,
|
fn adjust_for_abi(&mut self,
|
||||||
cx: &CodegenCx<'a, 'tcx>,
|
cx: &CodegenCx<'a, 'tcx>,
|
||||||
abi: Abi);
|
abi: Abi);
|
||||||
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
|
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
|
||||||
fn llvm_cconv(&self) -> llvm::CallConv;
|
fn llvm_cconv(&self) -> llvm::CallConv;
|
||||||
fn apply_attrs_llfn(&self, llfn: ValueRef);
|
fn apply_attrs_llfn(&self, llfn: ValueRef);
|
||||||
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'tcx>, callsite: ValueRef);
|
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
|
impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
|
||||||
@ -564,7 +564,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
|
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
|
||||||
let args_capacity: usize = self.args.iter().map(|arg|
|
let args_capacity: usize = self.args.iter().map(|arg|
|
||||||
if arg.pad.is_some() { 1 } else { 0 } +
|
if arg.pad.is_some() { 1 } else { 0 } +
|
||||||
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
|
if let PassMode::Pair(_, _) = arg.mode { 2 } else { 1 }
|
||||||
@ -606,9 +606,9 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.variadic {
|
if self.variadic {
|
||||||
Type::variadic_func(&llargument_tys, &llreturn_ty)
|
Type::variadic_func(&llargument_tys, llreturn_ty)
|
||||||
} else {
|
} else {
|
||||||
Type::func(&llargument_tys, &llreturn_ty)
|
Type::func(&llargument_tys, llreturn_ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,7 +659,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'tcx>, callsite: ValueRef) {
|
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: ValueRef) {
|
||||||
let mut i = 0;
|
let mut i = 0;
|
||||||
let mut apply = |attrs: &ArgAttributes| {
|
let mut apply = |attrs: &ArgAttributes| {
|
||||||
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
|
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
|
||||||
|
@ -24,8 +24,8 @@ use syntax::ast::AsmDialect;
|
|||||||
use libc::{c_uint, c_char};
|
use libc::{c_uint, c_char};
|
||||||
|
|
||||||
// Take an inline assembly expression and splat it out via LLVM
|
// Take an inline assembly expression and splat it out via LLVM
|
||||||
pub fn codegen_inline_asm<'a, 'tcx>(
|
pub fn codegen_inline_asm(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
ia: &hir::InlineAsm,
|
ia: &hir::InlineAsm,
|
||||||
outputs: Vec<PlaceRef<'tcx>>,
|
outputs: Vec<PlaceRef<'tcx>>,
|
||||||
mut inputs: Vec<ValueRef>
|
mut inputs: Vec<ValueRef>
|
||||||
|
@ -831,7 +831,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
|
|||||||
let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
|
let llconst = C_bytes_in_context(llcx, bitcode.unwrap_or(&[]));
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal = llvm::LLVMAddGlobal(
|
||||||
llmod,
|
llmod,
|
||||||
val_ty(llconst).to_ref(),
|
val_ty(llconst),
|
||||||
"rustc.embedded.module\0".as_ptr() as *const _,
|
"rustc.embedded.module\0".as_ptr() as *const _,
|
||||||
);
|
);
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
@ -851,7 +851,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
|
|||||||
let llconst = C_bytes_in_context(llcx, &[]);
|
let llconst = C_bytes_in_context(llcx, &[]);
|
||||||
let llglobal = llvm::LLVMAddGlobal(
|
let llglobal = llvm::LLVMAddGlobal(
|
||||||
llmod,
|
llmod,
|
||||||
val_ty(llconst).to_ref(),
|
val_ty(llconst),
|
||||||
"rustc.embedded.cmdline\0".as_ptr() as *const _,
|
"rustc.embedded.cmdline\0".as_ptr() as *const _,
|
||||||
);
|
);
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
@ -2380,7 +2380,7 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M
|
|||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
for (imp_name, val) in globals {
|
for (imp_name, val) in globals {
|
||||||
let imp = llvm::LLVMAddGlobal(llmod,
|
let imp = llvm::LLVMAddGlobal(llmod,
|
||||||
i8p_ty.to_ref(),
|
i8p_ty,
|
||||||
imp_name.as_ptr() as *const _);
|
imp_name.as_ptr() as *const _);
|
||||||
llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty));
|
llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty));
|
||||||
llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
|
llvm::LLVMRustSetLinkage(imp, llvm::Linkage::ExternalLinkage);
|
||||||
|
@ -19,9 +19,9 @@
|
|||||||
//!
|
//!
|
||||||
//! * There's no way to find out the Ty type of a ValueRef. Doing so
|
//! * There's no way to find out the Ty type of a ValueRef. Doing so
|
||||||
//! would be "trying to get the eggs out of an omelette" (credit:
|
//! would be "trying to get the eggs out of an omelette" (credit:
|
||||||
//! pcwalton). You can, instead, find out its TypeRef by calling val_ty,
|
//! pcwalton). You can, instead, find out its llvm::Type by calling val_ty,
|
||||||
//! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
|
//! but one llvm::Type corresponds to many `Ty`s; for instance, tup(int, int,
|
||||||
//! int) and rec(x=int, y=int, z=int) will have the same TypeRef.
|
//! int) and rec(x=int, y=int, z=int) will have the same llvm::Type.
|
||||||
|
|
||||||
use super::ModuleLlvm;
|
use super::ModuleLlvm;
|
||||||
use super::ModuleSource;
|
use super::ModuleSource;
|
||||||
@ -91,14 +91,14 @@ use mir::operand::OperandValue;
|
|||||||
|
|
||||||
use rustc_codegen_utils::check_for_rustc_errors_attr;
|
use rustc_codegen_utils::check_for_rustc_errors_attr;
|
||||||
|
|
||||||
pub struct StatRecorder<'a, 'tcx: 'a> {
|
pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll> {
|
||||||
cx: &'a CodegenCx<'a, 'tcx>,
|
cx: &'a CodegenCx<'ll, 'tcx>,
|
||||||
name: Option<String>,
|
name: Option<String>,
|
||||||
istart: usize,
|
istart: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
|
impl StatRecorder<'a, 'll, 'tcx> {
|
||||||
pub fn new(cx: &'a CodegenCx<'a, 'tcx>, name: String) -> StatRecorder<'a, 'tcx> {
|
pub fn new(cx: &'a CodegenCx<'ll, 'tcx>, name: String) -> Self {
|
||||||
let istart = cx.stats.borrow().n_llvm_insns;
|
let istart = cx.stats.borrow().n_llvm_insns;
|
||||||
StatRecorder {
|
StatRecorder {
|
||||||
cx,
|
cx,
|
||||||
@ -108,7 +108,7 @@ impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Drop for StatRecorder<'a, 'tcx> {
|
impl Drop for StatRecorder<'a, 'll, 'tcx> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
if self.cx.sess().codegen_stats() {
|
if self.cx.sess().codegen_stats() {
|
||||||
let mut stats = self.cx.stats.borrow_mut();
|
let mut stats = self.cx.stats.borrow_mut();
|
||||||
@ -155,12 +155,12 @@ pub fn bin_op_to_fcmp_predicate(op: hir::BinOpKind) -> llvm::RealPredicate {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compare_simd_types<'a, 'tcx>(
|
pub fn compare_simd_types(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
lhs: ValueRef,
|
lhs: ValueRef,
|
||||||
rhs: ValueRef,
|
rhs: ValueRef,
|
||||||
t: Ty<'tcx>,
|
t: Ty<'tcx>,
|
||||||
ret_ty: Type,
|
ret_ty: &'ll Type,
|
||||||
op: hir::BinOpKind
|
op: hir::BinOpKind
|
||||||
) -> ValueRef {
|
) -> ValueRef {
|
||||||
let signed = match t.sty {
|
let signed = match t.sty {
|
||||||
@ -216,8 +216,8 @@ pub fn unsized_info<'cx, 'tcx>(cx: &CodegenCx<'cx, 'tcx>,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
|
/// Coerce `src` to `dst_ty`. `src_ty` must be a thin pointer.
|
||||||
pub fn unsize_thin_ptr<'a, 'tcx>(
|
pub fn unsize_thin_ptr(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
src: ValueRef,
|
src: ValueRef,
|
||||||
src_ty: Ty<'tcx>,
|
src_ty: Ty<'tcx>,
|
||||||
dst_ty: Ty<'tcx>
|
dst_ty: Ty<'tcx>
|
||||||
@ -271,9 +271,11 @@ pub fn unsize_thin_ptr<'a, 'tcx>(
|
|||||||
|
|
||||||
/// Coerce `src`, which is a reference to a value of type `src_ty`,
|
/// Coerce `src`, which is a reference to a value of type `src_ty`,
|
||||||
/// to a value of type `dst_ty` and store the result in `dst`
|
/// to a value of type `dst_ty` and store the result in `dst`
|
||||||
pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
pub fn coerce_unsized_into(
|
||||||
src: PlaceRef<'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
dst: PlaceRef<'tcx>) {
|
src: PlaceRef<'tcx>,
|
||||||
|
dst: PlaceRef<'tcx>
|
||||||
|
) {
|
||||||
let src_ty = src.layout.ty;
|
let src_ty = src.layout.ty;
|
||||||
let dst_ty = dst.layout.ty;
|
let dst_ty = dst.layout.ty;
|
||||||
let coerce_ptr = || {
|
let coerce_ptr = || {
|
||||||
@ -334,14 +336,14 @@ pub fn cast_shift_expr_rhs(
|
|||||||
cast_shift_rhs(op, lhs, rhs, |a, b| cx.trunc(a, b), |a, b| cx.zext(a, b))
|
cast_shift_rhs(op, lhs, rhs, |a, b| cx.trunc(a, b), |a, b| cx.zext(a, b))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_shift_rhs<F, G>(op: hir::BinOpKind,
|
fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind,
|
||||||
lhs: ValueRef,
|
lhs: ValueRef,
|
||||||
rhs: ValueRef,
|
rhs: ValueRef,
|
||||||
trunc: F,
|
trunc: F,
|
||||||
zext: G)
|
zext: G)
|
||||||
-> ValueRef
|
-> ValueRef
|
||||||
where F: FnOnce(ValueRef, Type) -> ValueRef,
|
where F: FnOnce(ValueRef, &'ll Type) -> ValueRef,
|
||||||
G: FnOnce(ValueRef, Type) -> ValueRef
|
G: FnOnce(ValueRef, &'ll Type) -> ValueRef
|
||||||
{
|
{
|
||||||
// Shifts may have any size int on the rhs
|
// Shifts may have any size int on the rhs
|
||||||
if op.is_shift() {
|
if op.is_shift() {
|
||||||
@ -378,7 +380,7 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
|
|||||||
sess.target.target.options.is_like_msvc
|
sess.target.target.options.is_like_msvc
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_assume<'a, 'tcx>(bx: &Builder<'a, 'tcx>, val: ValueRef) {
|
pub fn call_assume(bx: &Builder<'a, 'll, 'tcx>, val: ValueRef) {
|
||||||
let assume_intrinsic = bx.cx.get_intrinsic("llvm.assume");
|
let assume_intrinsic = bx.cx.get_intrinsic("llvm.assume");
|
||||||
bx.call(assume_intrinsic, &[val], None);
|
bx.call(assume_intrinsic, &[val], None);
|
||||||
}
|
}
|
||||||
@ -430,8 +432,8 @@ pub fn call_memcpy(bx: &Builder,
|
|||||||
bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
|
bx.call(memcpy, &[dst_ptr, src_ptr, size, align, volatile], None);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn memcpy_ty<'a, 'tcx>(
|
pub fn memcpy_ty(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
dst: ValueRef,
|
dst: ValueRef,
|
||||||
src: ValueRef,
|
src: ValueRef,
|
||||||
layout: TyLayout<'tcx>,
|
layout: TyLayout<'tcx>,
|
||||||
@ -446,12 +448,14 @@ pub fn memcpy_ty<'a, 'tcx>(
|
|||||||
call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags);
|
call_memcpy(bx, dst, src, C_usize(bx.cx, size), align, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
pub fn call_memset(
|
||||||
ptr: ValueRef,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
fill_byte: ValueRef,
|
ptr: ValueRef,
|
||||||
size: ValueRef,
|
fill_byte: ValueRef,
|
||||||
align: ValueRef,
|
size: ValueRef,
|
||||||
volatile: bool) -> ValueRef {
|
align: ValueRef,
|
||||||
|
volatile: bool,
|
||||||
|
) -> ValueRef {
|
||||||
let ptr_width = &bx.cx.sess().target.target.target_pointer_width;
|
let ptr_width = &bx.cx.sess().target.target.target_pointer_width;
|
||||||
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
|
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
|
||||||
let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key);
|
let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key);
|
||||||
@ -553,7 +557,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
|
|||||||
rust_main: ValueRef,
|
rust_main: ValueRef,
|
||||||
rust_main_def_id: DefId,
|
rust_main_def_id: DefId,
|
||||||
use_start_lang_item: bool) {
|
use_start_lang_item: bool) {
|
||||||
let llfty = Type::func(&[Type::c_int(cx), Type::i8p(cx).ptr_to()], &Type::c_int(cx));
|
let llfty = 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,
|
||||||
@ -656,7 +660,7 @@ fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
|
|||||||
let name = exported_symbols::metadata_symbol_name(tcx);
|
let name = exported_symbols::metadata_symbol_name(tcx);
|
||||||
let buf = CString::new(name).unwrap();
|
let buf = CString::new(name).unwrap();
|
||||||
let llglobal = unsafe {
|
let llglobal = unsafe {
|
||||||
llvm::LLVMAddGlobal(metadata_llmod, val_ty(llconst).to_ref(), buf.as_ptr())
|
llvm::LLVMAddGlobal(metadata_llmod, val_ty(llconst), buf.as_ptr())
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||||
@ -1206,7 +1210,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
// Run replace-all-uses-with for statics that need it
|
// Run replace-all-uses-with for statics that need it
|
||||||
for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() {
|
for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() {
|
||||||
unsafe {
|
unsafe {
|
||||||
let bitcast = llvm::LLVMConstPointerCast(new_g, llvm::LLVMTypeOf(old_g));
|
let bitcast = llvm::LLVMConstPointerCast(new_g, val_ty(old_g));
|
||||||
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
|
llvm::LLVMReplaceAllUsesWith(old_g, bitcast);
|
||||||
llvm::LLVMDeleteGlobal(old_g);
|
llvm::LLVMDeleteGlobal(old_g);
|
||||||
}
|
}
|
||||||
@ -1221,7 +1225,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
|||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let g = llvm::LLVMAddGlobal(cx.llmod,
|
let g = llvm::LLVMAddGlobal(cx.llmod,
|
||||||
val_ty(array).to_ref(),
|
val_ty(array),
|
||||||
name.as_ptr());
|
name.as_ptr());
|
||||||
llvm::LLVMSetInitializer(g, array);
|
llvm::LLVMSetInitializer(g, array);
|
||||||
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
|
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
|
||||||
|
@ -31,12 +31,12 @@ use syntax_pos::Span;
|
|||||||
|
|
||||||
// All Builders must have an llfn associated with them
|
// All Builders must have an llfn associated with them
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub struct Builder<'a, 'tcx: 'a> {
|
pub struct Builder<'a, 'll: 'a, 'tcx: 'll> {
|
||||||
pub llbuilder: BuilderRef,
|
pub llbuilder: BuilderRef,
|
||||||
pub cx: &'a CodegenCx<'a, 'tcx>,
|
pub cx: &'a CodegenCx<'ll, 'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Drop for Builder<'a, 'tcx> {
|
impl Drop for Builder<'a, 'll, 'tcx> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMDisposeBuilder(self.llbuilder);
|
llvm::LLVMDisposeBuilder(self.llbuilder);
|
||||||
@ -59,8 +59,8 @@ bitflags! {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
impl Builder<'a, 'll, 'tcx> {
|
||||||
pub fn new_block<'b>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
|
pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
|
||||||
let bx = Builder::with_cx(cx);
|
let bx = Builder::with_cx(cx);
|
||||||
let llbb = unsafe {
|
let llbb = unsafe {
|
||||||
let name = CString::new(name).unwrap();
|
let name = CString::new(name).unwrap();
|
||||||
@ -74,7 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
bx
|
bx
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_cx(cx: &'a CodegenCx<'a, 'tcx>) -> Self {
|
pub fn with_cx(cx: &'a CodegenCx<'ll, 'tcx>) -> Self {
|
||||||
// Create a fresh builder from the crate context.
|
// Create a fresh builder from the crate context.
|
||||||
let llbuilder = unsafe {
|
let llbuilder = unsafe {
|
||||||
llvm::LLVMCreateBuilderInContext(cx.llcx)
|
llvm::LLVMCreateBuilderInContext(cx.llcx)
|
||||||
@ -85,7 +85,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'tcx> {
|
pub fn build_sibling_block<'b>(&self, name: &'b str) -> Builder<'a, 'll, 'tcx> {
|
||||||
Builder::new_block(self.cx, self.llfn(), name)
|
Builder::new_block(self.cx, self.llfn(), name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -504,7 +504,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef {
|
pub fn alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef {
|
||||||
let bx = Builder::with_cx(self.cx);
|
let bx = Builder::with_cx(self.cx);
|
||||||
bx.position_at_start(unsafe {
|
bx.position_at_start(unsafe {
|
||||||
llvm::LLVMGetFirstBasicBlock(self.llfn())
|
llvm::LLVMGetFirstBasicBlock(self.llfn())
|
||||||
@ -512,14 +512,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
bx.dynamic_alloca(ty, name, align)
|
bx.dynamic_alloca(ty, name, align)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dynamic_alloca(&self, ty: Type, name: &str, align: Align) -> ValueRef {
|
pub fn dynamic_alloca(&self, ty: &'ll Type, name: &str, align: Align) -> ValueRef {
|
||||||
self.count_insn("alloca");
|
self.count_insn("alloca");
|
||||||
unsafe {
|
unsafe {
|
||||||
let alloca = if name.is_empty() {
|
let alloca = if name.is_empty() {
|
||||||
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
|
llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
|
||||||
} else {
|
} else {
|
||||||
let name = CString::new(name).unwrap();
|
let name = CString::new(name).unwrap();
|
||||||
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(),
|
llvm::LLVMBuildAlloca(self.llbuilder, ty,
|
||||||
name.as_ptr())
|
name.as_ptr())
|
||||||
};
|
};
|
||||||
llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
|
llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
|
||||||
@ -678,136 +678,136 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Casts */
|
/* Casts */
|
||||||
pub fn trunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn trunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("trunc");
|
self.count_insn("trunc");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildTrunc(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zext(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn zext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("zext");
|
self.count_insn("zext");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildZExt(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sext(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn sext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("sext");
|
self.count_insn("sext");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildSExt(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fptoui(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn fptoui(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("fptoui");
|
self.count_insn("fptoui");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildFPToUI(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fptosi(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn fptosi(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("fptosi");
|
self.count_insn("fptosi");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty.to_ref(),noname())
|
llvm::LLVMBuildFPToSI(self.llbuilder, val, dest_ty,noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn uitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("uitofp");
|
self.count_insn("uitofp");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildUIToFP(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sitofp(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn sitofp(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("sitofp");
|
self.count_insn("sitofp");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildSIToFP(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fptrunc(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn fptrunc(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("fptrunc");
|
self.count_insn("fptrunc");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildFPTrunc(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fpext(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn fpext(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("fpext");
|
self.count_insn("fpext");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildFPExt(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ptrtoint(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn ptrtoint(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("ptrtoint");
|
self.count_insn("ptrtoint");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildPtrToInt(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn inttoptr(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn inttoptr(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("inttoptr");
|
self.count_insn("inttoptr");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildIntToPtr(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("bitcast");
|
self.count_insn("bitcast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildBitCast(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn zext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("zextorbitcast");
|
self.count_insn("zextorbitcast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildZExtOrBitCast(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn sext_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("sextorbitcast");
|
self.count_insn("sextorbitcast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildSExtOrBitCast(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn trunc_or_bitcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("truncorbitcast");
|
self.count_insn("truncorbitcast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildTruncOrBitCast(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn cast(&self, op: Opcode, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("cast");
|
self.count_insn("cast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildCast(self.llbuilder, op, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn pointercast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn pointercast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("pointercast");
|
self.count_insn("pointercast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildPointerCast(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn intcast(&self, val: ValueRef, dest_ty: Type, is_signed: bool) -> ValueRef {
|
pub fn intcast(&self, val: ValueRef, dest_ty: &'ll Type, is_signed: bool) -> ValueRef {
|
||||||
self.count_insn("intcast");
|
self.count_insn("intcast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty.to_ref(), is_signed)
|
llvm::LLVMRustBuildIntCast(self.llbuilder, val, dest_ty, is_signed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn fpcast(&self, val: ValueRef, dest_ty: Type) -> ValueRef {
|
pub fn fpcast(&self, val: ValueRef, dest_ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("fpcast");
|
self.count_insn("fpcast");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty.to_ref(), noname())
|
llvm::LLVMBuildFPCast(self.llbuilder, val, dest_ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -828,14 +828,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Miscellaneous instructions */
|
/* Miscellaneous instructions */
|
||||||
pub fn empty_phi(&self, ty: Type) -> ValueRef {
|
pub fn empty_phi(&self, ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("emptyphi");
|
self.count_insn("emptyphi");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildPhi(self.llbuilder, ty.to_ref(), noname())
|
llvm::LLVMBuildPhi(self.llbuilder, ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn phi(&self, ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef {
|
pub fn phi(&self, ty: &'ll Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef {
|
||||||
assert_eq!(vals.len(), bbs.len());
|
assert_eq!(vals.len(), bbs.len());
|
||||||
let phi = self.empty_phi(ty);
|
let phi = self.empty_phi(ty);
|
||||||
self.count_insn("addincoming");
|
self.count_insn("addincoming");
|
||||||
@ -865,7 +865,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
self.count_insn("inlineasm");
|
self.count_insn("inlineasm");
|
||||||
let comment_text = CString::new(comment_text).unwrap();
|
let comment_text = CString::new(comment_text).unwrap();
|
||||||
let asm = unsafe {
|
let asm = unsafe {
|
||||||
llvm::LLVMConstInlineAsm(Type::func(&[], &Type::void(self.cx)).to_ref(),
|
llvm::LLVMConstInlineAsm(Type::func(&[], Type::void(self.cx)),
|
||||||
comment_text.as_ptr(), noname(), False,
|
comment_text.as_ptr(), noname(), False,
|
||||||
False)
|
False)
|
||||||
};
|
};
|
||||||
@ -874,7 +874,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
|
pub fn inline_asm_call(&self, asm: *const c_char, cons: *const c_char,
|
||||||
inputs: &[ValueRef], output: Type,
|
inputs: &[ValueRef], output: &'ll Type,
|
||||||
volatile: bool, alignstack: bool,
|
volatile: bool, alignstack: bool,
|
||||||
dia: AsmDialect) -> ValueRef {
|
dia: AsmDialect) -> ValueRef {
|
||||||
self.count_insn("inlineasm");
|
self.count_insn("inlineasm");
|
||||||
@ -890,10 +890,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}).collect::<Vec<_>>();
|
}).collect::<Vec<_>>();
|
||||||
|
|
||||||
debug!("Asm Output Type: {:?}", output);
|
debug!("Asm Output Type: {:?}", output);
|
||||||
let fty = Type::func(&argtys[..], &output);
|
let fty = Type::func(&argtys[..], output);
|
||||||
unsafe {
|
unsafe {
|
||||||
let v = llvm::LLVMRustInlineAsm(
|
let v = llvm::LLVMRustInlineAsm(
|
||||||
fty.to_ref(), asm, cons, volatile, alignstack, dia);
|
fty, asm, cons, volatile, alignstack, dia);
|
||||||
self.call(v, inputs, None)
|
self.call(v, inputs, None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -946,10 +946,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn va_arg(&self, list: ValueRef, ty: Type) -> ValueRef {
|
pub fn va_arg(&self, list: ValueRef, ty: &'ll Type) -> ValueRef {
|
||||||
self.count_insn("vaarg");
|
self.count_insn("vaarg");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildVAArg(self.llbuilder, list, ty.to_ref(), noname())
|
llvm::LLVMBuildVAArg(self.llbuilder, list, ty, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -977,9 +977,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef {
|
pub fn vector_splat(&self, num_elts: usize, elt: ValueRef) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
let elt_ty = val_ty(elt);
|
let elt_ty = val_ty(elt);
|
||||||
let undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, num_elts as u64).to_ref());
|
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(&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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1164,11 +1164,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn landing_pad(&self, ty: Type, pers_fn: ValueRef,
|
pub fn landing_pad(&self, ty: &'ll Type, pers_fn: ValueRef,
|
||||||
num_clauses: usize) -> ValueRef {
|
num_clauses: usize) -> ValueRef {
|
||||||
self.count_insn("landingpad");
|
self.count_insn("landingpad");
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMBuildLandingPad(self.llbuilder, ty.to_ref(), pers_fn,
|
llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn,
|
||||||
num_clauses as c_uint, noname())
|
num_clauses as c_uint, noname())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,41 +112,42 @@ impl Funclet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn val_ty(v: ValueRef) -> Type {
|
// TODO: use proper lifetime in return type
|
||||||
|
pub fn val_ty(v: ValueRef) -> &'static Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
Type::from_ref(llvm::LLVMTypeOf(v))
|
llvm::LLVMTypeOf(&*v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// LLVM constant constructors.
|
// LLVM constant constructors.
|
||||||
pub fn C_null(t: Type) -> ValueRef {
|
pub fn C_null(t: &Type) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstNull(t.to_ref())
|
llvm::LLVMConstNull(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_undef(t: Type) -> ValueRef {
|
pub fn C_undef(t: &Type) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMGetUndef(t.to_ref())
|
llvm::LLVMGetUndef(t)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_int(t: Type, i: i64) -> ValueRef {
|
pub fn C_int(t: &Type, i: i64) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstInt(t.to_ref(), i as u64, True)
|
llvm::LLVMConstInt(t, i as u64, True)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_uint(t: Type, i: u64) -> ValueRef {
|
pub fn C_uint(t: &Type, i: u64) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstInt(t.to_ref(), i, False)
|
llvm::LLVMConstInt(t, i, False)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_uint_big(t: Type, u: u128) -> ValueRef {
|
pub fn C_uint_big(t: &Type, u: u128) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
let words = [u as u64, (u >> 64) as u64];
|
let words = [u as u64, (u >> 64) as u64];
|
||||||
llvm::LLVMConstIntOfArbitraryPrecision(t.to_ref(), 2, words.as_ptr())
|
llvm::LLVMConstIntOfArbitraryPrecision(t, 2, words.as_ptr())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -233,9 +234,9 @@ pub fn C_struct_in_context(llcx: &llvm::Context, elts: &[ValueRef], packed: bool
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef {
|
pub fn C_array(ty: &Type, elts: &[ValueRef]) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
return llvm::LLVMConstArray(ty.to_ref(), elts.as_ptr(), elts.len() as c_uint);
|
return llvm::LLVMConstArray(ty, elts.as_ptr(), elts.len() as c_uint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -345,8 +346,8 @@ pub fn langcall(tcx: TyCtxt,
|
|||||||
// all shifts). For 32- and 64-bit types, this matches the semantics
|
// all shifts). For 32- and 64-bit types, this matches the semantics
|
||||||
// of Java. (See related discussion on #1877 and #10183.)
|
// of Java. (See related discussion on #1877 and #10183.)
|
||||||
|
|
||||||
pub fn build_unchecked_lshift<'a, 'tcx>(
|
pub fn build_unchecked_lshift(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
lhs: ValueRef,
|
lhs: ValueRef,
|
||||||
rhs: ValueRef
|
rhs: ValueRef
|
||||||
) -> ValueRef {
|
) -> ValueRef {
|
||||||
@ -356,8 +357,8 @@ pub fn build_unchecked_lshift<'a, 'tcx>(
|
|||||||
bx.shl(lhs, rhs)
|
bx.shl(lhs, rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_unchecked_rshift<'a, 'tcx>(
|
pub fn build_unchecked_rshift(
|
||||||
bx: &Builder<'a, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef
|
bx: &Builder<'a, 'll, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef
|
||||||
) -> ValueRef {
|
) -> ValueRef {
|
||||||
let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
|
let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
|
||||||
// #1877, #10183: Ensure that input is always valid
|
// #1877, #10183: Ensure that input is always valid
|
||||||
@ -370,15 +371,15 @@ pub fn build_unchecked_rshift<'a, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn shift_mask_rhs<'a, 'tcx>(bx: &Builder<'a, 'tcx>, rhs: ValueRef) -> ValueRef {
|
fn shift_mask_rhs(bx: &Builder<'a, 'll, 'tcx>, rhs: ValueRef) -> ValueRef {
|
||||||
let rhs_llty = val_ty(rhs);
|
let rhs_llty = val_ty(rhs);
|
||||||
bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false))
|
bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn shift_mask_val<'a, 'tcx>(
|
pub fn shift_mask_val(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
llty: Type,
|
llty: &'ll Type,
|
||||||
mask_llty: Type,
|
mask_llty: &'ll Type,
|
||||||
invert: bool
|
invert: bool
|
||||||
) -> ValueRef {
|
) -> ValueRef {
|
||||||
let kind = llty.kind();
|
let kind = llty.kind();
|
||||||
|
@ -31,15 +31,15 @@ use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags};
|
|||||||
|
|
||||||
use std::ffi::{CStr, CString};
|
use std::ffi::{CStr, CString};
|
||||||
|
|
||||||
pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
|
pub fn ptrcast(val: ValueRef, ty: &Type) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstPointerCast(val, ty.to_ref())
|
llvm::LLVMConstPointerCast(val, ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bitcast(val: ValueRef, ty: Type) -> ValueRef {
|
pub fn bitcast(val: ValueRef, ty: &Type) -> ValueRef {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMConstBitCast(val, ty.to_ref())
|
llvm::LLVMConstBitCast(val, ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +294,7 @@ pub fn codegen_static<'a, 'tcx>(
|
|||||||
let mut val_llty = val_ty(v);
|
let mut val_llty = val_ty(v);
|
||||||
let v = if val_llty == Type::i1(cx) {
|
let v = if val_llty == Type::i1(cx) {
|
||||||
val_llty = Type::i8(cx);
|
val_llty = Type::i8(cx);
|
||||||
llvm::LLVMConstZExt(v, val_llty.to_ref())
|
llvm::LLVMConstZExt(v, val_llty)
|
||||||
} else {
|
} else {
|
||||||
v
|
v
|
||||||
};
|
};
|
||||||
@ -316,7 +316,7 @@ pub fn codegen_static<'a, 'tcx>(
|
|||||||
let visibility = llvm::LLVMRustGetVisibility(g);
|
let visibility = llvm::LLVMRustGetVisibility(g);
|
||||||
|
|
||||||
let new_g = llvm::LLVMRustGetOrInsertGlobal(
|
let new_g = llvm::LLVMRustGetOrInsertGlobal(
|
||||||
cx.llmod, name_string.as_ptr(), val_llty.to_ref());
|
cx.llmod, name_string.as_ptr(), val_llty);
|
||||||
|
|
||||||
llvm::LLVMRustSetLinkage(new_g, linkage);
|
llvm::LLVMRustSetLinkage(new_g, linkage);
|
||||||
llvm::LLVMRustSetVisibility(new_g, visibility);
|
llvm::LLVMRustSetVisibility(new_g, visibility);
|
||||||
@ -411,7 +411,7 @@ pub fn codegen_static<'a, 'tcx>(
|
|||||||
|
|
||||||
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
|
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
|
||||||
// This static will be stored in the llvm.used variable which is an array of i8*
|
// This static will be stored in the llvm.used variable which is an array of i8*
|
||||||
let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx).to_ref());
|
let cast = llvm::LLVMConstPointerCast(g, Type::i8p(cx));
|
||||||
cx.used_statics.borrow_mut().push(cast);
|
cx.used_statics.borrow_mut().push(cast);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -89,10 +89,10 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
|
|||||||
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
|
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
|
||||||
pub used_statics: RefCell<Vec<ValueRef>>,
|
pub used_statics: RefCell<Vec<ValueRef>>,
|
||||||
|
|
||||||
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>>,
|
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), &'a Type>>,
|
||||||
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
|
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'a Type>>,
|
||||||
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
|
pub pointee_infos: RefCell<FxHashMap<(Ty<'tcx>, Size), Option<PointeeInfo>>>,
|
||||||
pub isize_ty: Type,
|
pub isize_ty: &'a Type,
|
||||||
|
|
||||||
pub dbg_cx: Option<debuginfo::CrateDebugContext<'a, 'tcx>>,
|
pub dbg_cx: Option<debuginfo::CrateDebugContext<'a, 'tcx>>,
|
||||||
|
|
||||||
@ -373,7 +373,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
|||||||
} else {
|
} else {
|
||||||
"rust_eh_personality"
|
"rust_eh_personality"
|
||||||
};
|
};
|
||||||
let fty = Type::variadic_func(&[], &Type::i32(self));
|
let fty = Type::variadic_func(&[], Type::i32(self));
|
||||||
declare::declare_cfn(self, name, fty)
|
declare::declare_cfn(self, name, fty)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -439,25 +439,25 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ty::layout::HasDataLayout for &'a CodegenCx<'a, 'tcx> {
|
impl ty::layout::HasDataLayout for &'a CodegenCx<'ll, 'tcx> {
|
||||||
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
|
fn data_layout(&self) -> &ty::layout::TargetDataLayout {
|
||||||
&self.tcx.data_layout
|
&self.tcx.data_layout
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> HasTargetSpec for &'a CodegenCx<'a, 'tcx> {
|
impl HasTargetSpec for &'a CodegenCx<'ll, 'tcx> {
|
||||||
fn target_spec(&self) -> &Target {
|
fn target_spec(&self) -> &Target {
|
||||||
&self.tcx.sess.target.target
|
&self.tcx.sess.target.target
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'a, 'tcx> {
|
impl ty::layout::HasTyCtxt<'tcx> for &'a CodegenCx<'ll, 'tcx> {
|
||||||
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'tcx, 'tcx> {
|
||||||
self.tcx
|
self.tcx
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> LayoutOf for &'a CodegenCx<'a, 'tcx> {
|
impl LayoutOf for &'a CodegenCx<'ll, 'tcx> {
|
||||||
type Ty = Ty<'tcx>;
|
type Ty = Ty<'tcx>;
|
||||||
type TyLayout = TyLayout<'tcx>;
|
type TyLayout = TyLayout<'tcx>;
|
||||||
|
|
||||||
@ -475,7 +475,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
|||||||
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(&[], &$ret));
|
let f = declare::declare_cfn(cx, $name, Type::func(&[], $ret));
|
||||||
llvm::SetUnnamedAddr(f, 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);
|
||||||
@ -483,7 +483,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
|||||||
);
|
);
|
||||||
($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(&[], &$ret));
|
let f = declare::declare_cfn(cx, $name, Type::variadic_func(&[], $ret));
|
||||||
llvm::SetUnnamedAddr(f, 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);
|
||||||
@ -491,7 +491,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
|||||||
);
|
);
|
||||||
($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(&[$($arg),*], &$ret));
|
let f = declare::declare_cfn(cx, $name, Type::func(&[$($arg),*], $ret));
|
||||||
llvm::SetUnnamedAddr(f, 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);
|
||||||
@ -513,14 +513,14 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
|||||||
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(&t_f32, 2);
|
let t_v2f32 = Type::vector(t_f32, 2);
|
||||||
let t_v4f32 = Type::vector(&t_f32, 4);
|
let t_v4f32 = Type::vector(t_f32, 4);
|
||||||
let t_v8f32 = Type::vector(&t_f32, 8);
|
let t_v8f32 = Type::vector(t_f32, 8);
|
||||||
let t_v16f32 = Type::vector(&t_f32, 16);
|
let t_v16f32 = Type::vector(t_f32, 16);
|
||||||
|
|
||||||
let t_v2f64 = Type::vector(&t_f64, 2);
|
let t_v2f64 = Type::vector(t_f64, 2);
|
||||||
let t_v4f64 = Type::vector(&t_f64, 4);
|
let t_v4f64 = Type::vector(t_f64, 4);
|
||||||
let t_v8f64 = Type::vector(&t_f64, 8);
|
let t_v8f64 = Type::vector(t_f64, 8);
|
||||||
|
|
||||||
ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
|
ifn!("llvm.memcpy.p0i8.p0i8.i16", fn(i8p, i8p, t_i16, t_i32, i1) -> void);
|
||||||
ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
|
ifn!("llvm.memcpy.p0i8.p0i8.i32", fn(i8p, i8p, t_i32, t_i32, i1) -> void);
|
||||||
|
@ -54,7 +54,7 @@ pub fn get_or_insert_gdb_debug_scripts_section_global(cx: &CodegenCx)
|
|||||||
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(&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,
|
||||||
|
@ -471,14 +471,16 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn declare_local<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
pub fn declare_local(
|
||||||
dbg_context: &FunctionDebugContext,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
variable_name: ast::Name,
|
dbg_context: &FunctionDebugContext,
|
||||||
variable_type: Ty<'tcx>,
|
variable_name: ast::Name,
|
||||||
scope_metadata: DIScope,
|
variable_type: Ty<'tcx>,
|
||||||
variable_access: VariableAccess,
|
scope_metadata: DIScope,
|
||||||
variable_kind: VariableKind,
|
variable_access: VariableAccess,
|
||||||
span: Span) {
|
variable_kind: VariableKind,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
assert!(!dbg_context.get_ref(span).source_locations_enabled.get());
|
assert!(!dbg_context.get_ref(span).source_locations_enabled.get());
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
|
|
||||||
|
@ -49,8 +49,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>)
|
pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, 'tcx> {
|
||||||
-> &'a CrateDebugContext<'a, 'tcx> {
|
|
||||||
cx.dbg_cx.as_ref().unwrap()
|
cx.dbg_cx.as_ref().unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,13 +40,13 @@ use std::ffi::CString;
|
|||||||
///
|
///
|
||||||
/// 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
|
||||||
/// return its ValueRef instead.
|
/// return its ValueRef instead.
|
||||||
pub fn declare_global(cx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef {
|
pub fn declare_global(cx: &CodegenCx, name: &str, ty: &Type) -> llvm::ValueRef {
|
||||||
debug!("declare_global(name={:?})", name);
|
debug!("declare_global(name={:?})", name);
|
||||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
||||||
bug!("name {:?} contains an interior null byte", name)
|
bug!("name {:?} contains an interior null byte", name)
|
||||||
});
|
});
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty.to_ref())
|
llvm::LLVMRustGetOrInsertGlobal(cx.llmod, namebuf.as_ptr(), ty)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,13 +55,13 @@ pub fn declare_global(cx: &CodegenCx, name: &str, ty: Type) -> llvm::ValueRef {
|
|||||||
///
|
///
|
||||||
/// 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 ValueRef instead.
|
/// update the declaration and return existing ValueRef instead.
|
||||||
fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Type) -> ValueRef {
|
fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: &Type) -> ValueRef {
|
||||||
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
|
debug!("declare_raw_fn(name={:?}, ty={:?})", name, ty);
|
||||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
||||||
bug!("name {:?} contains an interior null byte", name)
|
bug!("name {:?} contains an interior null byte", name)
|
||||||
});
|
});
|
||||||
let llfn = unsafe {
|
let llfn = unsafe {
|
||||||
llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty.to_ref())
|
llvm::LLVMRustGetOrInsertFunction(cx.llmod, namebuf.as_ptr(), ty)
|
||||||
};
|
};
|
||||||
|
|
||||||
llvm::SetFunctionCallConv(llfn, callconv);
|
llvm::SetFunctionCallConv(llfn, callconv);
|
||||||
@ -115,7 +115,7 @@ fn declare_raw_fn(cx: &CodegenCx, name: &str, callconv: llvm::CallConv, ty: Type
|
|||||||
///
|
///
|
||||||
/// 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 ValueRef instead.
|
/// update the declaration and return existing ValueRef instead.
|
||||||
pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: Type) -> ValueRef {
|
pub fn declare_cfn(cx: &CodegenCx, name: &str, fn_type: &Type) -> ValueRef {
|
||||||
declare_raw_fn(cx, name, llvm::CCallConv, fn_type)
|
declare_raw_fn(cx, name, llvm::CCallConv, fn_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -154,7 +154,7 @@ pub fn declare_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, name: &str,
|
|||||||
/// return None if the name already has a definition associated with it. In that
|
/// return None if the name already has a definition associated with it. In that
|
||||||
/// case an error should be reported to the user, because it usually happens due
|
/// case an error should be reported to the user, because it usually happens due
|
||||||
/// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
|
/// to user’s fault (e.g. misuse of #[no_mangle] or #[export_name] attributes).
|
||||||
pub fn define_global(cx: &CodegenCx, name: &str, ty: Type) -> Option<ValueRef> {
|
pub fn define_global(cx: &CodegenCx, name: &str, ty: &Type) -> Option<ValueRef> {
|
||||||
if get_defined_value(cx, name).is_some() {
|
if get_defined_value(cx, name).is_some() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
|
@ -23,7 +23,7 @@ use rustc::ty::layout::LayoutOf;
|
|||||||
use rustc::ty::{self, Ty};
|
use rustc::ty::{self, Ty};
|
||||||
use value::Value;
|
use value::Value;
|
||||||
|
|
||||||
pub fn size_and_align_of_dst<'a, 'tcx>(bx: &Builder<'a, 'tcx>, t: Ty<'tcx>, info: ValueRef)
|
pub fn size_and_align_of_dst(bx: &Builder<'a, 'll, 'tcx>, t: Ty<'tcx>, info: ValueRef)
|
||||||
-> (ValueRef, ValueRef) {
|
-> (ValueRef, ValueRef) {
|
||||||
debug!("calculate size of DST: {}; with lost info: {:?}",
|
debug!("calculate size of DST: {}; with lost info: {:?}",
|
||||||
t, Value(info));
|
t, Value(info));
|
||||||
|
@ -85,12 +85,14 @@ fn get_simple_intrinsic(cx: &CodegenCx, name: &str) -> Option<ValueRef> {
|
|||||||
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
|
/// Remember to add all intrinsics here, in librustc_typeck/check/mod.rs,
|
||||||
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
|
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
|
||||||
/// add them to librustc_codegen_llvm/context.rs
|
/// add them to librustc_codegen_llvm/context.rs
|
||||||
pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
pub fn codegen_intrinsic_call(
|
||||||
callee_ty: Ty<'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
fn_ty: &FnType<'tcx, Ty<'tcx>>,
|
callee_ty: Ty<'tcx>,
|
||||||
args: &[OperandRef<'tcx>],
|
fn_ty: &FnType<'tcx, Ty<'tcx>>,
|
||||||
llresult: ValueRef,
|
args: &[OperandRef<'tcx>],
|
||||||
span: Span) {
|
llresult: ValueRef,
|
||||||
|
span: Span,
|
||||||
|
) {
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
let tcx = cx.tcx;
|
let tcx = cx.tcx;
|
||||||
|
|
||||||
@ -545,7 +547,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
assert_eq!(x.len(), 1);
|
assert_eq!(x.len(), 1);
|
||||||
x.into_iter().next().unwrap()
|
x.into_iter().next().unwrap()
|
||||||
}
|
}
|
||||||
fn ty_to_type(cx: &CodegenCx, t: &intrinsics::Type) -> Vec<Type> {
|
fn ty_to_type(cx: &CodegenCx<'ll, '_>, t: &intrinsics::Type) -> Vec<&'ll Type> {
|
||||||
use intrinsics::Type::*;
|
use intrinsics::Type::*;
|
||||||
match *t {
|
match *t {
|
||||||
Void => vec![Type::void(cx)],
|
Void => vec![Type::void(cx)],
|
||||||
@ -567,7 +569,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
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(&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()
|
||||||
@ -587,10 +589,11 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
// qux` to be converted into `foo, bar, baz, qux`, integer
|
// qux` to be converted into `foo, bar, baz, qux`, integer
|
||||||
// arguments to be truncated as needed and pointers to be
|
// arguments to be truncated as needed and pointers to be
|
||||||
// cast.
|
// cast.
|
||||||
fn modify_as_needed<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
fn modify_as_needed(
|
||||||
t: &intrinsics::Type,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
arg: &OperandRef<'tcx>)
|
t: &intrinsics::Type,
|
||||||
-> Vec<ValueRef>
|
arg: &OperandRef<'tcx>,
|
||||||
|
) -> Vec<ValueRef>
|
||||||
{
|
{
|
||||||
match *t {
|
match *t {
|
||||||
intrinsics::Type::Aggregate(true, ref contents) => {
|
intrinsics::Type::Aggregate(true, ref contents) => {
|
||||||
@ -616,7 +619,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => {
|
intrinsics::Type::Vector(_, Some(ref llvm_elem), length) => {
|
||||||
let llvm_elem = one(ty_to_type(bx.cx, llvm_elem));
|
let llvm_elem = one(ty_to_type(bx.cx, llvm_elem));
|
||||||
vec![bx.bitcast(arg.immediate(), Type::vector(&llvm_elem, length as u64))]
|
vec![bx.bitcast(arg.immediate(), 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 => {
|
||||||
// the LLVM intrinsic uses a smaller integer
|
// the LLVM intrinsic uses a smaller integer
|
||||||
@ -644,7 +647,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
intrinsics::IntrinsicDef::Named(name) => {
|
intrinsics::IntrinsicDef::Named(name) => {
|
||||||
let f = declare::declare_cfn(cx,
|
let f = declare::declare_cfn(cx,
|
||||||
name,
|
name,
|
||||||
Type::func(&inputs, &outputs));
|
Type::func(&inputs, outputs));
|
||||||
bx.call(f, &llargs, None)
|
bx.call(f, &llargs, None)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@ -677,14 +680,15 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
fn copy_intrinsic(
|
||||||
allow_overlap: bool,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
volatile: bool,
|
allow_overlap: bool,
|
||||||
ty: Ty<'tcx>,
|
volatile: bool,
|
||||||
dst: ValueRef,
|
ty: Ty<'tcx>,
|
||||||
src: ValueRef,
|
dst: ValueRef,
|
||||||
count: ValueRef)
|
src: ValueRef,
|
||||||
-> ValueRef {
|
count: ValueRef,
|
||||||
|
) -> ValueRef {
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
let (size, align) = cx.size_and_align_of(ty);
|
let (size, align) = cx.size_and_align_of(ty);
|
||||||
let size = C_usize(cx, size.bytes());
|
let size = C_usize(cx, size.bytes());
|
||||||
@ -712,8 +716,8 @@ fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
None)
|
None)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn memset_intrinsic<'a, 'tcx>(
|
fn memset_intrinsic(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
volatile: bool,
|
volatile: bool,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
dst: ValueRef,
|
dst: ValueRef,
|
||||||
@ -728,8 +732,8 @@ fn memset_intrinsic<'a, 'tcx>(
|
|||||||
call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
|
call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_intrinsic<'a, 'tcx>(
|
fn try_intrinsic(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
cx: &CodegenCx,
|
cx: &CodegenCx,
|
||||||
func: ValueRef,
|
func: ValueRef,
|
||||||
data: ValueRef,
|
data: ValueRef,
|
||||||
@ -754,12 +758,14 @@ fn try_intrinsic<'a, 'tcx>(
|
|||||||
// instructions are meant to work for all targets, as of the time of this
|
// instructions are meant to work for all targets, as of the time of this
|
||||||
// writing, however, LLVM does not recommend the usage of these new instructions
|
// writing, however, LLVM does not recommend the usage of these new instructions
|
||||||
// as the old ones are still more optimized.
|
// as the old ones are still more optimized.
|
||||||
fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
fn codegen_msvc_try(
|
||||||
cx: &CodegenCx,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
func: ValueRef,
|
cx: &CodegenCx,
|
||||||
data: ValueRef,
|
func: ValueRef,
|
||||||
local_ptr: ValueRef,
|
data: ValueRef,
|
||||||
dest: ValueRef) {
|
local_ptr: ValueRef,
|
||||||
|
dest: ValueRef,
|
||||||
|
) {
|
||||||
let llfn = get_rust_try_fn(cx, &mut |bx| {
|
let llfn = get_rust_try_fn(cx, &mut |bx| {
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
|
|
||||||
@ -862,12 +868,14 @@ fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
// function calling it, and that function may already have other personality
|
// function calling it, and that function may already have other personality
|
||||||
// functions in play. By calling a shim we're guaranteed that our shim will have
|
// functions in play. By calling a shim we're guaranteed that our shim will have
|
||||||
// the right personality function.
|
// the right personality function.
|
||||||
fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
fn codegen_gnu_try(
|
||||||
cx: &CodegenCx,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
func: ValueRef,
|
cx: &CodegenCx,
|
||||||
data: ValueRef,
|
func: ValueRef,
|
||||||
local_ptr: ValueRef,
|
data: ValueRef,
|
||||||
dest: ValueRef) {
|
local_ptr: ValueRef,
|
||||||
|
dest: ValueRef,
|
||||||
|
) {
|
||||||
let llfn = get_rust_try_fn(cx, &mut |bx| {
|
let llfn = get_rust_try_fn(cx, &mut |bx| {
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
|
|
||||||
@ -922,12 +930,13 @@ fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
|||||||
|
|
||||||
// Helper function to give a Block to a closure to codegen a shim function.
|
// Helper function to give a Block to a closure to codegen a shim function.
|
||||||
// This is currently primarily used for the `try` intrinsic functions above.
|
// This is currently primarily used for the `try` intrinsic functions above.
|
||||||
fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn gen_fn<'ll, 'tcx>(
|
||||||
name: &str,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
inputs: Vec<Ty<'tcx>>,
|
name: &str,
|
||||||
output: Ty<'tcx>,
|
inputs: Vec<Ty<'tcx>>,
|
||||||
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
|
output: Ty<'tcx>,
|
||||||
-> ValueRef {
|
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
|
||||||
|
) -> ValueRef {
|
||||||
let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig(
|
let rust_fn_ty = cx.tcx.mk_fn_ptr(ty::Binder::bind(cx.tcx.mk_fn_sig(
|
||||||
inputs.into_iter(),
|
inputs.into_iter(),
|
||||||
output,
|
output,
|
||||||
@ -945,9 +954,10 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||||||
// catch exceptions.
|
// catch exceptions.
|
||||||
//
|
//
|
||||||
// This function is only generated once and is then cached.
|
// This function is only generated once and is then cached.
|
||||||
fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn get_rust_try_fn<'ll, 'tcx>(
|
||||||
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
-> ValueRef {
|
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
|
||||||
|
) -> ValueRef {
|
||||||
if let Some(llfn) = cx.rust_try_fn.get() {
|
if let Some(llfn) = cx.rust_try_fn.get() {
|
||||||
return llfn;
|
return llfn;
|
||||||
}
|
}
|
||||||
@ -972,13 +982,13 @@ fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
|
|||||||
span_err!(a, b, E0511, "{}", c);
|
span_err!(a, b, E0511, "{}", c);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn generic_simd_intrinsic<'a, 'tcx>(
|
fn generic_simd_intrinsic(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
name: &str,
|
name: &str,
|
||||||
callee_ty: Ty<'tcx>,
|
callee_ty: Ty<'tcx>,
|
||||||
args: &[OperandRef<'tcx>],
|
args: &[OperandRef<'tcx>],
|
||||||
ret_ty: Ty<'tcx>,
|
ret_ty: Ty<'tcx>,
|
||||||
llret_ty: Type,
|
llret_ty: &'ll Type,
|
||||||
span: Span
|
span: Span
|
||||||
) -> Result<ValueRef, ()> {
|
) -> Result<ValueRef, ()> {
|
||||||
// macros for error handling:
|
// macros for error handling:
|
||||||
@ -1145,19 +1155,20 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
}
|
}
|
||||||
// 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(&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()));
|
||||||
}
|
}
|
||||||
|
|
||||||
fn simd_simple_float_intrinsic<'a, 'tcx>(name: &str,
|
fn simd_simple_float_intrinsic(
|
||||||
in_elem: &::rustc::ty::TyS,
|
name: &str,
|
||||||
in_ty: &::rustc::ty::TyS,
|
in_elem: &::rustc::ty::TyS,
|
||||||
in_len: usize,
|
in_ty: &::rustc::ty::TyS,
|
||||||
bx: &Builder<'a, 'tcx>,
|
in_len: usize,
|
||||||
span: Span,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
args: &[OperandRef<'tcx>])
|
span: Span,
|
||||||
-> Result<ValueRef, ()> {
|
args: &[OperandRef<'tcx>],
|
||||||
|
) -> Result<ValueRef, ()> {
|
||||||
macro_rules! emit_error {
|
macro_rules! emit_error {
|
||||||
($msg: tt) => {
|
($msg: tt) => {
|
||||||
emit_error!($msg, )
|
emit_error!($msg, )
|
||||||
@ -1283,8 +1294,8 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn llvm_vector_ty(cx: &CodegenCx, elem_ty: ty::Ty, vec_len: usize,
|
fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: ty::Ty, vec_len: usize,
|
||||||
mut no_pointers: usize) -> Type {
|
mut no_pointers: usize) -> &'ll Type {
|
||||||
// FIXME: use cx.layout_of(ty).llvm_type() ?
|
// FIXME: use cx.layout_of(ty).llvm_type() ?
|
||||||
let mut elem_ty = match elem_ty.sty {
|
let mut elem_ty = match elem_ty.sty {
|
||||||
ty::TyInt(v) => Type::int_from_ty(cx, v),
|
ty::TyInt(v) => Type::int_from_ty(cx, v),
|
||||||
@ -1296,7 +1307,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
elem_ty = elem_ty.ptr_to();
|
elem_ty = elem_ty.ptr_to();
|
||||||
no_pointers -= 1;
|
no_pointers -= 1;
|
||||||
}
|
}
|
||||||
Type::vector(&elem_ty, vec_len as u64)
|
Type::vector(elem_ty, vec_len as u64)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1379,7 +1390,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
// 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(&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)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1395,7 +1406,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
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(&[llvm_pointer_vec_ty, alignment_ty, mask_ty,
|
Type::func(&[llvm_pointer_vec_ty, alignment_ty, mask_ty,
|
||||||
llvm_elem_vec_ty], &llvm_elem_vec_ty));
|
llvm_elem_vec_ty], llvm_elem_vec_ty));
|
||||||
llvm::SetUnnamedAddr(f, false);
|
llvm::SetUnnamedAddr(f, false);
|
||||||
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()],
|
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()],
|
||||||
None);
|
None);
|
||||||
@ -1476,7 +1487,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
// 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(&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)
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -1496,7 +1507,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
|||||||
Type::func(&[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));
|
||||||
llvm::SetUnnamedAddr(f, false);
|
llvm::SetUnnamedAddr(f, false);
|
||||||
let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask],
|
let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask],
|
||||||
None);
|
None);
|
||||||
@ -1629,7 +1640,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(&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 {
|
||||||
|
@ -377,8 +377,7 @@ pub enum ThreadLocalMode {
|
|||||||
// Opaque pointer types
|
// Opaque pointer types
|
||||||
extern { pub type Module; }
|
extern { pub type Module; }
|
||||||
extern { pub type Context; }
|
extern { pub type Context; }
|
||||||
extern { pub type Type_opaque; }
|
extern { pub type Type; }
|
||||||
pub type TypeRef = *mut Type_opaque;
|
|
||||||
extern { pub type Value_opaque; }
|
extern { pub type Value_opaque; }
|
||||||
pub type ValueRef = *mut Value_opaque;
|
pub type ValueRef = *mut Value_opaque;
|
||||||
extern { pub type Metadata_opaque; }
|
extern { pub type Metadata_opaque; }
|
||||||
@ -517,55 +516,55 @@ extern "C" {
|
|||||||
pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char);
|
pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char);
|
||||||
|
|
||||||
/// See llvm::LLVMTypeKind::getTypeID.
|
/// See llvm::LLVMTypeKind::getTypeID.
|
||||||
pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind;
|
pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
|
||||||
|
|
||||||
// Operations on integer types
|
// Operations on integer types
|
||||||
pub fn LLVMInt1TypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMInt1TypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMInt8TypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMInt8TypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMInt16TypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMInt16TypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMInt32TypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMInt32TypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMInt64TypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMInt64TypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> TypeRef;
|
pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> &Type;
|
||||||
|
|
||||||
pub fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
|
pub fn LLVMGetIntTypeWidth(IntegerTy: &Type) -> c_uint;
|
||||||
|
|
||||||
// Operations on real types
|
// Operations on real types
|
||||||
pub fn LLVMFloatTypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMFloatTypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMDoubleTypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
|
||||||
|
|
||||||
// Operations on function types
|
// Operations on function types
|
||||||
pub fn LLVMFunctionType(ReturnType: TypeRef,
|
pub fn LLVMFunctionType(ReturnType: &'a Type,
|
||||||
ParamTypes: *const TypeRef,
|
ParamTypes: *const &'a Type,
|
||||||
ParamCount: c_uint,
|
ParamCount: c_uint,
|
||||||
IsVarArg: Bool)
|
IsVarArg: Bool)
|
||||||
-> TypeRef;
|
-> &'a Type;
|
||||||
pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
|
pub fn LLVMGetReturnType(FunctionTy: &Type) -> &Type;
|
||||||
pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
|
pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint;
|
||||||
pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef);
|
pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type);
|
||||||
|
|
||||||
// Operations on struct types
|
// Operations on struct types
|
||||||
pub fn LLVMStructTypeInContext(C: &Context,
|
pub fn LLVMStructTypeInContext(C: &'a Context,
|
||||||
ElementTypes: *const TypeRef,
|
ElementTypes: *const &'a Type,
|
||||||
ElementCount: c_uint,
|
ElementCount: c_uint,
|
||||||
Packed: Bool)
|
Packed: Bool)
|
||||||
-> TypeRef;
|
-> &'a Type;
|
||||||
pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
|
pub fn LLVMIsPackedStruct(StructTy: &Type) -> Bool;
|
||||||
|
|
||||||
// Operations on array, pointer, and vector types (sequence types)
|
// Operations on array, pointer, and vector types (sequence types)
|
||||||
pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
|
pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type;
|
||||||
pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint) -> TypeRef;
|
pub fn LLVMPointerType(ElementType: &Type, AddressSpace: c_uint) -> &Type;
|
||||||
pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint) -> TypeRef;
|
pub fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type;
|
||||||
|
|
||||||
pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
|
pub fn LLVMGetElementType(Ty: &Type) -> &Type;
|
||||||
pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
|
pub fn LLVMGetVectorSize(VectorTy: &Type) -> c_uint;
|
||||||
|
|
||||||
// Operations on other types
|
// Operations on other types
|
||||||
pub fn LLVMVoidTypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMVoidTypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMX86MMXTypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMX86MMXTypeInContext(C: &Context) -> &Type;
|
||||||
pub fn LLVMRustMetadataTypeInContext(C: &Context) -> TypeRef;
|
pub fn LLVMRustMetadataTypeInContext(C: &Context) -> &Type;
|
||||||
|
|
||||||
// Operations on all values
|
// Operations on all values
|
||||||
pub fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
|
pub fn LLVMTypeOf(Val: &Value_opaque) -> &Type;
|
||||||
pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
|
pub fn LLVMGetValueName(Val: ValueRef) -> *const c_char;
|
||||||
pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
|
pub fn LLVMSetValueName(Val: ValueRef, Name: *const c_char);
|
||||||
pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
|
pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
|
||||||
@ -580,10 +579,10 @@ extern "C" {
|
|||||||
pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
|
pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
|
||||||
|
|
||||||
// Operations on constants of any type
|
// Operations on constants of any type
|
||||||
pub fn LLVMConstNull(Ty: TypeRef) -> ValueRef;
|
pub fn LLVMConstNull(Ty: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
|
pub fn LLVMConstICmp(Pred: IntPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
|
pub fn LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
|
pub fn LLVMGetUndef(Ty: &Type) -> ValueRef;
|
||||||
|
|
||||||
// Operations on metadata
|
// Operations on metadata
|
||||||
pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef;
|
pub fn LLVMMDStringInContext(C: &Context, Str: *const c_char, SLen: c_uint) -> ValueRef;
|
||||||
@ -591,8 +590,8 @@ extern "C" {
|
|||||||
pub fn LLVMAddNamedMetadataOperand(M: &Module, Name: *const c_char, Val: ValueRef);
|
pub fn LLVMAddNamedMetadataOperand(M: &Module, Name: *const c_char, Val: ValueRef);
|
||||||
|
|
||||||
// Operations on scalar constants
|
// Operations on scalar constants
|
||||||
pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
|
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
|
||||||
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: TypeRef, Wn: c_uint, Ws: *const u64) -> ValueRef;
|
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> ValueRef;
|
||||||
pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
|
pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
|
||||||
pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
|
pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
|
||||||
pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
|
pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
|
||||||
@ -612,14 +611,14 @@ extern "C" {
|
|||||||
Packed: Bool)
|
Packed: Bool)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
|
|
||||||
pub fn LLVMConstArray(ElementTy: TypeRef,
|
pub fn LLVMConstArray(ElementTy: &Type,
|
||||||
ConstantVals: *const ValueRef,
|
ConstantVals: *const ValueRef,
|
||||||
Length: c_uint)
|
Length: c_uint)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef;
|
pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef;
|
||||||
|
|
||||||
// Constant expressions
|
// Constant expressions
|
||||||
pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
|
pub fn LLVMSizeOf(Ty: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
|
pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
|
pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
|
pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
|
||||||
@ -651,23 +650,23 @@ extern "C" {
|
|||||||
ConstantIndices: *const ValueRef,
|
ConstantIndices: *const ValueRef,
|
||||||
NumIndices: c_uint,
|
NumIndices: c_uint,
|
||||||
) -> ValueRef;
|
) -> ValueRef;
|
||||||
pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef, isSigned: Bool) -> ValueRef;
|
pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: &Type, isSigned: Bool) -> ValueRef;
|
||||||
pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||||
pub fn LLVMConstExtractValue(AggConstant: ValueRef,
|
pub fn LLVMConstExtractValue(AggConstant: ValueRef,
|
||||||
IdxList: *const c_uint,
|
IdxList: *const c_uint,
|
||||||
NumIdx: c_uint)
|
NumIdx: c_uint)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMConstInlineAsm(Ty: TypeRef,
|
pub fn LLVMConstInlineAsm(Ty: &Type,
|
||||||
AsmString: *const c_char,
|
AsmString: *const c_char,
|
||||||
Constraints: *const c_char,
|
Constraints: *const c_char,
|
||||||
HasSideEffects: Bool,
|
HasSideEffects: Bool,
|
||||||
@ -690,9 +689,9 @@ extern "C" {
|
|||||||
|
|
||||||
// Operations on global variables
|
// Operations on global variables
|
||||||
pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef;
|
pub fn LLVMIsAGlobalVariable(GlobalVar: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMAddGlobal(M: &Module, Ty: TypeRef, Name: *const c_char) -> ValueRef;
|
pub fn LLVMAddGlobal(M: &Module, Ty: &Type, Name: *const c_char) -> ValueRef;
|
||||||
pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> ValueRef;
|
pub fn LLVMGetNamedGlobal(M: &Module, Name: *const c_char) -> ValueRef;
|
||||||
pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: TypeRef) -> ValueRef;
|
pub fn LLVMRustGetOrInsertGlobal(M: &Module, Name: *const c_char, T: &Type) -> ValueRef;
|
||||||
pub fn LLVMGetFirstGlobal(M: &Module) -> ValueRef;
|
pub fn LLVMGetFirstGlobal(M: &Module) -> ValueRef;
|
||||||
pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
|
pub fn LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
|
pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
|
||||||
@ -706,13 +705,13 @@ extern "C" {
|
|||||||
pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
|
pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
|
||||||
|
|
||||||
// Operations on functions
|
// Operations on functions
|
||||||
pub fn LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: TypeRef) -> ValueRef;
|
pub fn LLVMAddFunction(M: &Module, Name: *const c_char, FunctionTy: &Type) -> ValueRef;
|
||||||
pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> ValueRef;
|
pub fn LLVMGetNamedFunction(M: &Module, Name: *const c_char) -> ValueRef;
|
||||||
pub fn LLVMGetFirstFunction(M: &Module) -> ValueRef;
|
pub fn LLVMGetFirstFunction(M: &Module) -> ValueRef;
|
||||||
pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
|
pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMRustGetOrInsertFunction(M: &Module,
|
pub fn LLVMRustGetOrInsertFunction(M: &Module,
|
||||||
Name: *const c_char,
|
Name: *const c_char,
|
||||||
FunctionTy: TypeRef)
|
FunctionTy: &Type)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
|
pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
|
||||||
pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32);
|
pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32);
|
||||||
@ -801,7 +800,7 @@ extern "C" {
|
|||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildLandingPad(B: BuilderRef,
|
pub fn LLVMBuildLandingPad(B: BuilderRef,
|
||||||
Ty: TypeRef,
|
Ty: &Type,
|
||||||
PersFn: ValueRef,
|
PersFn: ValueRef,
|
||||||
NumClauses: c_uint,
|
NumClauses: c_uint,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
@ -989,7 +988,7 @@ extern "C" {
|
|||||||
pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
|
pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
|
||||||
|
|
||||||
// Memory
|
// Memory
|
||||||
pub fn LLVMBuildAlloca(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef;
|
pub fn LLVMBuildAlloca(B: BuilderRef, Ty: &Type, Name: *const c_char) -> ValueRef;
|
||||||
pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
|
pub fn LLVMBuildFree(B: BuilderRef, PointerVal: ValueRef) -> ValueRef;
|
||||||
pub fn LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *const c_char) -> ValueRef;
|
pub fn LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *const c_char) -> ValueRef;
|
||||||
|
|
||||||
@ -1024,98 +1023,98 @@ extern "C" {
|
|||||||
// Casts
|
// Casts
|
||||||
pub fn LLVMBuildTrunc(B: BuilderRef,
|
pub fn LLVMBuildTrunc(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildZExt(B: BuilderRef,
|
pub fn LLVMBuildZExt(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildSExt(B: BuilderRef,
|
pub fn LLVMBuildSExt(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildFPToUI(B: BuilderRef,
|
pub fn LLVMBuildFPToUI(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildFPToSI(B: BuilderRef,
|
pub fn LLVMBuildFPToSI(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildUIToFP(B: BuilderRef,
|
pub fn LLVMBuildUIToFP(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildSIToFP(B: BuilderRef,
|
pub fn LLVMBuildSIToFP(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildFPTrunc(B: BuilderRef,
|
pub fn LLVMBuildFPTrunc(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildFPExt(B: BuilderRef,
|
pub fn LLVMBuildFPExt(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildPtrToInt(B: BuilderRef,
|
pub fn LLVMBuildPtrToInt(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildIntToPtr(B: BuilderRef,
|
pub fn LLVMBuildIntToPtr(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildBitCast(B: BuilderRef,
|
pub fn LLVMBuildBitCast(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
|
pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
|
pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
|
pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildCast(B: BuilderRef,
|
pub fn LLVMBuildCast(B: BuilderRef,
|
||||||
Op: Opcode,
|
Op: Opcode,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildPointerCast(B: BuilderRef,
|
pub fn LLVMBuildPointerCast(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMRustBuildIntCast(B: BuilderRef,
|
pub fn LLVMRustBuildIntCast(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
IsSized: bool)
|
IsSized: bool)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildFPCast(B: BuilderRef,
|
pub fn LLVMBuildFPCast(B: BuilderRef,
|
||||||
Val: ValueRef,
|
Val: ValueRef,
|
||||||
DestTy: TypeRef,
|
DestTy: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
|
|
||||||
@ -1134,7 +1133,7 @@ extern "C" {
|
|||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
|
|
||||||
// Miscellaneous instructions
|
// Miscellaneous instructions
|
||||||
pub fn LLVMBuildPhi(B: BuilderRef, Ty: TypeRef, Name: *const c_char) -> ValueRef;
|
pub fn LLVMBuildPhi(B: BuilderRef, Ty: &Type, Name: *const c_char) -> ValueRef;
|
||||||
pub fn LLVMRustBuildCall(B: BuilderRef,
|
pub fn LLVMRustBuildCall(B: BuilderRef,
|
||||||
Fn: ValueRef,
|
Fn: ValueRef,
|
||||||
Args: *const ValueRef,
|
Args: *const ValueRef,
|
||||||
@ -1150,7 +1149,7 @@ extern "C" {
|
|||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildVAArg(B: BuilderRef,
|
pub fn LLVMBuildVAArg(B: BuilderRef,
|
||||||
list: ValueRef,
|
list: ValueRef,
|
||||||
Ty: TypeRef,
|
Ty: &Type,
|
||||||
Name: *const c_char)
|
Name: *const c_char)
|
||||||
-> ValueRef;
|
-> ValueRef;
|
||||||
pub fn LLVMBuildExtractElement(B: BuilderRef,
|
pub fn LLVMBuildExtractElement(B: BuilderRef,
|
||||||
@ -1347,15 +1346,15 @@ extern "C" {
|
|||||||
/// Print the pass timings since static dtors aren't picking them up.
|
/// Print the pass timings since static dtors aren't picking them up.
|
||||||
pub fn LLVMRustPrintPassTimings();
|
pub fn LLVMRustPrintPassTimings();
|
||||||
|
|
||||||
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> TypeRef;
|
pub fn LLVMStructCreateNamed(C: &Context, Name: *const c_char) -> &Type;
|
||||||
|
|
||||||
pub fn LLVMStructSetBody(StructTy: TypeRef,
|
pub fn LLVMStructSetBody(StructTy: &'a Type,
|
||||||
ElementTypes: *const TypeRef,
|
ElementTypes: *const &'a Type,
|
||||||
ElementCount: c_uint,
|
ElementCount: c_uint,
|
||||||
Packed: Bool);
|
Packed: Bool);
|
||||||
|
|
||||||
/// Prepares inline assembly.
|
/// Prepares inline assembly.
|
||||||
pub fn LLVMRustInlineAsm(Ty: TypeRef,
|
pub fn LLVMRustInlineAsm(Ty: &Type,
|
||||||
AsmString: *const c_char,
|
AsmString: *const c_char,
|
||||||
Constraints: *const c_char,
|
Constraints: *const c_char,
|
||||||
SideEffects: Bool,
|
SideEffects: Bool,
|
||||||
@ -1587,7 +1586,7 @@ extern "C" {
|
|||||||
pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
|
pub fn LLVMRustDIBuilderCreateOpDeref() -> i64;
|
||||||
pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64;
|
pub fn LLVMRustDIBuilderCreateOpPlusUconst() -> i64;
|
||||||
|
|
||||||
pub fn LLVMRustWriteTypeToString(Type: TypeRef, s: RustStringRef);
|
pub fn LLVMRustWriteTypeToString(Type: &Type, s: RustStringRef);
|
||||||
pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef);
|
pub fn LLVMRustWriteValueToString(value_ref: ValueRef, s: RustStringRef);
|
||||||
|
|
||||||
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
|
pub fn LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
|
||||||
|
@ -33,7 +33,7 @@ impl<'a, 'tcx> VirtualIndex {
|
|||||||
VirtualIndex(index as u64 + 3)
|
VirtualIndex(index as u64 + 3)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_fn(self, bx: &Builder<'a, 'tcx>,
|
pub fn get_fn(self, bx: &Builder<'a, 'll, 'tcx>,
|
||||||
llvtable: ValueRef,
|
llvtable: ValueRef,
|
||||||
fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef {
|
fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef {
|
||||||
// Load the data pointer from the object.
|
// Load the data pointer from the object.
|
||||||
@ -48,7 +48,7 @@ impl<'a, 'tcx> VirtualIndex {
|
|||||||
ptr
|
ptr
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_usize(self, bx: &Builder<'a, 'tcx>, llvtable: ValueRef) -> ValueRef {
|
pub fn get_usize(self, bx: &Builder<'a, 'll, 'tcx>, llvtable: ValueRef) -> ValueRef {
|
||||||
// Load the data pointer from the object.
|
// Load the data pointer from the object.
|
||||||
debug!("get_int({:?}, {:?})", Value(llvtable), self);
|
debug!("get_int({:?}, {:?})", Value(llvtable), self);
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ use rustc::ty::layout::LayoutOf;
|
|||||||
use type_of::LayoutLlvmExt;
|
use type_of::LayoutLlvmExt;
|
||||||
use super::FunctionCx;
|
use super::FunctionCx;
|
||||||
|
|
||||||
pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector<mir::Local> {
|
pub fn non_ssa_locals(fx: &FunctionCx<'a, 'll, 'tcx>) -> BitVector<mir::Local> {
|
||||||
let mir = fx.mir;
|
let mir = fx.mir;
|
||||||
let mut analyzer = LocalAnalyzer::new(fx);
|
let mut analyzer = LocalAnalyzer::new(fx);
|
||||||
|
|
||||||
@ -51,8 +51,8 @@ pub fn non_ssa_locals<'a, 'tcx>(fx: &FunctionCx<'a, 'tcx>) -> BitVector<mir::Loc
|
|||||||
analyzer.non_ssa_locals
|
analyzer.non_ssa_locals
|
||||||
}
|
}
|
||||||
|
|
||||||
struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
|
struct LocalAnalyzer<'mir, 'a: 'mir, 'll: 'a, 'tcx: 'll> {
|
||||||
fx: &'mir FunctionCx<'a, 'tcx>,
|
fx: &'mir FunctionCx<'a, 'll, 'tcx>,
|
||||||
dominators: Dominators<mir::BasicBlock>,
|
dominators: Dominators<mir::BasicBlock>,
|
||||||
non_ssa_locals: BitVector<mir::Local>,
|
non_ssa_locals: BitVector<mir::Local>,
|
||||||
// The location of the first visited direct assignment to each
|
// The location of the first visited direct assignment to each
|
||||||
@ -60,8 +60,8 @@ struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
|
|||||||
first_assignment: IndexVec<mir::Local, Location>
|
first_assignment: IndexVec<mir::Local, Location>
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
|
impl LocalAnalyzer<'mir, 'a, 'll, 'tcx> {
|
||||||
fn new(fx: &'mir FunctionCx<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> {
|
fn new(fx: &'mir FunctionCx<'a, 'll, 'tcx>) -> Self {
|
||||||
let invalid_location =
|
let invalid_location =
|
||||||
mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location();
|
mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location();
|
||||||
let mut analyzer = LocalAnalyzer {
|
let mut analyzer = LocalAnalyzer {
|
||||||
@ -102,7 +102,7 @@ impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'mir, 'a, 'tcx> Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'tcx> {
|
impl Visitor<'tcx> for LocalAnalyzer<'mir, 'a, 'll, 'tcx> {
|
||||||
fn visit_assign(&mut self,
|
fn visit_assign(&mut self,
|
||||||
block: mir::BasicBlock,
|
block: mir::BasicBlock,
|
||||||
place: &mir::Place<'tcx>,
|
place: &mir::Place<'tcx>,
|
||||||
|
@ -33,7 +33,7 @@ use super::place::PlaceRef;
|
|||||||
use super::operand::OperandRef;
|
use super::operand::OperandRef;
|
||||||
use super::operand::OperandValue::{Pair, Ref, Immediate};
|
use super::operand::OperandValue::{Pair, Ref, Immediate};
|
||||||
|
|
||||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
pub fn codegen_block(&mut self, bb: mir::BasicBlock) {
|
pub fn codegen_block(&mut self, bb: mir::BasicBlock) {
|
||||||
let mut bx = self.build_block(bb);
|
let mut bx = self.build_block(bb);
|
||||||
let data = &self.mir[bb];
|
let data = &self.mir[bb];
|
||||||
@ -48,7 +48,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_terminator(&mut self,
|
fn codegen_terminator(&mut self,
|
||||||
mut bx: Builder<'a, 'tcx>,
|
mut bx: Builder<'a, 'll, 'tcx>,
|
||||||
bb: mir::BasicBlock,
|
bb: mir::BasicBlock,
|
||||||
terminator: &mir::Terminator<'tcx>)
|
terminator: &mir::Terminator<'tcx>)
|
||||||
{
|
{
|
||||||
@ -110,7 +110,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
|
|
||||||
let do_call = |
|
let do_call = |
|
||||||
this: &mut Self,
|
this: &mut Self,
|
||||||
bx: Builder<'a, 'tcx>,
|
bx: Builder<'a, 'll, 'tcx>,
|
||||||
fn_ty: FnType<'tcx, Ty<'tcx>>,
|
fn_ty: FnType<'tcx, Ty<'tcx>>,
|
||||||
fn_ptr: ValueRef,
|
fn_ptr: ValueRef,
|
||||||
llargs: &[ValueRef],
|
llargs: &[ValueRef],
|
||||||
@ -627,7 +627,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_argument(&mut self,
|
fn codegen_argument(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
op: OperandRef<'tcx>,
|
op: OperandRef<'tcx>,
|
||||||
llargs: &mut Vec<ValueRef>,
|
llargs: &mut Vec<ValueRef>,
|
||||||
arg: &ArgType<'tcx, Ty<'tcx>>) {
|
arg: &ArgType<'tcx, Ty<'tcx>>) {
|
||||||
@ -706,7 +706,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_arguments_untupled(&mut self,
|
fn codegen_arguments_untupled(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
operand: &mir::Operand<'tcx>,
|
operand: &mir::Operand<'tcx>,
|
||||||
llargs: &mut Vec<ValueRef>,
|
llargs: &mut Vec<ValueRef>,
|
||||||
args: &[ArgType<'tcx, Ty<'tcx>>]) {
|
args: &[ArgType<'tcx, Ty<'tcx>>]) {
|
||||||
@ -728,7 +728,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_personality_slot(&mut self, bx: &Builder<'a, 'tcx>) -> PlaceRef<'tcx> {
|
fn get_personality_slot(&mut self, bx: &Builder<'a, 'll, 'tcx>) -> PlaceRef<'tcx> {
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
if let Some(slot) = self.personality_slot {
|
if let Some(slot) = self.personality_slot {
|
||||||
slot
|
slot
|
||||||
@ -777,7 +777,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
bx.llbb()
|
bx.llbb()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn landing_pad_type(&self) -> Type {
|
fn landing_pad_type(&self) -> &'ll Type {
|
||||||
let cx = self.cx;
|
let cx = self.cx;
|
||||||
Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false)
|
Type::struct_(cx, &[Type::i8p(cx), Type::i32(cx)], false)
|
||||||
}
|
}
|
||||||
@ -791,17 +791,17 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_block(&self, name: &str) -> Builder<'a, 'tcx> {
|
pub fn new_block(&self, name: &str) -> Builder<'a, 'll, 'tcx> {
|
||||||
Builder::new_block(self.cx, self.llfn, name)
|
Builder::new_block(self.cx, self.llfn, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'tcx> {
|
pub fn build_block(&self, bb: mir::BasicBlock) -> Builder<'a, 'll, 'tcx> {
|
||||||
let bx = Builder::with_cx(self.cx);
|
let bx = Builder::with_cx(self.cx);
|
||||||
bx.position_at_end(self.blocks[bb]);
|
bx.position_at_end(self.blocks[bb]);
|
||||||
bx
|
bx
|
||||||
}
|
}
|
||||||
|
|
||||||
fn make_return_dest(&mut self, bx: &Builder<'a, 'tcx>,
|
fn make_return_dest(&mut self, bx: &Builder<'a, 'll, 'tcx>,
|
||||||
dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>,
|
dest: &mir::Place<'tcx>, fn_ret: &ArgType<'tcx, Ty<'tcx>>,
|
||||||
llargs: &mut Vec<ValueRef>, is_intrinsic: bool)
|
llargs: &mut Vec<ValueRef>, is_intrinsic: bool)
|
||||||
-> ReturnDest<'tcx> {
|
-> ReturnDest<'tcx> {
|
||||||
@ -857,7 +857,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_transmute(&mut self, bx: &Builder<'a, 'tcx>,
|
fn codegen_transmute(&mut self, bx: &Builder<'a, 'll, 'tcx>,
|
||||||
src: &mir::Operand<'tcx>,
|
src: &mir::Operand<'tcx>,
|
||||||
dst: &mir::Place<'tcx>) {
|
dst: &mir::Place<'tcx>) {
|
||||||
if let mir::Place::Local(index) = *dst {
|
if let mir::Place::Local(index) = *dst {
|
||||||
@ -884,7 +884,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'tcx>,
|
fn codegen_transmute_into(&mut self, bx: &Builder<'a, 'll, 'tcx>,
|
||||||
src: &mir::Operand<'tcx>,
|
src: &mir::Operand<'tcx>,
|
||||||
dst: PlaceRef<'tcx>) {
|
dst: PlaceRef<'tcx>) {
|
||||||
let src = self.codegen_operand(bx, src);
|
let src = self.codegen_operand(bx, src);
|
||||||
@ -897,7 +897,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
|
|
||||||
// Stores the return value of a function call into it's final location.
|
// Stores the return value of a function call into it's final location.
|
||||||
fn store_return(&mut self,
|
fn store_return(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
dest: ReturnDest<'tcx>,
|
dest: ReturnDest<'tcx>,
|
||||||
ret_ty: &ArgType<'tcx, Ty<'tcx>>,
|
ret_ty: &ArgType<'tcx, Ty<'tcx>>,
|
||||||
llval: ValueRef) {
|
llval: ValueRef) {
|
||||||
|
@ -33,7 +33,7 @@ use super::FunctionCx;
|
|||||||
pub fn scalar_to_llvm(cx: &CodegenCx,
|
pub fn scalar_to_llvm(cx: &CodegenCx,
|
||||||
cv: Scalar,
|
cv: Scalar,
|
||||||
layout: &layout::Scalar,
|
layout: &layout::Scalar,
|
||||||
llty: Type) -> ValueRef {
|
llty: &Type) -> ValueRef {
|
||||||
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() };
|
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() };
|
||||||
match cv {
|
match cv {
|
||||||
Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => {
|
Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => {
|
||||||
@ -42,7 +42,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
|
|||||||
Scalar::Bits { bits, .. } => {
|
Scalar::Bits { bits, .. } => {
|
||||||
let llval = C_uint_big(Type::ix(cx, bitsize), bits);
|
let llval = C_uint_big(Type::ix(cx, bitsize), bits);
|
||||||
if layout.value == layout::Pointer {
|
if layout.value == layout::Pointer {
|
||||||
unsafe { llvm::LLVMConstIntToPtr(llval, llty.to_ref()) }
|
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
|
||||||
} else {
|
} else {
|
||||||
consts::bitcast(llval, llty)
|
consts::bitcast(llval, llty)
|
||||||
}
|
}
|
||||||
@ -73,7 +73,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
|
|||||||
1,
|
1,
|
||||||
) };
|
) };
|
||||||
if layout.value != layout::Pointer {
|
if layout.value != layout::Pointer {
|
||||||
unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) }
|
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
|
||||||
} else {
|
} else {
|
||||||
consts::bitcast(llval, llty)
|
consts::bitcast(llval, llty)
|
||||||
}
|
}
|
||||||
@ -135,10 +135,10 @@ pub fn codegen_static_initializer<'a, 'tcx>(
|
|||||||
Ok((const_alloc_to_llvm(cx, alloc), alloc))
|
Ok((const_alloc_to_llvm(cx, alloc), alloc))
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
fn fully_evaluate(
|
fn fully_evaluate(
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
constant: &'tcx ty::Const<'tcx>,
|
constant: &'tcx ty::Const<'tcx>,
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||||
match constant.val {
|
match constant.val {
|
||||||
@ -158,7 +158,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
|
|
||||||
pub fn eval_mir_constant(
|
pub fn eval_mir_constant(
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
constant: &mir::Constant<'tcx>,
|
constant: &mir::Constant<'tcx>,
|
||||||
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||||
let c = self.monomorphize(&constant.literal);
|
let c = self.monomorphize(&constant.literal);
|
||||||
@ -168,7 +168,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
/// process constant containing SIMD shuffle indices
|
/// process constant containing SIMD shuffle indices
|
||||||
pub fn simd_shuffle_indices(
|
pub fn simd_shuffle_indices(
|
||||||
&mut self,
|
&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
span: Span,
|
span: Span,
|
||||||
ty: Ty<'tcx>,
|
ty: Ty<'tcx>,
|
||||||
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,
|
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,
|
||||||
|
@ -43,7 +43,7 @@ use rustc::mir::traversal;
|
|||||||
use self::operand::{OperandRef, OperandValue};
|
use self::operand::{OperandRef, OperandValue};
|
||||||
|
|
||||||
/// Master context for codegenning from MIR.
|
/// Master context for codegenning from MIR.
|
||||||
pub struct FunctionCx<'a, 'tcx:'a> {
|
pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
|
|
||||||
mir: &'a mir::Mir<'tcx>,
|
mir: &'a mir::Mir<'tcx>,
|
||||||
@ -52,7 +52,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
|
|||||||
|
|
||||||
llfn: ValueRef,
|
llfn: ValueRef,
|
||||||
|
|
||||||
cx: &'a CodegenCx<'a, 'tcx>,
|
cx: &'a CodegenCx<'ll, 'tcx>,
|
||||||
|
|
||||||
fn_ty: FnType<'tcx, Ty<'tcx>>,
|
fn_ty: FnType<'tcx, Ty<'tcx>>,
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
|
|||||||
param_substs: &'tcx Substs<'tcx>,
|
param_substs: &'tcx Substs<'tcx>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
pub fn monomorphize<T>(&self, value: &T) -> T
|
pub fn monomorphize<T>(&self, value: &T) -> T
|
||||||
where T: TypeFoldable<'tcx>
|
where T: TypeFoldable<'tcx>
|
||||||
{
|
{
|
||||||
@ -198,8 +198,8 @@ impl<'a, 'tcx> LocalRef<'tcx> {
|
|||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////
|
///////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
pub fn codegen_mir<'a, 'tcx: 'a>(
|
pub fn codegen_mir(
|
||||||
cx: &'a CodegenCx<'a, 'tcx>,
|
cx: &'a CodegenCx<'ll, 'tcx>,
|
||||||
llfn: ValueRef,
|
llfn: ValueRef,
|
||||||
mir: &'a Mir<'tcx>,
|
mir: &'a Mir<'tcx>,
|
||||||
instance: Instance<'tcx>,
|
instance: Instance<'tcx>,
|
||||||
@ -344,9 +344,9 @@ pub fn codegen_mir<'a, 'tcx: 'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_funclets<'a, 'tcx>(
|
fn create_funclets(
|
||||||
mir: &'a Mir<'tcx>,
|
mir: &'a Mir<'tcx>,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>,
|
cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>,
|
||||||
block_bxs: &IndexVec<mir::BasicBlock, BasicBlockRef>)
|
block_bxs: &IndexVec<mir::BasicBlock, BasicBlockRef>)
|
||||||
-> (IndexVec<mir::BasicBlock, Option<BasicBlockRef>>,
|
-> (IndexVec<mir::BasicBlock, Option<BasicBlockRef>>,
|
||||||
@ -413,11 +413,12 @@ fn create_funclets<'a, 'tcx>(
|
|||||||
/// Produce, for each argument, a `ValueRef` pointing at the
|
/// Produce, for each argument, a `ValueRef` pointing at the
|
||||||
/// argument's value. As arguments are places, these are always
|
/// argument's value. As arguments are places, these are always
|
||||||
/// indirect.
|
/// indirect.
|
||||||
fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
fn arg_local_refs(
|
||||||
fx: &FunctionCx<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
|
fx: &FunctionCx<'a, 'll, 'tcx>,
|
||||||
memory_locals: &BitVector<mir::Local>)
|
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
|
||||||
-> Vec<LocalRef<'tcx>> {
|
memory_locals: &BitVector<mir::Local>,
|
||||||
|
) -> Vec<LocalRef<'tcx>> {
|
||||||
let mir = fx.mir;
|
let mir = fx.mir;
|
||||||
let tcx = bx.tcx();
|
let tcx = bx.tcx();
|
||||||
let mut idx = 0;
|
let mut idx = 0;
|
||||||
|
@ -92,7 +92,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_const(bx: &Builder<'a, 'tcx>,
|
pub fn from_const(bx: &Builder<'a, 'll, 'tcx>,
|
||||||
val: &'tcx ty::Const<'tcx>)
|
val: &'tcx ty::Const<'tcx>)
|
||||||
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||||
let layout = bx.cx.layout_of(val.ty);
|
let layout = bx.cx.layout_of(val.ty);
|
||||||
@ -174,7 +174,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
|||||||
|
|
||||||
/// If this operand is a `Pair`, we return an aggregate with the two values.
|
/// If this operand is a `Pair`, we return an aggregate with the two values.
|
||||||
/// For other cases, see `immediate`.
|
/// For other cases, see `immediate`.
|
||||||
pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'tcx>) -> ValueRef {
|
pub fn immediate_or_packed_pair(self, bx: &Builder<'a, 'll, 'tcx>) -> ValueRef {
|
||||||
if let OperandValue::Pair(a, b) = self.val {
|
if let OperandValue::Pair(a, b) = self.val {
|
||||||
let llty = self.layout.llvm_type(bx.cx);
|
let llty = self.layout.llvm_type(bx.cx);
|
||||||
debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}",
|
debug!("Operand::immediate_or_packed_pair: packing {:?} into {:?}",
|
||||||
@ -190,7 +190,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// If the type is a pair, we return a `Pair`, otherwise, an `Immediate`.
|
/// If the type is a pair, we return a `Pair`, otherwise, an `Immediate`.
|
||||||
pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'tcx>,
|
pub fn from_immediate_or_packed_pair(bx: &Builder<'a, 'll, 'tcx>,
|
||||||
llval: ValueRef,
|
llval: ValueRef,
|
||||||
layout: TyLayout<'tcx>)
|
layout: TyLayout<'tcx>)
|
||||||
-> OperandRef<'tcx> {
|
-> OperandRef<'tcx> {
|
||||||
@ -208,7 +208,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
|||||||
OperandRef { val, layout }
|
OperandRef { val, layout }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn extract_field(&self, bx: &Builder<'a, 'tcx>, i: usize) -> OperandRef<'tcx> {
|
pub fn extract_field(&self, bx: &Builder<'a, 'll, 'tcx>, i: usize) -> OperandRef<'tcx> {
|
||||||
let field = self.layout.field(bx.cx, i);
|
let field = self.layout.field(bx.cx, i);
|
||||||
let offset = self.layout.fields.offset(i);
|
let offset = self.layout.fields.offset(i);
|
||||||
|
|
||||||
@ -267,23 +267,23 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> OperandValue {
|
impl<'a, 'tcx> OperandValue {
|
||||||
pub fn store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
pub fn store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
|
||||||
self.store_with_flags(bx, dest, MemFlags::empty());
|
self.store_with_flags(bx, dest, MemFlags::empty());
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
pub fn volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
|
||||||
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
|
self.store_with_flags(bx, dest, MemFlags::VOLATILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
pub fn unaligned_volatile_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
|
||||||
self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
|
self.store_with_flags(bx, dest, MemFlags::VOLATILE | MemFlags::UNALIGNED);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn nontemporal_store(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>) {
|
pub fn nontemporal_store(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>) {
|
||||||
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
|
self.store_with_flags(bx, dest, MemFlags::NONTEMPORAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn store_with_flags(self, bx: &Builder<'a, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) {
|
fn store_with_flags(self, bx: &Builder<'a, 'll, 'tcx>, dest: PlaceRef<'tcx>, flags: MemFlags) {
|
||||||
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
|
debug!("OperandRef::store: operand={:?}, dest={:?}", self, dest);
|
||||||
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized
|
// Avoid generating stores of zero-sized values, because the only way to have a zero-sized
|
||||||
// value is through `undef`, and store itself is useless.
|
// value is through `undef`, and store itself is useless.
|
||||||
@ -310,9 +310,9 @@ impl<'a, 'tcx> OperandValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
fn maybe_codegen_consume_direct(&mut self,
|
fn maybe_codegen_consume_direct(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
place: &mir::Place<'tcx>)
|
place: &mir::Place<'tcx>)
|
||||||
-> Option<OperandRef<'tcx>>
|
-> Option<OperandRef<'tcx>>
|
||||||
{
|
{
|
||||||
@ -360,7 +360,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_consume(&mut self,
|
pub fn codegen_consume(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
place: &mir::Place<'tcx>)
|
place: &mir::Place<'tcx>)
|
||||||
-> OperandRef<'tcx>
|
-> OperandRef<'tcx>
|
||||||
{
|
{
|
||||||
@ -384,7 +384,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_operand(&mut self,
|
pub fn codegen_operand(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
operand: &mir::Operand<'tcx>)
|
operand: &mir::Operand<'tcx>)
|
||||||
-> OperandRef<'tcx>
|
-> OperandRef<'tcx>
|
||||||
{
|
{
|
||||||
|
@ -56,7 +56,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_const_alloc(
|
pub fn from_const_alloc(
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
layout: TyLayout<'tcx>,
|
layout: TyLayout<'tcx>,
|
||||||
alloc: &mir::interpret::Allocation,
|
alloc: &mir::interpret::Allocation,
|
||||||
offset: Size,
|
offset: Size,
|
||||||
@ -73,7 +73,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
PlaceRef::new_sized(llval, layout, alloc.align)
|
PlaceRef::new_sized(llval, layout, alloc.align)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn alloca(bx: &Builder<'a, 'tcx>, layout: TyLayout<'tcx>, name: &str)
|
pub fn alloca(bx: &Builder<'a, 'll, 'tcx>, layout: TyLayout<'tcx>, name: &str)
|
||||||
-> PlaceRef<'tcx> {
|
-> PlaceRef<'tcx> {
|
||||||
debug!("alloca({:?}: {:?})", name, layout);
|
debug!("alloca({:?}: {:?})", name, layout);
|
||||||
let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align);
|
let tmp = bx.alloca(layout.llvm_type(bx.cx), name, layout.align);
|
||||||
@ -98,7 +98,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
!self.llextra.is_null()
|
!self.llextra.is_null()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn load(&self, bx: &Builder<'a, 'tcx>) -> OperandRef<'tcx> {
|
pub fn load(&self, bx: &Builder<'a, 'll, 'tcx>) -> OperandRef<'tcx> {
|
||||||
debug!("PlaceRef::load: {:?}", self);
|
debug!("PlaceRef::load: {:?}", self);
|
||||||
|
|
||||||
assert!(!self.has_extra());
|
assert!(!self.has_extra());
|
||||||
@ -162,7 +162,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Access a field, at a point when the value's case is known.
|
/// Access a field, at a point when the value's case is known.
|
||||||
pub fn project_field(self, bx: &Builder<'a, 'tcx>, ix: usize) -> PlaceRef<'tcx> {
|
pub fn project_field(self, bx: &Builder<'a, 'll, 'tcx>, ix: usize) -> PlaceRef<'tcx> {
|
||||||
let cx = bx.cx;
|
let cx = bx.cx;
|
||||||
let field = self.layout.field(cx, ix);
|
let field = self.layout.field(cx, ix);
|
||||||
let offset = self.layout.fields.offset(ix);
|
let offset = self.layout.fields.offset(ix);
|
||||||
@ -266,7 +266,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Obtain the actual discriminant of a value.
|
/// Obtain the actual discriminant of a value.
|
||||||
pub fn codegen_get_discr(self, bx: &Builder<'a, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
|
pub fn codegen_get_discr(self, bx: &Builder<'a, 'll, 'tcx>, cast_to: Ty<'tcx>) -> ValueRef {
|
||||||
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);
|
||||||
if self.layout.abi == layout::Abi::Uninhabited {
|
if self.layout.abi == layout::Abi::Uninhabited {
|
||||||
return C_undef(cast_to);
|
return C_undef(cast_to);
|
||||||
@ -330,7 +330,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
|
|
||||||
/// Set the discriminant for a new value of the given case of the given
|
/// Set the discriminant for a new value of the given case of the given
|
||||||
/// representation.
|
/// representation.
|
||||||
pub fn codegen_set_discr(&self, bx: &Builder<'a, 'tcx>, variant_index: usize) {
|
pub fn codegen_set_discr(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize) {
|
||||||
if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited {
|
if self.layout.for_variant(bx.cx, variant_index).abi == layout::Abi::Uninhabited {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -384,7 +384,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn project_index(&self, bx: &Builder<'a, 'tcx>, llindex: ValueRef)
|
pub fn project_index(&self, bx: &Builder<'a, 'll, 'tcx>, llindex: ValueRef)
|
||||||
-> PlaceRef<'tcx> {
|
-> PlaceRef<'tcx> {
|
||||||
PlaceRef {
|
PlaceRef {
|
||||||
llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]),
|
llval: bx.inbounds_gep(self.llval, &[C_usize(bx.cx, 0), llindex]),
|
||||||
@ -394,7 +394,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn project_downcast(&self, bx: &Builder<'a, 'tcx>, variant_index: usize)
|
pub fn project_downcast(&self, bx: &Builder<'a, 'll, 'tcx>, variant_index: usize)
|
||||||
-> PlaceRef<'tcx> {
|
-> PlaceRef<'tcx> {
|
||||||
let mut downcast = *self;
|
let mut downcast = *self;
|
||||||
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
|
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
|
||||||
@ -406,18 +406,18 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
|||||||
downcast
|
downcast
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn storage_live(&self, bx: &Builder<'a, 'tcx>) {
|
pub fn storage_live(&self, bx: &Builder<'a, 'll, 'tcx>) {
|
||||||
bx.lifetime_start(self.llval, self.layout.size);
|
bx.lifetime_start(self.llval, self.layout.size);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn storage_dead(&self, bx: &Builder<'a, 'tcx>) {
|
pub fn storage_dead(&self, bx: &Builder<'a, 'll, 'tcx>) {
|
||||||
bx.lifetime_end(self.llval, self.layout.size);
|
bx.lifetime_end(self.llval, self.layout.size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
pub fn codegen_place(&mut self,
|
pub fn codegen_place(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
place: &mir::Place<'tcx>)
|
place: &mir::Place<'tcx>)
|
||||||
-> PlaceRef<'tcx> {
|
-> PlaceRef<'tcx> {
|
||||||
debug!("codegen_place(place={:?})", place);
|
debug!("codegen_place(place={:?})", place);
|
||||||
|
@ -32,12 +32,12 @@ use super::{FunctionCx, LocalRef};
|
|||||||
use super::operand::{OperandRef, OperandValue};
|
use super::operand::{OperandRef, OperandValue};
|
||||||
use super::place::PlaceRef;
|
use super::place::PlaceRef;
|
||||||
|
|
||||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
pub fn codegen_rvalue(&mut self,
|
pub fn codegen_rvalue(&mut self,
|
||||||
bx: Builder<'a, 'tcx>,
|
bx: Builder<'a, 'll, 'tcx>,
|
||||||
dest: PlaceRef<'tcx>,
|
dest: PlaceRef<'tcx>,
|
||||||
rvalue: &mir::Rvalue<'tcx>)
|
rvalue: &mir::Rvalue<'tcx>)
|
||||||
-> Builder<'a, 'tcx>
|
-> Builder<'a, 'll, 'tcx>
|
||||||
{
|
{
|
||||||
debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})",
|
debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})",
|
||||||
Value(dest.llval), rvalue);
|
Value(dest.llval), rvalue);
|
||||||
@ -176,9 +176,9 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_rvalue_operand(&mut self,
|
pub fn codegen_rvalue_operand(&mut self,
|
||||||
bx: Builder<'a, 'tcx>,
|
bx: Builder<'a, 'll, 'tcx>,
|
||||||
rvalue: &mir::Rvalue<'tcx>)
|
rvalue: &mir::Rvalue<'tcx>)
|
||||||
-> (Builder<'a, 'tcx>, OperandRef<'tcx>)
|
-> (Builder<'a, 'll, 'tcx>, OperandRef<'tcx>)
|
||||||
{
|
{
|
||||||
assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue);
|
assert!(self.rvalue_creates_operand(rvalue), "cannot codegen {:?} to operand", rvalue);
|
||||||
|
|
||||||
@ -512,7 +512,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn evaluate_array_len(&mut self,
|
fn evaluate_array_len(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
place: &mir::Place<'tcx>) -> ValueRef
|
place: &mir::Place<'tcx>) -> ValueRef
|
||||||
{
|
{
|
||||||
// ZST are passed as operands and require special handling
|
// ZST are passed as operands and require special handling
|
||||||
@ -531,7 +531,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_scalar_binop(&mut self,
|
pub fn codegen_scalar_binop(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
op: mir::BinOp,
|
op: mir::BinOp,
|
||||||
lhs: ValueRef,
|
lhs: ValueRef,
|
||||||
rhs: ValueRef,
|
rhs: ValueRef,
|
||||||
@ -597,7 +597,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_fat_ptr_binop(&mut self,
|
pub fn codegen_fat_ptr_binop(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
op: mir::BinOp,
|
op: mir::BinOp,
|
||||||
lhs_addr: ValueRef,
|
lhs_addr: ValueRef,
|
||||||
lhs_extra: ValueRef,
|
lhs_extra: ValueRef,
|
||||||
@ -644,7 +644,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn codegen_scalar_checked_binop(&mut self,
|
pub fn codegen_scalar_checked_binop(&mut self,
|
||||||
bx: &Builder<'a, 'tcx>,
|
bx: &Builder<'a, 'll, 'tcx>,
|
||||||
op: mir::BinOp,
|
op: mir::BinOp,
|
||||||
lhs: ValueRef,
|
lhs: ValueRef,
|
||||||
rhs: ValueRef,
|
rhs: ValueRef,
|
||||||
@ -796,11 +796,11 @@ fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> ValueRef {
|
|||||||
bx.cx.get_intrinsic(&name)
|
bx.cx.get_intrinsic(&name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_int_to_float(bx: &Builder,
|
fn cast_int_to_float(bx: &Builder<'_, 'll, '_>,
|
||||||
signed: bool,
|
signed: bool,
|
||||||
x: ValueRef,
|
x: ValueRef,
|
||||||
int_ty: Type,
|
int_ty: &'ll Type,
|
||||||
float_ty: Type) -> ValueRef {
|
float_ty: &'ll Type) -> ValueRef {
|
||||||
// Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding.
|
// Most integer types, even i128, fit into [-f32::MAX, f32::MAX] after rounding.
|
||||||
// It's only u128 -> f32 that can cause overflows (i.e., should yield infinity).
|
// It's only u128 -> f32 that can cause overflows (i.e., should yield infinity).
|
||||||
// LLVM's uitofp produces undef in those cases, so we manually check for that case.
|
// LLVM's uitofp produces undef in those cases, so we manually check for that case.
|
||||||
@ -826,11 +826,11 @@ fn cast_int_to_float(bx: &Builder,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn cast_float_to_int(bx: &Builder,
|
fn cast_float_to_int(bx: &Builder<'_, 'll, '_>,
|
||||||
signed: bool,
|
signed: bool,
|
||||||
x: ValueRef,
|
x: ValueRef,
|
||||||
float_ty: Type,
|
float_ty: &'ll Type,
|
||||||
int_ty: Type) -> ValueRef {
|
int_ty: &'ll Type) -> ValueRef {
|
||||||
let fptosui_result = if signed {
|
let fptosui_result = if signed {
|
||||||
bx.fptosi(x, int_ty)
|
bx.fptosi(x, int_ty)
|
||||||
} else {
|
} else {
|
||||||
@ -859,14 +859,14 @@ fn cast_float_to_int(bx: &Builder,
|
|||||||
// On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
|
// On the other hand, f_max works even if int_ty::MAX is greater than float_ty::MAX. Because
|
||||||
// we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
|
// we're rounding towards zero, we just get float_ty::MAX (which is always an integer).
|
||||||
// This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
|
// This already happens today with u128::MAX = 2^128 - 1 > f32::MAX.
|
||||||
fn compute_clamp_bounds<F: Float>(signed: bool, int_ty: Type) -> (u128, u128) {
|
fn compute_clamp_bounds<F: Float>(signed: bool, int_ty: &Type) -> (u128, u128) {
|
||||||
let rounded_min = F::from_i128_r(int_min(signed, int_ty), Round::TowardZero);
|
let rounded_min = F::from_i128_r(int_min(signed, int_ty), Round::TowardZero);
|
||||||
assert_eq!(rounded_min.status, Status::OK);
|
assert_eq!(rounded_min.status, Status::OK);
|
||||||
let rounded_max = F::from_u128_r(int_max(signed, int_ty), Round::TowardZero);
|
let rounded_max = F::from_u128_r(int_max(signed, int_ty), Round::TowardZero);
|
||||||
assert!(rounded_max.value.is_finite());
|
assert!(rounded_max.value.is_finite());
|
||||||
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
|
(rounded_min.value.to_bits(), rounded_max.value.to_bits())
|
||||||
}
|
}
|
||||||
fn int_max(signed: bool, int_ty: Type) -> u128 {
|
fn int_max(signed: bool, int_ty: &Type) -> u128 {
|
||||||
let shift_amount = 128 - int_ty.int_width();
|
let shift_amount = 128 - int_ty.int_width();
|
||||||
if signed {
|
if signed {
|
||||||
i128::MAX as u128 >> shift_amount
|
i128::MAX as u128 >> shift_amount
|
||||||
@ -874,7 +874,7 @@ fn cast_float_to_int(bx: &Builder,
|
|||||||
u128::MAX >> shift_amount
|
u128::MAX >> shift_amount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn int_min(signed: bool, int_ty: Type) -> i128 {
|
fn int_min(signed: bool, int_ty: &Type) -> i128 {
|
||||||
if signed {
|
if signed {
|
||||||
i128::MIN >> (128 - int_ty.int_width())
|
i128::MIN >> (128 - int_ty.int_width())
|
||||||
} else {
|
} else {
|
||||||
|
@ -16,11 +16,11 @@ use builder::Builder;
|
|||||||
use super::FunctionCx;
|
use super::FunctionCx;
|
||||||
use super::LocalRef;
|
use super::LocalRef;
|
||||||
|
|
||||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
impl FunctionCx<'a, 'll, 'tcx> {
|
||||||
pub fn codegen_statement(&mut self,
|
pub fn codegen_statement(&mut self,
|
||||||
bx: Builder<'a, 'tcx>,
|
bx: Builder<'a, 'll, 'tcx>,
|
||||||
statement: &mir::Statement<'tcx>)
|
statement: &mir::Statement<'tcx>)
|
||||||
-> Builder<'a, 'tcx> {
|
-> Builder<'a, 'll, 'tcx> {
|
||||||
debug!("codegen_statement(statement={:?})", statement);
|
debug!("codegen_statement(statement={:?})", statement);
|
||||||
|
|
||||||
self.set_debug_loc(&bx, statement.source_info);
|
self.set_debug_loc(&bx, statement.source_info);
|
||||||
|
@ -10,8 +10,10 @@
|
|||||||
|
|
||||||
#![allow(non_upper_case_globals)]
|
#![allow(non_upper_case_globals)]
|
||||||
|
|
||||||
|
pub use llvm::Type;
|
||||||
|
|
||||||
use llvm;
|
use llvm;
|
||||||
use llvm::{TypeRef, Bool, False, True, TypeKind};
|
use llvm::{Bool, False, True, TypeKind};
|
||||||
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
use llvm::{Float, Double, X86_FP80, PPC_FP128, FP128};
|
||||||
|
|
||||||
use context::CodegenCx;
|
use context::CodegenCx;
|
||||||
@ -21,121 +23,125 @@ use rustc::ty::layout::{self, Align, Size};
|
|||||||
|
|
||||||
use std::ffi::CString;
|
use std::ffi::CString;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
|
||||||
|
|
||||||
use libc::c_uint;
|
use libc::c_uint;
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq)]
|
impl PartialEq for Type {
|
||||||
#[repr(C)]
|
fn eq(&self, other: &Self) -> bool {
|
||||||
pub struct Type {
|
self as *const _ == other as *const _
|
||||||
rf: TypeRef
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Debug for Type {
|
impl fmt::Debug for Type {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
f.write_str(&llvm::build_string(|s| unsafe {
|
f.write_str(&llvm::build_string(|s| unsafe {
|
||||||
llvm::LLVMRustWriteTypeToString(self.to_ref(), s);
|
llvm::LLVMRustWriteTypeToString(self, s);
|
||||||
}).expect("non-UTF8 type description from LLVM"))
|
}).expect("non-UTF8 type description from LLVM"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
macro_rules! ty {
|
|
||||||
($e:expr) => ( Type::from_ref(unsafe { $e }))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wrapper for LLVM TypeRef
|
|
||||||
impl Type {
|
impl Type {
|
||||||
#[inline(always)]
|
pub fn void(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
pub fn from_ref(r: TypeRef) -> Type {
|
unsafe {
|
||||||
Type {
|
llvm::LLVMVoidTypeInContext(cx.llcx)
|
||||||
rf: r
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler
|
pub fn metadata(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
pub fn to_ref(&self) -> TypeRef {
|
unsafe {
|
||||||
self.rf
|
llvm::LLVMRustMetadataTypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] {
|
pub fn i1(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
unsafe { mem::transmute(slice) }
|
unsafe {
|
||||||
|
llvm::LLVMInt1TypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn void(cx: &CodegenCx) -> Type {
|
pub fn i8(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMVoidTypeInContext(cx.llcx))
|
unsafe {
|
||||||
|
llvm::LLVMInt8TypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn metadata(cx: &CodegenCx) -> Type {
|
pub fn i8_llcx(llcx: &llvm::Context) -> &Type {
|
||||||
ty!(llvm::LLVMRustMetadataTypeInContext(cx.llcx))
|
unsafe {
|
||||||
|
llvm::LLVMInt8TypeInContext(llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i1(cx: &CodegenCx) -> Type {
|
pub fn i16(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMInt1TypeInContext(cx.llcx))
|
unsafe {
|
||||||
|
llvm::LLVMInt16TypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8(cx: &CodegenCx) -> Type {
|
pub fn i32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMInt8TypeInContext(cx.llcx))
|
unsafe {
|
||||||
|
llvm::LLVMInt32TypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8_llcx(llcx: &llvm::Context) -> Type {
|
pub fn i64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMInt8TypeInContext(llcx))
|
unsafe {
|
||||||
|
llvm::LLVMInt64TypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i16(cx: &CodegenCx) -> Type {
|
pub fn i128(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMInt16TypeInContext(cx.llcx))
|
unsafe {
|
||||||
}
|
llvm::LLVMIntTypeInContext(cx.llcx, 128)
|
||||||
|
}
|
||||||
pub fn i32(cx: &CodegenCx) -> Type {
|
|
||||||
ty!(llvm::LLVMInt32TypeInContext(cx.llcx))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i64(cx: &CodegenCx) -> Type {
|
|
||||||
ty!(llvm::LLVMInt64TypeInContext(cx.llcx))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn i128(cx: &CodegenCx) -> Type {
|
|
||||||
ty!(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(cx: &CodegenCx, num_bits: u64) -> Type {
|
pub fn ix(cx: &CodegenCx<'ll, '_>, num_bits: u64) -> &'ll Type {
|
||||||
ty!(llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint))
|
unsafe {
|
||||||
|
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(llcx: &llvm::Context, num_bits: u64) -> Type {
|
pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type {
|
||||||
ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint))
|
unsafe {
|
||||||
|
llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f32(cx: &CodegenCx) -> Type {
|
pub fn f32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMFloatTypeInContext(cx.llcx))
|
unsafe {
|
||||||
|
llvm::LLVMFloatTypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn f64(cx: &CodegenCx) -> Type {
|
pub fn f64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMDoubleTypeInContext(cx.llcx))
|
unsafe {
|
||||||
|
llvm::LLVMDoubleTypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn bool(cx: &CodegenCx) -> Type {
|
pub fn bool(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
Type::i8(cx)
|
Type::i8(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn char(cx: &CodegenCx) -> Type {
|
pub fn char(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
Type::i32(cx)
|
Type::i32(cx)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8p(cx: &CodegenCx) -> Type {
|
pub fn i8p(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
Type::i8(cx).ptr_to()
|
Type::i8(cx).ptr_to()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn i8p_llcx(llcx: &llvm::Context) -> Type {
|
pub fn i8p_llcx(llcx: &llvm::Context) -> &Type {
|
||||||
Type::i8_llcx(llcx).ptr_to()
|
Type::i8_llcx(llcx).ptr_to()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn isize(cx: &CodegenCx) -> Type {
|
pub fn isize(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
cx.isize_ty
|
cx.isize_ty
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn c_int(cx: &CodegenCx) -> Type {
|
pub fn c_int(cx: &CodegenCx<'ll, '_>) -> &'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),
|
||||||
@ -144,7 +150,7 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn int_from_ty(cx: &CodegenCx, t: ast::IntTy) -> Type {
|
pub fn int_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::IntTy) -> &'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),
|
||||||
@ -155,7 +161,7 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn uint_from_ty(cx: &CodegenCx, t: ast::UintTy) -> Type {
|
pub fn uint_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::UintTy) -> &'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),
|
||||||
@ -166,83 +172,93 @@ impl Type {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn float_from_ty(cx: &CodegenCx, t: ast::FloatTy) -> Type {
|
pub fn float_from_ty(cx: &CodegenCx<'ll, '_>, t: ast::FloatTy) -> &'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(args: &[Type], ret: &Type) -> Type {
|
pub fn func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
|
||||||
let slice: &[TypeRef] = Type::to_ref_slice(args);
|
unsafe {
|
||||||
ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
|
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
||||||
args.len() as c_uint, False))
|
args.len() as c_uint, False)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
|
pub fn variadic_func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
|
||||||
let slice: &[TypeRef] = Type::to_ref_slice(args);
|
unsafe {
|
||||||
ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
|
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
||||||
args.len() as c_uint, True))
|
args.len() as c_uint, True)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn struct_(cx: &CodegenCx, els: &[Type], packed: bool) -> Type {
|
pub fn struct_(cx: &CodegenCx<'ll, '_>, els: &[&'ll Type], packed: bool) -> &'ll Type {
|
||||||
let els: &[TypeRef] = Type::to_ref_slice(els);
|
unsafe {
|
||||||
ty!(llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
|
llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
|
||||||
els.len() as c_uint,
|
els.len() as c_uint,
|
||||||
packed as Bool))
|
packed as Bool)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn named_struct(cx: &CodegenCx, name: &str) -> Type {
|
pub fn named_struct(cx: &CodegenCx<'ll, '_>, name: &str) -> &'ll Type {
|
||||||
let name = CString::new(name).unwrap();
|
let name = CString::new(name).unwrap();
|
||||||
ty!(llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr()))
|
unsafe {
|
||||||
|
llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn array(ty: &Type, len: u64) -> Type {
|
pub fn array(ty: &Type, len: u64) -> &Type {
|
||||||
ty!(llvm::LLVMRustArrayType(ty.to_ref(), len))
|
unsafe {
|
||||||
|
llvm::LLVMRustArrayType(ty, len)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn vector(ty: &Type, len: u64) -> Type {
|
pub fn vector(ty: &Type, len: u64) -> &Type {
|
||||||
ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint))
|
unsafe {
|
||||||
|
llvm::LLVMVectorType(ty, len as c_uint)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn kind(&self) -> TypeKind {
|
pub fn kind(&self) -> TypeKind {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMRustGetTypeKind(self.to_ref())
|
llvm::LLVMRustGetTypeKind(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
|
pub fn set_struct_body(&'ll self, els: &[&'ll Type], packed: bool) {
|
||||||
let slice: &[TypeRef] = Type::to_ref_slice(els);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(),
|
llvm::LLVMStructSetBody(self, els.as_ptr(),
|
||||||
els.len() as c_uint, packed as Bool)
|
els.len() as c_uint, packed as Bool)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn ptr_to(&self) -> Type {
|
pub fn ptr_to(&self) -> &Type {
|
||||||
ty!(llvm::LLVMPointerType(self.to_ref(), 0))
|
unsafe {
|
||||||
|
llvm::LLVMPointerType(self, 0)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn element_type(&self) -> Type {
|
pub fn element_type(&self) -> &Type {
|
||||||
unsafe {
|
unsafe {
|
||||||
Type::from_ref(llvm::LLVMGetElementType(self.to_ref()))
|
llvm::LLVMGetElementType(self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of elements in `self` if it is a LLVM vector type.
|
/// Return the number of elements in `self` if it is a LLVM vector type.
|
||||||
pub fn vector_length(&self) -> usize {
|
pub fn vector_length(&self) -> usize {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMGetVectorSize(self.to_ref()) as usize
|
llvm::LLVMGetVectorSize(self) as usize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn func_params(&self) -> Vec<Type> {
|
pub fn func_params(&self) -> Vec<&Type> {
|
||||||
unsafe {
|
unsafe {
|
||||||
let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize;
|
let n_args = llvm::LLVMCountParamTypes(self) as usize;
|
||||||
let mut args = vec![Type { rf: 0 as *mut _ }; n_args];
|
let mut args = Vec::with_capacity(n_args);
|
||||||
llvm::LLVMGetParamTypes(self.to_ref(),
|
llvm::LLVMGetParamTypes(self, args.as_mut_ptr());
|
||||||
args.as_mut_ptr() as *mut TypeRef);
|
args.set_len(n_args);
|
||||||
args
|
args
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -260,11 +276,11 @@ impl Type {
|
|||||||
/// Retrieve the bit width of the integer type `self`.
|
/// Retrieve the bit width of the integer type `self`.
|
||||||
pub fn int_width(&self) -> u64 {
|
pub fn int_width(&self) -> u64 {
|
||||||
unsafe {
|
unsafe {
|
||||||
llvm::LLVMGetIntTypeWidth(self.to_ref()) as u64
|
llvm::LLVMGetIntTypeWidth(self) as u64
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_integer(cx: &CodegenCx, i: layout::Integer) -> Type {
|
pub fn from_integer(cx: &CodegenCx<'ll, '_>, i: layout::Integer) -> &'ll Type {
|
||||||
use rustc::ty::layout::Integer::*;
|
use rustc::ty::layout::Integer::*;
|
||||||
match i {
|
match i {
|
||||||
I8 => Type::i8(cx),
|
I8 => Type::i8(cx),
|
||||||
@ -277,7 +293,7 @@ impl Type {
|
|||||||
|
|
||||||
/// Return a LLVM type that has at most the required alignment,
|
/// Return a LLVM type that has at most the required alignment,
|
||||||
/// as a conservative approximation for unknown pointee types.
|
/// as a conservative approximation for unknown pointee types.
|
||||||
pub fn pointee_for_abi_align(cx: &CodegenCx, align: Align) -> Type {
|
pub fn pointee_for_abi_align(cx: &CodegenCx<'ll, '_>, align: Align) -> &'ll Type {
|
||||||
// FIXME(eddyb) We could find a better approximation if ity.align < align.
|
// FIXME(eddyb) We could find a better approximation if ity.align < align.
|
||||||
let ity = layout::Integer::approximate_abi_align(cx, align);
|
let ity = layout::Integer::approximate_abi_align(cx, align);
|
||||||
Type::from_integer(cx, ity)
|
Type::from_integer(cx, ity)
|
||||||
@ -285,15 +301,17 @@ impl Type {
|
|||||||
|
|
||||||
/// Return a LLVM type that has at most the required alignment,
|
/// Return a LLVM type that has at most the required alignment,
|
||||||
/// and exactly the required size, as a best-effort padding array.
|
/// and exactly the required size, as a best-effort padding array.
|
||||||
pub fn padding_filler(cx: &CodegenCx, size: Size, align: Align) -> Type {
|
pub fn padding_filler(cx: &CodegenCx<'ll, '_>, size: Size, align: Align) -> &'ll Type {
|
||||||
let unit = layout::Integer::approximate_abi_align(cx, align);
|
let unit = layout::Integer::approximate_abi_align(cx, align);
|
||||||
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(&Type::from_integer(cx, unit), size / unit_size)
|
Type::array(Type::from_integer(cx, unit), size / unit_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn x86_mmx(cx: &CodegenCx) -> Type {
|
pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||||
ty!(llvm::LLVMX86MMXTypeInContext(cx.llcx))
|
unsafe {
|
||||||
|
llvm::LLVMX86MMXTypeInContext(cx.llcx)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,8 +23,8 @@ use std::fmt::Write;
|
|||||||
|
|
||||||
fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
layout: TyLayout<'tcx>,
|
layout: TyLayout<'tcx>,
|
||||||
defer: &mut Option<(Type, TyLayout<'tcx>)>)
|
defer: &mut Option<(&'a Type, TyLayout<'tcx>)>)
|
||||||
-> Type {
|
-> &'a Type {
|
||||||
match layout.abi {
|
match layout.abi {
|
||||||
layout::Abi::Scalar(_) => bug!("handled elsewhere"),
|
layout::Abi::Scalar(_) => bug!("handled elsewhere"),
|
||||||
layout::Abi::Vector { ref element, count } => {
|
layout::Abi::Vector { ref element, count } => {
|
||||||
@ -42,7 +42,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(&element, count);
|
return Type::vector(element, count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
layout::Abi::ScalarPair(..) => {
|
layout::Abi::ScalarPair(..) => {
|
||||||
@ -96,7 +96,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
layout::FieldPlacement::Array { count, .. } => {
|
layout::FieldPlacement::Array { count, .. } => {
|
||||||
Type::array(&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 {
|
||||||
@ -116,14 +116,14 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
|||||||
|
|
||||||
fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
fn struct_llfields<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||||
layout: TyLayout<'tcx>)
|
layout: TyLayout<'tcx>)
|
||||||
-> (Vec<Type>, bool) {
|
-> (Vec<&'a Type>, bool) {
|
||||||
debug!("struct_llfields: {:#?}", layout);
|
debug!("struct_llfields: {:#?}", layout);
|
||||||
let field_count = layout.fields.count();
|
let field_count = layout.fields.count();
|
||||||
|
|
||||||
let mut packed = false;
|
let mut packed = false;
|
||||||
let mut offset = Size::ZERO;
|
let mut offset = Size::ZERO;
|
||||||
let mut prev_align = layout.align;
|
let mut prev_align = layout.align;
|
||||||
let mut result: Vec<Type> = Vec::with_capacity(1 + field_count * 2);
|
let mut result: Vec<_> = Vec::with_capacity(1 + field_count * 2);
|
||||||
for i in layout.fields.index_by_increasing_offset() {
|
for i in layout.fields.index_by_increasing_offset() {
|
||||||
let field = layout.field(cx, i);
|
let field = layout.field(cx, i);
|
||||||
packed |= layout.align.abi() < field.align.abi();
|
packed |= layout.align.abi() < field.align.abi();
|
||||||
@ -201,12 +201,12 @@ pub struct PointeeInfo {
|
|||||||
pub trait LayoutLlvmExt<'tcx> {
|
pub trait LayoutLlvmExt<'tcx> {
|
||||||
fn is_llvm_immediate(&self) -> bool;
|
fn is_llvm_immediate(&self) -> bool;
|
||||||
fn is_llvm_scalar_pair<'a>(&self) -> bool;
|
fn is_llvm_scalar_pair<'a>(&self) -> bool;
|
||||||
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
|
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
|
||||||
fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
|
fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
|
||||||
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
||||||
scalar: &layout::Scalar, offset: Size) -> Type;
|
scalar: &layout::Scalar, offset: Size) -> &'a Type;
|
||||||
fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
||||||
index: usize, immediate: bool) -> Type;
|
index: usize, immediate: bool) -> &'a Type;
|
||||||
fn llvm_field_index(&self, index: usize) -> u64;
|
fn llvm_field_index(&self, index: usize) -> u64;
|
||||||
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size)
|
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size)
|
||||||
-> Option<PointeeInfo>;
|
-> Option<PointeeInfo>;
|
||||||
@ -244,7 +244,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||||||
/// with the inner-most trailing unsized field using the "minimal unit"
|
/// with the inner-most trailing unsized field using the "minimal unit"
|
||||||
/// of that field's type - this is useful for taking the address of
|
/// of that field's type - this is useful for taking the address of
|
||||||
/// that field and ensuring the struct has the right alignment.
|
/// that field and ensuring the struct has the right alignment.
|
||||||
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
|
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
|
||||||
if let layout::Abi::Scalar(ref scalar) = self.abi {
|
if let layout::Abi::Scalar(ref scalar) = self.abi {
|
||||||
// Use a different cache for scalars because pointers to DSTs
|
// Use a different cache for scalars because pointers to DSTs
|
||||||
// can be either fat or thin (data pointers of fat pointers).
|
// can be either fat or thin (data pointers of fat pointers).
|
||||||
@ -304,7 +304,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||||||
|
|
||||||
cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty);
|
cx.lltypes.borrow_mut().insert((self.ty, variant_index), llty);
|
||||||
|
|
||||||
if let Some((mut llty, layout)) = defer {
|
if let Some((llty, layout)) = defer {
|
||||||
let (llfields, packed) = struct_llfields(cx, layout);
|
let (llfields, packed) = struct_llfields(cx, layout);
|
||||||
llty.set_struct_body(&llfields, packed)
|
llty.set_struct_body(&llfields, packed)
|
||||||
}
|
}
|
||||||
@ -312,7 +312,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||||||
llty
|
llty
|
||||||
}
|
}
|
||||||
|
|
||||||
fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
|
fn immediate_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
|
||||||
if let layout::Abi::Scalar(ref scalar) = self.abi {
|
if let layout::Abi::Scalar(ref scalar) = self.abi {
|
||||||
if scalar.is_bool() {
|
if scalar.is_bool() {
|
||||||
return Type::i1(cx);
|
return Type::i1(cx);
|
||||||
@ -322,7 +322,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
fn scalar_llvm_type_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
||||||
scalar: &layout::Scalar, offset: Size) -> Type {
|
scalar: &layout::Scalar, offset: Size) -> &'a Type {
|
||||||
match scalar.value {
|
match scalar.value {
|
||||||
layout::Int(i, _) => Type::from_integer(cx, i),
|
layout::Int(i, _) => Type::from_integer(cx, i),
|
||||||
layout::Float(FloatTy::F32) => Type::f32(cx),
|
layout::Float(FloatTy::F32) => Type::f32(cx),
|
||||||
@ -340,7 +340,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
fn scalar_pair_element_llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>,
|
||||||
index: usize, immediate: bool) -> Type {
|
index: usize, immediate: bool) -> &'a Type {
|
||||||
// HACK(eddyb) special-case fat pointers until LLVM removes
|
// HACK(eddyb) special-case fat pointers until LLVM removes
|
||||||
// pointee types, to avoid bitcasting every `OperandRef::deref`.
|
// pointee types, to avoid bitcasting every `OperandRef::deref`.
|
||||||
match self.ty.sty {
|
match self.ty.sty {
|
||||||
|
Loading…
Reference in New Issue
Block a user