mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-21 11:23:03 +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 {
|
||||
fn llvm_type(&self, cx: &CodegenCx) -> Type;
|
||||
fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type;
|
||||
}
|
||||
|
||||
impl LlvmType for Reg {
|
||||
fn llvm_type(&self, cx: &CodegenCx) -> Type {
|
||||
fn llvm_type(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
match self.kind {
|
||||
RegKind::Integer => Type::ix(cx, self.size.bits()),
|
||||
RegKind::Float => {
|
||||
@ -118,14 +118,14 @@ impl LlvmType for Reg {
|
||||
}
|
||||
}
|
||||
RegKind::Vector => {
|
||||
Type::vector(&Type::i8(cx), self.size.bytes())
|
||||
Type::vector(Type::i8(cx), self.size.bytes())
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
|
||||
(0, 0)
|
||||
@ -142,7 +142,7 @@ impl LlvmType for CastTarget {
|
||||
|
||||
// Simplify to array when all chunks are the same size and type
|
||||
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> {
|
||||
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
|
||||
fn store(&self, bx: &Builder<'a, 'tcx>, val: ValueRef, dst: PlaceRef<'tcx>);
|
||||
fn store_fn_arg(&self, bx: &Builder<'a, 'tcx>, idx: &mut usize, dst: PlaceRef<'tcx>);
|
||||
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type;
|
||||
fn store(&self, bx: &Builder<'a, 'll, 'tcx>, val: ValueRef, 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>> {
|
||||
/// 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`.
|
||||
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> Type {
|
||||
fn memory_ty(&self, cx: &CodegenCx<'a, 'tcx>) -> &'a Type {
|
||||
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.
|
||||
/// Can be used for both storing formal arguments into Rust variables
|
||||
/// 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() {
|
||||
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 val = llvm::get_param(bx.llfn(), *idx as c_uint);
|
||||
*idx += 1;
|
||||
@ -270,10 +270,10 @@ pub trait FnTypeExt<'a, 'tcx> {
|
||||
fn adjust_for_abi(&mut self,
|
||||
cx: &CodegenCx<'a, 'tcx>,
|
||||
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 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>> {
|
||||
@ -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|
|
||||
if arg.pad.is_some() { 1 } else { 0 } +
|
||||
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 {
|
||||
Type::variadic_func(&llargument_tys, &llreturn_ty)
|
||||
Type::variadic_func(&llargument_tys, llreturn_ty)
|
||||
} 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 apply = |attrs: &ArgAttributes| {
|
||||
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
|
||||
|
@ -24,8 +24,8 @@ use syntax::ast::AsmDialect;
|
||||
use libc::{c_uint, c_char};
|
||||
|
||||
// Take an inline assembly expression and splat it out via LLVM
|
||||
pub fn codegen_inline_asm<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
pub fn codegen_inline_asm(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
ia: &hir::InlineAsm,
|
||||
outputs: Vec<PlaceRef<'tcx>>,
|
||||
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 llglobal = llvm::LLVMAddGlobal(
|
||||
llmod,
|
||||
val_ty(llconst).to_ref(),
|
||||
val_ty(llconst),
|
||||
"rustc.embedded.module\0".as_ptr() as *const _,
|
||||
);
|
||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||
@ -851,7 +851,7 @@ unsafe fn embed_bitcode(cgcx: &CodegenContext,
|
||||
let llconst = C_bytes_in_context(llcx, &[]);
|
||||
let llglobal = llvm::LLVMAddGlobal(
|
||||
llmod,
|
||||
val_ty(llconst).to_ref(),
|
||||
val_ty(llconst),
|
||||
"rustc.embedded.cmdline\0".as_ptr() as *const _,
|
||||
);
|
||||
llvm::LLVMSetInitializer(llglobal, llconst);
|
||||
@ -2380,7 +2380,7 @@ fn create_msvc_imps(cgcx: &CodegenContext, llcx: &llvm::Context, llmod: &llvm::M
|
||||
.collect::<Vec<_>>();
|
||||
for (imp_name, val) in globals {
|
||||
let imp = llvm::LLVMAddGlobal(llmod,
|
||||
i8p_ty.to_ref(),
|
||||
i8p_ty,
|
||||
imp_name.as_ptr() as *const _);
|
||||
llvm::LLVMSetInitializer(imp, consts::ptrcast(val, i8p_ty));
|
||||
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
|
||||
//! would be "trying to get the eggs out of an omelette" (credit:
|
||||
//! pcwalton). You can, instead, find out its TypeRef by calling val_ty,
|
||||
//! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
|
||||
//! int) and rec(x=int, y=int, z=int) will have the same TypeRef.
|
||||
//! pcwalton). You can, instead, find out its llvm::Type by calling val_ty,
|
||||
//! 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 llvm::Type.
|
||||
|
||||
use super::ModuleLlvm;
|
||||
use super::ModuleSource;
|
||||
@ -91,14 +91,14 @@ use mir::operand::OperandValue;
|
||||
|
||||
use rustc_codegen_utils::check_for_rustc_errors_attr;
|
||||
|
||||
pub struct StatRecorder<'a, 'tcx: 'a> {
|
||||
cx: &'a CodegenCx<'a, 'tcx>,
|
||||
pub struct StatRecorder<'a, 'll: 'a, 'tcx: 'll> {
|
||||
cx: &'a CodegenCx<'ll, 'tcx>,
|
||||
name: Option<String>,
|
||||
istart: usize,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> StatRecorder<'a, 'tcx> {
|
||||
pub fn new(cx: &'a CodegenCx<'a, 'tcx>, name: String) -> StatRecorder<'a, 'tcx> {
|
||||
impl StatRecorder<'a, 'll, 'tcx> {
|
||||
pub fn new(cx: &'a CodegenCx<'ll, 'tcx>, name: String) -> Self {
|
||||
let istart = cx.stats.borrow().n_llvm_insns;
|
||||
StatRecorder {
|
||||
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) {
|
||||
if self.cx.sess().codegen_stats() {
|
||||
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>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
pub fn compare_simd_types(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
t: Ty<'tcx>,
|
||||
ret_ty: Type,
|
||||
ret_ty: &'ll Type,
|
||||
op: hir::BinOpKind
|
||||
) -> ValueRef {
|
||||
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.
|
||||
pub fn unsize_thin_ptr<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
pub fn unsize_thin_ptr(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
src: ValueRef,
|
||||
src_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`,
|
||||
/// to a value of type `dst_ty` and store the result in `dst`
|
||||
pub fn coerce_unsized_into<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
src: PlaceRef<'tcx>,
|
||||
dst: PlaceRef<'tcx>) {
|
||||
pub fn coerce_unsized_into(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
src: PlaceRef<'tcx>,
|
||||
dst: PlaceRef<'tcx>
|
||||
) {
|
||||
let src_ty = src.layout.ty;
|
||||
let dst_ty = dst.layout.ty;
|
||||
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))
|
||||
}
|
||||
|
||||
fn cast_shift_rhs<F, G>(op: hir::BinOpKind,
|
||||
fn cast_shift_rhs<'ll, F, G>(op: hir::BinOpKind,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
trunc: F,
|
||||
zext: G)
|
||||
-> ValueRef
|
||||
where F: FnOnce(ValueRef, Type) -> ValueRef,
|
||||
G: FnOnce(ValueRef, Type) -> ValueRef
|
||||
where F: FnOnce(ValueRef, &'ll Type) -> ValueRef,
|
||||
G: FnOnce(ValueRef, &'ll Type) -> ValueRef
|
||||
{
|
||||
// Shifts may have any size int on the rhs
|
||||
if op.is_shift() {
|
||||
@ -378,7 +380,7 @@ pub fn wants_msvc_seh(sess: &Session) -> bool {
|
||||
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");
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn memcpy_ty<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
pub fn memcpy_ty(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
dst: ValueRef,
|
||||
src: ValueRef,
|
||||
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);
|
||||
}
|
||||
|
||||
pub fn call_memset<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
ptr: ValueRef,
|
||||
fill_byte: ValueRef,
|
||||
size: ValueRef,
|
||||
align: ValueRef,
|
||||
volatile: bool) -> ValueRef {
|
||||
pub fn call_memset(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
ptr: ValueRef,
|
||||
fill_byte: ValueRef,
|
||||
size: ValueRef,
|
||||
align: ValueRef,
|
||||
volatile: bool,
|
||||
) -> ValueRef {
|
||||
let ptr_width = &bx.cx.sess().target.target.target_pointer_width;
|
||||
let intrinsic_key = format!("llvm.memset.p0i8.i{}", ptr_width);
|
||||
let llintrinsicfn = bx.cx.get_intrinsic(&intrinsic_key);
|
||||
@ -553,7 +557,7 @@ fn maybe_create_entry_wrapper(cx: &CodegenCx) {
|
||||
rust_main: ValueRef,
|
||||
rust_main_def_id: DefId,
|
||||
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();
|
||||
// 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 buf = CString::new(name).unwrap();
|
||||
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 {
|
||||
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
|
||||
for &(old_g, new_g) in cx.statics_to_rauw.borrow().iter() {
|
||||
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::LLVMDeleteGlobal(old_g);
|
||||
}
|
||||
@ -1221,7 +1225,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
|
||||
unsafe {
|
||||
let g = llvm::LLVMAddGlobal(cx.llmod,
|
||||
val_ty(array).to_ref(),
|
||||
val_ty(array),
|
||||
name.as_ptr());
|
||||
llvm::LLVMSetInitializer(g, array);
|
||||
llvm::LLVMRustSetLinkage(g, llvm::Linkage::AppendingLinkage);
|
||||
|
@ -31,12 +31,12 @@ use syntax_pos::Span;
|
||||
|
||||
// All Builders must have an llfn associated with them
|
||||
#[must_use]
|
||||
pub struct Builder<'a, 'tcx: 'a> {
|
||||
pub struct Builder<'a, 'll: 'a, 'tcx: 'll> {
|
||||
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) {
|
||||
unsafe {
|
||||
llvm::LLVMDisposeBuilder(self.llbuilder);
|
||||
@ -59,8 +59,8 @@ bitflags! {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
pub fn new_block<'b>(cx: &'a CodegenCx<'a, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
|
||||
impl Builder<'a, 'll, 'tcx> {
|
||||
pub fn new_block<'b>(cx: &'a CodegenCx<'ll, 'tcx>, llfn: ValueRef, name: &'b str) -> Self {
|
||||
let bx = Builder::with_cx(cx);
|
||||
let llbb = unsafe {
|
||||
let name = CString::new(name).unwrap();
|
||||
@ -74,7 +74,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
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.
|
||||
let llbuilder = unsafe {
|
||||
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)
|
||||
}
|
||||
|
||||
@ -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);
|
||||
bx.position_at_start(unsafe {
|
||||
llvm::LLVMGetFirstBasicBlock(self.llfn())
|
||||
@ -512,14 +512,14 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
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");
|
||||
unsafe {
|
||||
let alloca = if name.is_empty() {
|
||||
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(), noname())
|
||||
llvm::LLVMBuildAlloca(self.llbuilder, ty, noname())
|
||||
} else {
|
||||
let name = CString::new(name).unwrap();
|
||||
llvm::LLVMBuildAlloca(self.llbuilder, ty.to_ref(),
|
||||
llvm::LLVMBuildAlloca(self.llbuilder, ty,
|
||||
name.as_ptr())
|
||||
};
|
||||
llvm::LLVMSetAlignment(alloca, align.abi() as c_uint);
|
||||
@ -678,136 +678,136 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}
|
||||
|
||||
/* 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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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");
|
||||
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 */
|
||||
pub fn empty_phi(&self, ty: Type) -> ValueRef {
|
||||
pub fn empty_phi(&self, ty: &'ll Type) -> ValueRef {
|
||||
self.count_insn("emptyphi");
|
||||
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());
|
||||
let phi = self.empty_phi(ty);
|
||||
self.count_insn("addincoming");
|
||||
@ -865,7 +865,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
self.count_insn("inlineasm");
|
||||
let comment_text = CString::new(comment_text).unwrap();
|
||||
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,
|
||||
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,
|
||||
inputs: &[ValueRef], output: Type,
|
||||
inputs: &[ValueRef], output: &'ll Type,
|
||||
volatile: bool, alignstack: bool,
|
||||
dia: AsmDialect) -> ValueRef {
|
||||
self.count_insn("inlineasm");
|
||||
@ -890,10 +890,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
||||
}).collect::<Vec<_>>();
|
||||
|
||||
debug!("Asm Output Type: {:?}", output);
|
||||
let fty = Type::func(&argtys[..], &output);
|
||||
let fty = Type::func(&argtys[..], output);
|
||||
unsafe {
|
||||
let v = llvm::LLVMRustInlineAsm(
|
||||
fty.to_ref(), asm, cons, volatile, alignstack, dia);
|
||||
fty, asm, cons, volatile, alignstack, dia);
|
||||
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");
|
||||
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 {
|
||||
unsafe {
|
||||
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_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))
|
||||
}
|
||||
}
|
||||
@ -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 {
|
||||
self.count_insn("landingpad");
|
||||
unsafe {
|
||||
llvm::LLVMBuildLandingPad(self.llbuilder, ty.to_ref(), pers_fn,
|
||||
llvm::LLVMBuildLandingPad(self.llbuilder, ty, pers_fn,
|
||||
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 {
|
||||
Type::from_ref(llvm::LLVMTypeOf(v))
|
||||
llvm::LLVMTypeOf(&*v)
|
||||
}
|
||||
}
|
||||
|
||||
// LLVM constant constructors.
|
||||
pub fn C_null(t: Type) -> ValueRef {
|
||||
pub fn C_null(t: &Type) -> ValueRef {
|
||||
unsafe {
|
||||
llvm::LLVMConstNull(t.to_ref())
|
||||
llvm::LLVMConstNull(t)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn C_undef(t: Type) -> ValueRef {
|
||||
pub fn C_undef(t: &Type) -> ValueRef {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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 {
|
||||
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
|
||||
// of Java. (See related discussion on #1877 and #10183.)
|
||||
|
||||
pub fn build_unchecked_lshift<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
pub fn build_unchecked_lshift(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef
|
||||
) -> ValueRef {
|
||||
@ -356,8 +357,8 @@ pub fn build_unchecked_lshift<'a, 'tcx>(
|
||||
bx.shl(lhs, rhs)
|
||||
}
|
||||
|
||||
pub fn build_unchecked_rshift<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef
|
||||
pub fn build_unchecked_rshift(
|
||||
bx: &Builder<'a, 'll, 'tcx>, lhs_t: Ty<'tcx>, lhs: ValueRef, rhs: ValueRef
|
||||
) -> ValueRef {
|
||||
let rhs = base::cast_shift_expr_rhs(bx, hir::BinOpKind::Shr, lhs, rhs);
|
||||
// #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);
|
||||
bx.and(rhs, shift_mask_val(bx, rhs_llty, rhs_llty, false))
|
||||
}
|
||||
|
||||
pub fn shift_mask_val<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
llty: Type,
|
||||
mask_llty: Type,
|
||||
pub fn shift_mask_val(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
llty: &'ll Type,
|
||||
mask_llty: &'ll Type,
|
||||
invert: bool
|
||||
) -> ValueRef {
|
||||
let kind = llty.kind();
|
||||
|
@ -31,15 +31,15 @@ use rustc::hir::{self, CodegenFnAttrs, CodegenFnAttrFlags};
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
|
||||
pub fn ptrcast(val: ValueRef, ty: Type) -> ValueRef {
|
||||
pub fn ptrcast(val: ValueRef, ty: &Type) -> ValueRef {
|
||||
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 {
|
||||
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 v = if val_llty == Type::i1(cx) {
|
||||
val_llty = Type::i8(cx);
|
||||
llvm::LLVMConstZExt(v, val_llty.to_ref())
|
||||
llvm::LLVMConstZExt(v, val_llty)
|
||||
} else {
|
||||
v
|
||||
};
|
||||
@ -316,7 +316,7 @@ pub fn codegen_static<'a, 'tcx>(
|
||||
let visibility = llvm::LLVMRustGetVisibility(g);
|
||||
|
||||
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::LLVMRustSetVisibility(new_g, visibility);
|
||||
@ -411,7 +411,7 @@ pub fn codegen_static<'a, 'tcx>(
|
||||
|
||||
if attrs.flags.contains(CodegenFnAttrFlags::USED) {
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
@ -89,10 +89,10 @@ pub struct CodegenCx<'a, 'tcx: 'a> {
|
||||
/// See http://llvm.org/docs/LangRef.html#the-llvm-used-global-variable for details
|
||||
pub used_statics: RefCell<Vec<ValueRef>>,
|
||||
|
||||
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), Type>>,
|
||||
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, Type>>,
|
||||
pub lltypes: RefCell<FxHashMap<(Ty<'tcx>, Option<usize>), &'a Type>>,
|
||||
pub scalar_lltypes: RefCell<FxHashMap<Ty<'tcx>, &'a Type>>,
|
||||
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>>,
|
||||
|
||||
@ -373,7 +373,7 @@ impl<'b, 'tcx> CodegenCx<'b, 'tcx> {
|
||||
} else {
|
||||
"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)
|
||||
}
|
||||
};
|
||||
@ -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 {
|
||||
&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 {
|
||||
&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> {
|
||||
self.tcx
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> LayoutOf for &'a CodegenCx<'a, 'tcx> {
|
||||
impl LayoutOf for &'a CodegenCx<'ll, 'tcx> {
|
||||
type Ty = Ty<'tcx>;
|
||||
type TyLayout = TyLayout<'tcx>;
|
||||
|
||||
@ -475,7 +475,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
||||
macro_rules! ifn {
|
||||
($name:expr, fn() -> $ret:expr) => (
|
||||
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);
|
||||
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||
return Some(f);
|
||||
@ -483,7 +483,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
||||
);
|
||||
($name:expr, fn(...) -> $ret:expr) => (
|
||||
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);
|
||||
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||
return Some(f);
|
||||
@ -491,7 +491,7 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
||||
);
|
||||
($name:expr, fn($($arg:expr),*) -> $ret:expr) => (
|
||||
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);
|
||||
cx.intrinsics.borrow_mut().insert($name, f.clone());
|
||||
return Some(f);
|
||||
@ -513,14 +513,14 @@ fn declare_intrinsic(cx: &CodegenCx, key: &str) -> Option<ValueRef> {
|
||||
let t_f32 = Type::f32(cx);
|
||||
let t_f64 = Type::f64(cx);
|
||||
|
||||
let t_v2f32 = Type::vector(&t_f32, 2);
|
||||
let t_v4f32 = Type::vector(&t_f32, 4);
|
||||
let t_v8f32 = Type::vector(&t_f32, 8);
|
||||
let t_v16f32 = Type::vector(&t_f32, 16);
|
||||
let t_v2f32 = Type::vector(t_f32, 2);
|
||||
let t_v4f32 = Type::vector(t_f32, 4);
|
||||
let t_v8f32 = Type::vector(t_f32, 8);
|
||||
let t_v16f32 = Type::vector(t_f32, 16);
|
||||
|
||||
let t_v2f64 = Type::vector(&t_f64, 2);
|
||||
let t_v4f64 = Type::vector(&t_f64, 4);
|
||||
let t_v8f64 = Type::vector(&t_f64, 8);
|
||||
let t_v2f64 = Type::vector(t_f64, 2);
|
||||
let t_v4f64 = Type::vector(t_f64, 4);
|
||||
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.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";
|
||||
|
||||
unsafe {
|
||||
let llvm_type = Type::array(&Type::i8(cx),
|
||||
let llvm_type = Type::array(Type::i8(cx),
|
||||
section_contents.len() as u64);
|
||||
|
||||
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>,
|
||||
dbg_context: &FunctionDebugContext,
|
||||
variable_name: ast::Name,
|
||||
variable_type: Ty<'tcx>,
|
||||
scope_metadata: DIScope,
|
||||
variable_access: VariableAccess,
|
||||
variable_kind: VariableKind,
|
||||
span: Span) {
|
||||
pub fn declare_local(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
dbg_context: &FunctionDebugContext,
|
||||
variable_name: ast::Name,
|
||||
variable_type: Ty<'tcx>,
|
||||
scope_metadata: DIScope,
|
||||
variable_access: VariableAccess,
|
||||
variable_kind: VariableKind,
|
||||
span: Span,
|
||||
) {
|
||||
assert!(!dbg_context.get_ref(span).source_locations_enabled.get());
|
||||
let cx = bx.cx;
|
||||
|
||||
|
@ -49,8 +49,7 @@ pub fn span_start(cx: &CodegenCx, span: Span) -> syntax_pos::Loc {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn debug_context<'a, 'tcx>(cx: &'a CodegenCx<'a, 'tcx>)
|
||||
-> &'a CrateDebugContext<'a, 'tcx> {
|
||||
pub fn debug_context(cx: &'a CodegenCx<'ll, 'tcx>) -> &'a CrateDebugContext<'a, 'tcx> {
|
||||
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
|
||||
/// 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);
|
||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
||||
bug!("name {:?} contains an interior null byte", name)
|
||||
});
|
||||
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
|
||||
/// 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);
|
||||
let namebuf = CString::new(name).unwrap_or_else(|_|{
|
||||
bug!("name {:?} contains an interior null byte", name)
|
||||
});
|
||||
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);
|
||||
@ -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
|
||||
/// 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)
|
||||
}
|
||||
|
||||
@ -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
|
||||
/// 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).
|
||||
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() {
|
||||
None
|
||||
} else {
|
||||
|
@ -23,7 +23,7 @@ use rustc::ty::layout::LayoutOf;
|
||||
use rustc::ty::{self, Ty};
|
||||
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) {
|
||||
debug!("calculate size of DST: {}; with lost 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,
|
||||
/// and in libcore/intrinsics.rs; if you need access to any llvm intrinsics,
|
||||
/// add them to librustc_codegen_llvm/context.rs
|
||||
pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
callee_ty: Ty<'tcx>,
|
||||
fn_ty: &FnType<'tcx, Ty<'tcx>>,
|
||||
args: &[OperandRef<'tcx>],
|
||||
llresult: ValueRef,
|
||||
span: Span) {
|
||||
pub fn codegen_intrinsic_call(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
callee_ty: Ty<'tcx>,
|
||||
fn_ty: &FnType<'tcx, Ty<'tcx>>,
|
||||
args: &[OperandRef<'tcx>],
|
||||
llresult: ValueRef,
|
||||
span: Span,
|
||||
) {
|
||||
let cx = bx.cx;
|
||||
let tcx = cx.tcx;
|
||||
|
||||
@ -545,7 +547,7 @@ pub fn codegen_intrinsic_call<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
assert_eq!(x.len(), 1);
|
||||
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::*;
|
||||
match *t {
|
||||
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) => {
|
||||
let t = llvm_elem.as_ref().unwrap_or(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) => {
|
||||
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
|
||||
// arguments to be truncated as needed and pointers to be
|
||||
// cast.
|
||||
fn modify_as_needed<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
t: &intrinsics::Type,
|
||||
arg: &OperandRef<'tcx>)
|
||||
-> Vec<ValueRef>
|
||||
fn modify_as_needed(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
t: &intrinsics::Type,
|
||||
arg: &OperandRef<'tcx>,
|
||||
) -> Vec<ValueRef>
|
||||
{
|
||||
match *t {
|
||||
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) => {
|
||||
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 => {
|
||||
// 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) => {
|
||||
let f = declare::declare_cfn(cx,
|
||||
name,
|
||||
Type::func(&inputs, &outputs));
|
||||
Type::func(&inputs, outputs));
|
||||
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>,
|
||||
allow_overlap: bool,
|
||||
volatile: bool,
|
||||
ty: Ty<'tcx>,
|
||||
dst: ValueRef,
|
||||
src: ValueRef,
|
||||
count: ValueRef)
|
||||
-> ValueRef {
|
||||
fn copy_intrinsic(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
allow_overlap: bool,
|
||||
volatile: bool,
|
||||
ty: Ty<'tcx>,
|
||||
dst: ValueRef,
|
||||
src: ValueRef,
|
||||
count: ValueRef,
|
||||
) -> ValueRef {
|
||||
let cx = bx.cx;
|
||||
let (size, align) = cx.size_and_align_of(ty);
|
||||
let size = C_usize(cx, size.bytes());
|
||||
@ -712,8 +716,8 @@ fn copy_intrinsic<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
None)
|
||||
}
|
||||
|
||||
fn memset_intrinsic<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
fn memset_intrinsic(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
volatile: bool,
|
||||
ty: Ty<'tcx>,
|
||||
dst: ValueRef,
|
||||
@ -728,8 +732,8 @@ fn memset_intrinsic<'a, 'tcx>(
|
||||
call_memset(bx, dst, val, bx.mul(size, count), align, volatile)
|
||||
}
|
||||
|
||||
fn try_intrinsic<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
fn try_intrinsic(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
cx: &CodegenCx,
|
||||
func: 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
|
||||
// writing, however, LLVM does not recommend the usage of these new instructions
|
||||
// as the old ones are still more optimized.
|
||||
fn codegen_msvc_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
cx: &CodegenCx,
|
||||
func: ValueRef,
|
||||
data: ValueRef,
|
||||
local_ptr: ValueRef,
|
||||
dest: ValueRef) {
|
||||
fn codegen_msvc_try(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
cx: &CodegenCx,
|
||||
func: ValueRef,
|
||||
data: ValueRef,
|
||||
local_ptr: ValueRef,
|
||||
dest: ValueRef,
|
||||
) {
|
||||
let llfn = get_rust_try_fn(cx, &mut |bx| {
|
||||
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
|
||||
// functions in play. By calling a shim we're guaranteed that our shim will have
|
||||
// the right personality function.
|
||||
fn codegen_gnu_try<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
cx: &CodegenCx,
|
||||
func: ValueRef,
|
||||
data: ValueRef,
|
||||
local_ptr: ValueRef,
|
||||
dest: ValueRef) {
|
||||
fn codegen_gnu_try(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
cx: &CodegenCx,
|
||||
func: ValueRef,
|
||||
data: ValueRef,
|
||||
local_ptr: ValueRef,
|
||||
dest: ValueRef,
|
||||
) {
|
||||
let llfn = get_rust_try_fn(cx, &mut |bx| {
|
||||
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.
|
||||
// This is currently primarily used for the `try` intrinsic functions above.
|
||||
fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
name: &str,
|
||||
inputs: Vec<Ty<'tcx>>,
|
||||
output: Ty<'tcx>,
|
||||
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
|
||||
-> ValueRef {
|
||||
fn gen_fn<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
name: &str,
|
||||
inputs: Vec<Ty<'tcx>>,
|
||||
output: Ty<'tcx>,
|
||||
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(
|
||||
inputs.into_iter(),
|
||||
output,
|
||||
@ -945,9 +954,10 @@ fn gen_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
// catch exceptions.
|
||||
//
|
||||
// This function is only generated once and is then cached.
|
||||
fn get_rust_try_fn<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
codegen: &mut dyn for<'b> FnMut(Builder<'b, 'tcx>))
|
||||
-> ValueRef {
|
||||
fn get_rust_try_fn<'ll, 'tcx>(
|
||||
cx: &CodegenCx<'ll, 'tcx>,
|
||||
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
|
||||
) -> ValueRef {
|
||||
if let Some(llfn) = cx.rust_try_fn.get() {
|
||||
return llfn;
|
||||
}
|
||||
@ -972,13 +982,13 @@ fn span_invalid_monomorphization_error(a: &Session, b: Span, c: &str) {
|
||||
span_err!(a, b, E0511, "{}", c);
|
||||
}
|
||||
|
||||
fn generic_simd_intrinsic<'a, 'tcx>(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
fn generic_simd_intrinsic(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
name: &str,
|
||||
callee_ty: Ty<'tcx>,
|
||||
args: &[OperandRef<'tcx>],
|
||||
ret_ty: Ty<'tcx>,
|
||||
llret_ty: Type,
|
||||
llret_ty: &'ll Type,
|
||||
span: Span
|
||||
) -> Result<ValueRef, ()> {
|
||||
// macros for error handling:
|
||||
@ -1145,19 +1155,20 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
||||
}
|
||||
// truncate the mask to a vector of i1s
|
||||
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);
|
||||
return Ok(bx.select(m_i1s, args[1].immediate(), args[2].immediate()));
|
||||
}
|
||||
|
||||
fn simd_simple_float_intrinsic<'a, 'tcx>(name: &str,
|
||||
in_elem: &::rustc::ty::TyS,
|
||||
in_ty: &::rustc::ty::TyS,
|
||||
in_len: usize,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
span: Span,
|
||||
args: &[OperandRef<'tcx>])
|
||||
-> Result<ValueRef, ()> {
|
||||
fn simd_simple_float_intrinsic(
|
||||
name: &str,
|
||||
in_elem: &::rustc::ty::TyS,
|
||||
in_ty: &::rustc::ty::TyS,
|
||||
in_len: usize,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
span: Span,
|
||||
args: &[OperandRef<'tcx>],
|
||||
) -> Result<ValueRef, ()> {
|
||||
macro_rules! emit_error {
|
||||
($msg: tt) => {
|
||||
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,
|
||||
mut no_pointers: usize) -> Type {
|
||||
fn llvm_vector_ty(cx: &CodegenCx<'ll, '_>, elem_ty: ty::Ty, vec_len: usize,
|
||||
mut no_pointers: usize) -> &'ll Type {
|
||||
// FIXME: use cx.layout_of(ty).llvm_type() ?
|
||||
let mut elem_ty = match elem_ty.sty {
|
||||
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();
|
||||
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:
|
||||
let (mask, mask_ty) = {
|
||||
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)
|
||||
};
|
||||
|
||||
@ -1395,7 +1406,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
||||
llvm_elem_vec_str, llvm_pointer_vec_str);
|
||||
let f = declare::declare_cfn(bx.cx, &llvm_intrinsic,
|
||||
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);
|
||||
let v = bx.call(f, &[args[1].immediate(), alignment, mask, args[0].immediate()],
|
||||
None);
|
||||
@ -1476,7 +1487,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
||||
// Truncate the mask vector to a vector of i1s:
|
||||
let (mask, mask_ty) = {
|
||||
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)
|
||||
};
|
||||
|
||||
@ -1496,7 +1507,7 @@ fn generic_simd_intrinsic<'a, 'tcx>(
|
||||
Type::func(&[llvm_elem_vec_ty,
|
||||
llvm_pointer_vec_ty,
|
||||
alignment_ty,
|
||||
mask_ty], &ret_t));
|
||||
mask_ty], ret_t));
|
||||
llvm::SetUnnamedAddr(f, false);
|
||||
let v = bx.call(f, &[args[0].immediate(), args[1].immediate(), alignment, mask],
|
||||
None);
|
||||
@ -1629,7 +1640,7 @@ unsupported {} from `{}` with element `{}` of size `{}` to `{}`"#,
|
||||
|
||||
// boolean reductions operate on vectors of i1s:
|
||||
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)
|
||||
};
|
||||
return match in_elem.sty {
|
||||
|
@ -377,8 +377,7 @@ pub enum ThreadLocalMode {
|
||||
// Opaque pointer types
|
||||
extern { pub type Module; }
|
||||
extern { pub type Context; }
|
||||
extern { pub type Type_opaque; }
|
||||
pub type TypeRef = *mut Type_opaque;
|
||||
extern { pub type Type; }
|
||||
extern { pub type Value_opaque; }
|
||||
pub type ValueRef = *mut Value_opaque;
|
||||
extern { pub type Metadata_opaque; }
|
||||
@ -517,55 +516,55 @@ extern "C" {
|
||||
pub fn LLVMRustAppendModuleInlineAsm(M: &Module, Asm: *const c_char);
|
||||
|
||||
/// See llvm::LLVMTypeKind::getTypeID.
|
||||
pub fn LLVMRustGetTypeKind(Ty: TypeRef) -> TypeKind;
|
||||
pub fn LLVMRustGetTypeKind(Ty: &Type) -> TypeKind;
|
||||
|
||||
// Operations on integer types
|
||||
pub fn LLVMInt1TypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMInt8TypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMInt16TypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMInt32TypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMInt64TypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMIntTypeInContext(C: &Context, NumBits: c_uint) -> TypeRef;
|
||||
pub fn LLVMInt1TypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMInt8TypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMInt16TypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMInt32TypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMInt64TypeInContext(C: &Context) -> &Type;
|
||||
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
|
||||
pub fn LLVMFloatTypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMDoubleTypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMFloatTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMDoubleTypeInContext(C: &Context) -> &Type;
|
||||
|
||||
// Operations on function types
|
||||
pub fn LLVMFunctionType(ReturnType: TypeRef,
|
||||
ParamTypes: *const TypeRef,
|
||||
pub fn LLVMFunctionType(ReturnType: &'a Type,
|
||||
ParamTypes: *const &'a Type,
|
||||
ParamCount: c_uint,
|
||||
IsVarArg: Bool)
|
||||
-> TypeRef;
|
||||
pub fn LLVMGetReturnType(FunctionTy: TypeRef) -> TypeRef;
|
||||
pub fn LLVMCountParamTypes(FunctionTy: TypeRef) -> c_uint;
|
||||
pub fn LLVMGetParamTypes(FunctionTy: TypeRef, Dest: *mut TypeRef);
|
||||
-> &'a Type;
|
||||
pub fn LLVMGetReturnType(FunctionTy: &Type) -> &Type;
|
||||
pub fn LLVMCountParamTypes(FunctionTy: &Type) -> c_uint;
|
||||
pub fn LLVMGetParamTypes(FunctionTy: &'a Type, Dest: *mut &'a Type);
|
||||
|
||||
// Operations on struct types
|
||||
pub fn LLVMStructTypeInContext(C: &Context,
|
||||
ElementTypes: *const TypeRef,
|
||||
pub fn LLVMStructTypeInContext(C: &'a Context,
|
||||
ElementTypes: *const &'a Type,
|
||||
ElementCount: c_uint,
|
||||
Packed: Bool)
|
||||
-> TypeRef;
|
||||
pub fn LLVMIsPackedStruct(StructTy: TypeRef) -> Bool;
|
||||
-> &'a Type;
|
||||
pub fn LLVMIsPackedStruct(StructTy: &Type) -> Bool;
|
||||
|
||||
// Operations on array, pointer, and vector types (sequence types)
|
||||
pub fn LLVMRustArrayType(ElementType: TypeRef, ElementCount: u64) -> TypeRef;
|
||||
pub fn LLVMPointerType(ElementType: TypeRef, AddressSpace: c_uint) -> TypeRef;
|
||||
pub fn LLVMVectorType(ElementType: TypeRef, ElementCount: c_uint) -> TypeRef;
|
||||
pub fn LLVMRustArrayType(ElementType: &Type, ElementCount: u64) -> &Type;
|
||||
pub fn LLVMPointerType(ElementType: &Type, AddressSpace: c_uint) -> &Type;
|
||||
pub fn LLVMVectorType(ElementType: &Type, ElementCount: c_uint) -> &Type;
|
||||
|
||||
pub fn LLVMGetElementType(Ty: TypeRef) -> TypeRef;
|
||||
pub fn LLVMGetVectorSize(VectorTy: TypeRef) -> c_uint;
|
||||
pub fn LLVMGetElementType(Ty: &Type) -> &Type;
|
||||
pub fn LLVMGetVectorSize(VectorTy: &Type) -> c_uint;
|
||||
|
||||
// Operations on other types
|
||||
pub fn LLVMVoidTypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMX86MMXTypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMRustMetadataTypeInContext(C: &Context) -> TypeRef;
|
||||
pub fn LLVMVoidTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMX86MMXTypeInContext(C: &Context) -> &Type;
|
||||
pub fn LLVMRustMetadataTypeInContext(C: &Context) -> &Type;
|
||||
|
||||
// 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 LLVMSetValueName(Val: ValueRef, Name: *const c_char);
|
||||
pub fn LLVMReplaceAllUsesWith(OldVal: ValueRef, NewVal: ValueRef);
|
||||
@ -580,10 +579,10 @@ extern "C" {
|
||||
pub fn LLVMGetOperand(Val: ValueRef, Index: c_uint) -> ValueRef;
|
||||
|
||||
// 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 LLVMConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef;
|
||||
pub fn LLVMGetUndef(Ty: TypeRef) -> ValueRef;
|
||||
pub fn LLVMGetUndef(Ty: &Type) -> ValueRef;
|
||||
|
||||
// Operations on metadata
|
||||
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);
|
||||
|
||||
// Operations on scalar constants
|
||||
pub fn LLVMConstInt(IntTy: TypeRef, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
|
||||
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: TypeRef, Wn: c_uint, Ws: *const u64) -> ValueRef;
|
||||
pub fn LLVMConstInt(IntTy: &Type, N: c_ulonglong, SignExtend: Bool) -> ValueRef;
|
||||
pub fn LLVMConstIntOfArbitraryPrecision(IntTy: &Type, Wn: c_uint, Ws: *const u64) -> ValueRef;
|
||||
pub fn LLVMConstIntGetZExtValue(ConstantVal: ValueRef) -> c_ulonglong;
|
||||
pub fn LLVMConstIntGetSExtValue(ConstantVal: ValueRef) -> c_longlong;
|
||||
pub fn LLVMRustConstInt128Get(ConstantVal: ValueRef, SExt: bool,
|
||||
@ -612,14 +611,14 @@ extern "C" {
|
||||
Packed: Bool)
|
||||
-> ValueRef;
|
||||
|
||||
pub fn LLVMConstArray(ElementTy: TypeRef,
|
||||
pub fn LLVMConstArray(ElementTy: &Type,
|
||||
ConstantVals: *const ValueRef,
|
||||
Length: c_uint)
|
||||
-> ValueRef;
|
||||
pub fn LLVMConstVector(ScalarConstantVals: *const ValueRef, Size: c_uint) -> ValueRef;
|
||||
|
||||
// Constant expressions
|
||||
pub fn LLVMSizeOf(Ty: TypeRef) -> ValueRef;
|
||||
pub fn LLVMSizeOf(Ty: &Type) -> ValueRef;
|
||||
pub fn LLVMConstNeg(ConstantVal: ValueRef) -> ValueRef;
|
||||
pub fn LLVMConstFNeg(ConstantVal: ValueRef) -> ValueRef;
|
||||
pub fn LLVMConstNot(ConstantVal: ValueRef) -> ValueRef;
|
||||
@ -651,23 +650,23 @@ extern "C" {
|
||||
ConstantIndices: *const ValueRef,
|
||||
NumIndices: c_uint,
|
||||
) -> ValueRef;
|
||||
pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: TypeRef, isSigned: Bool) -> ValueRef;
|
||||
pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: TypeRef) -> ValueRef;
|
||||
pub fn LLVMConstTrunc(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstZExt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstUIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstSIToFP(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstFPToUI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstFPToSI(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstPtrToInt(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstIntToPtr(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstBitCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstPointerCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstIntCast(ConstantVal: ValueRef, ToType: &Type, isSigned: Bool) -> ValueRef;
|
||||
pub fn LLVMConstFPCast(ConstantVal: ValueRef, ToType: &Type) -> ValueRef;
|
||||
pub fn LLVMConstExtractValue(AggConstant: ValueRef,
|
||||
IdxList: *const c_uint,
|
||||
NumIdx: c_uint)
|
||||
-> ValueRef;
|
||||
pub fn LLVMConstInlineAsm(Ty: TypeRef,
|
||||
pub fn LLVMConstInlineAsm(Ty: &Type,
|
||||
AsmString: *const c_char,
|
||||
Constraints: *const c_char,
|
||||
HasSideEffects: Bool,
|
||||
@ -690,9 +689,9 @@ extern "C" {
|
||||
|
||||
// Operations on global variables
|
||||
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 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 LLVMGetNextGlobal(GlobalVar: ValueRef) -> ValueRef;
|
||||
pub fn LLVMDeleteGlobal(GlobalVar: ValueRef);
|
||||
@ -706,13 +705,13 @@ extern "C" {
|
||||
pub fn LLVMSetTailCall(CallInst: ValueRef, IsTailCall: Bool);
|
||||
|
||||
// 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 LLVMGetFirstFunction(M: &Module) -> ValueRef;
|
||||
pub fn LLVMGetNextFunction(Fn: ValueRef) -> ValueRef;
|
||||
pub fn LLVMRustGetOrInsertFunction(M: &Module,
|
||||
Name: *const c_char,
|
||||
FunctionTy: TypeRef)
|
||||
FunctionTy: &Type)
|
||||
-> ValueRef;
|
||||
pub fn LLVMSetFunctionCallConv(Fn: ValueRef, CC: c_uint);
|
||||
pub fn LLVMRustAddAlignmentAttr(Fn: ValueRef, index: c_uint, bytes: u32);
|
||||
@ -801,7 +800,7 @@ extern "C" {
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildLandingPad(B: BuilderRef,
|
||||
Ty: TypeRef,
|
||||
Ty: &Type,
|
||||
PersFn: ValueRef,
|
||||
NumClauses: c_uint,
|
||||
Name: *const c_char)
|
||||
@ -989,7 +988,7 @@ extern "C" {
|
||||
pub fn LLVMRustSetHasUnsafeAlgebra(Instr: ValueRef);
|
||||
|
||||
// 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 LLVMBuildLoad(B: BuilderRef, PointerVal: ValueRef, Name: *const c_char) -> ValueRef;
|
||||
|
||||
@ -1024,98 +1023,98 @@ extern "C" {
|
||||
// Casts
|
||||
pub fn LLVMBuildTrunc(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildZExt(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildSExt(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildFPToUI(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildFPToSI(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildUIToFP(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildSIToFP(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildFPTrunc(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildFPExt(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildPtrToInt(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildIntToPtr(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildBitCast(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildZExtOrBitCast(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildSExtOrBitCast(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildTruncOrBitCast(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildCast(B: BuilderRef,
|
||||
Op: Opcode,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildPointerCast(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMRustBuildIntCast(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
IsSized: bool)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildFPCast(B: BuilderRef,
|
||||
Val: ValueRef,
|
||||
DestTy: TypeRef,
|
||||
DestTy: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
|
||||
@ -1134,7 +1133,7 @@ extern "C" {
|
||||
-> ValueRef;
|
||||
|
||||
// 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,
|
||||
Fn: ValueRef,
|
||||
Args: *const ValueRef,
|
||||
@ -1150,7 +1149,7 @@ extern "C" {
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildVAArg(B: BuilderRef,
|
||||
list: ValueRef,
|
||||
Ty: TypeRef,
|
||||
Ty: &Type,
|
||||
Name: *const c_char)
|
||||
-> ValueRef;
|
||||
pub fn LLVMBuildExtractElement(B: BuilderRef,
|
||||
@ -1347,15 +1346,15 @@ extern "C" {
|
||||
/// Print the pass timings since static dtors aren't picking them up.
|
||||
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,
|
||||
ElementTypes: *const TypeRef,
|
||||
pub fn LLVMStructSetBody(StructTy: &'a Type,
|
||||
ElementTypes: *const &'a Type,
|
||||
ElementCount: c_uint,
|
||||
Packed: Bool);
|
||||
|
||||
/// Prepares inline assembly.
|
||||
pub fn LLVMRustInlineAsm(Ty: TypeRef,
|
||||
pub fn LLVMRustInlineAsm(Ty: &Type,
|
||||
AsmString: *const c_char,
|
||||
Constraints: *const c_char,
|
||||
SideEffects: Bool,
|
||||
@ -1587,7 +1586,7 @@ extern "C" {
|
||||
pub fn LLVMRustDIBuilderCreateOpDeref() -> 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 LLVMIsAConstantInt(value_ref: ValueRef) -> ValueRef;
|
||||
|
@ -33,7 +33,7 @@ impl<'a, 'tcx> VirtualIndex {
|
||||
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,
|
||||
fn_ty: &FnType<'tcx, Ty<'tcx>>) -> ValueRef {
|
||||
// Load the data pointer from the object.
|
||||
@ -48,7 +48,7 @@ impl<'a, 'tcx> VirtualIndex {
|
||||
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.
|
||||
debug!("get_int({:?}, {:?})", Value(llvtable), self);
|
||||
|
||||
|
@ -22,7 +22,7 @@ use rustc::ty::layout::LayoutOf;
|
||||
use type_of::LayoutLlvmExt;
|
||||
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 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
|
||||
}
|
||||
|
||||
struct LocalAnalyzer<'mir, 'a: 'mir, 'tcx: 'a> {
|
||||
fx: &'mir FunctionCx<'a, 'tcx>,
|
||||
struct LocalAnalyzer<'mir, 'a: 'mir, 'll: 'a, 'tcx: 'll> {
|
||||
fx: &'mir FunctionCx<'a, 'll, 'tcx>,
|
||||
dominators: Dominators<mir::BasicBlock>,
|
||||
non_ssa_locals: BitVector<mir::Local>,
|
||||
// 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>
|
||||
}
|
||||
|
||||
impl<'mir, 'a, 'tcx> LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
fn new(fx: &'mir FunctionCx<'a, 'tcx>) -> LocalAnalyzer<'mir, 'a, 'tcx> {
|
||||
impl LocalAnalyzer<'mir, 'a, 'll, 'tcx> {
|
||||
fn new(fx: &'mir FunctionCx<'a, 'll, 'tcx>) -> Self {
|
||||
let invalid_location =
|
||||
mir::BasicBlock::new(fx.mir.basic_blocks().len()).start_location();
|
||||
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,
|
||||
block: mir::BasicBlock,
|
||||
place: &mir::Place<'tcx>,
|
||||
|
@ -33,7 +33,7 @@ use super::place::PlaceRef;
|
||||
use super::operand::OperandRef;
|
||||
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) {
|
||||
let mut bx = self.build_block(bb);
|
||||
let data = &self.mir[bb];
|
||||
@ -48,7 +48,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn codegen_terminator(&mut self,
|
||||
mut bx: Builder<'a, 'tcx>,
|
||||
mut bx: Builder<'a, 'll, 'tcx>,
|
||||
bb: mir::BasicBlock,
|
||||
terminator: &mir::Terminator<'tcx>)
|
||||
{
|
||||
@ -110,7 +110,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
|
||||
let do_call = |
|
||||
this: &mut Self,
|
||||
bx: Builder<'a, 'tcx>,
|
||||
bx: Builder<'a, 'll, 'tcx>,
|
||||
fn_ty: FnType<'tcx, Ty<'tcx>>,
|
||||
fn_ptr: ValueRef,
|
||||
llargs: &[ValueRef],
|
||||
@ -627,7 +627,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn codegen_argument(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
op: OperandRef<'tcx>,
|
||||
llargs: &mut Vec<ValueRef>,
|
||||
arg: &ArgType<'tcx, Ty<'tcx>>) {
|
||||
@ -706,7 +706,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn codegen_arguments_untupled(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
operand: &mir::Operand<'tcx>,
|
||||
llargs: &mut Vec<ValueRef>,
|
||||
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;
|
||||
if let Some(slot) = self.personality_slot {
|
||||
slot
|
||||
@ -777,7 +777,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
bx.llbb()
|
||||
}
|
||||
|
||||
fn landing_pad_type(&self) -> Type {
|
||||
fn landing_pad_type(&self) -> &'ll Type {
|
||||
let cx = self.cx;
|
||||
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)
|
||||
}
|
||||
|
||||
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);
|
||||
bx.position_at_end(self.blocks[bb]);
|
||||
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>>,
|
||||
llargs: &mut Vec<ValueRef>, is_intrinsic: bool)
|
||||
-> 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>,
|
||||
dst: &mir::Place<'tcx>) {
|
||||
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>,
|
||||
dst: PlaceRef<'tcx>) {
|
||||
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.
|
||||
fn store_return(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
dest: ReturnDest<'tcx>,
|
||||
ret_ty: &ArgType<'tcx, Ty<'tcx>>,
|
||||
llval: ValueRef) {
|
||||
|
@ -33,7 +33,7 @@ use super::FunctionCx;
|
||||
pub fn scalar_to_llvm(cx: &CodegenCx,
|
||||
cv: Scalar,
|
||||
layout: &layout::Scalar,
|
||||
llty: Type) -> ValueRef {
|
||||
llty: &Type) -> ValueRef {
|
||||
let bitsize = if layout.is_bool() { 1 } else { layout.value.size(cx).bits() };
|
||||
match cv {
|
||||
Scalar::Bits { defined, .. } if (defined as u64) < bitsize || defined == 0 => {
|
||||
@ -42,7 +42,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
|
||||
Scalar::Bits { bits, .. } => {
|
||||
let llval = C_uint_big(Type::ix(cx, bitsize), bits);
|
||||
if layout.value == layout::Pointer {
|
||||
unsafe { llvm::LLVMConstIntToPtr(llval, llty.to_ref()) }
|
||||
unsafe { llvm::LLVMConstIntToPtr(llval, llty) }
|
||||
} else {
|
||||
consts::bitcast(llval, llty)
|
||||
}
|
||||
@ -73,7 +73,7 @@ pub fn scalar_to_llvm(cx: &CodegenCx,
|
||||
1,
|
||||
) };
|
||||
if layout.value != layout::Pointer {
|
||||
unsafe { llvm::LLVMConstPtrToInt(llval, llty.to_ref()) }
|
||||
unsafe { llvm::LLVMConstPtrToInt(llval, llty) }
|
||||
} else {
|
||||
consts::bitcast(llval, llty)
|
||||
}
|
||||
@ -135,10 +135,10 @@ pub fn codegen_static_initializer<'a, 'tcx>(
|
||||
Ok((const_alloc_to_llvm(cx, alloc), alloc))
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
impl FunctionCx<'a, 'll, 'tcx> {
|
||||
fn fully_evaluate(
|
||||
&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
constant: &'tcx ty::Const<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||
match constant.val {
|
||||
@ -158,7 +158,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
|
||||
pub fn eval_mir_constant(
|
||||
&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
constant: &mir::Constant<'tcx>,
|
||||
) -> Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||
let c = self.monomorphize(&constant.literal);
|
||||
@ -168,7 +168,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
/// process constant containing SIMD shuffle indices
|
||||
pub fn simd_shuffle_indices(
|
||||
&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
span: Span,
|
||||
ty: Ty<'tcx>,
|
||||
constant: Result<&'tcx ty::Const<'tcx>, Lrc<ConstEvalErr<'tcx>>>,
|
||||
|
@ -43,7 +43,7 @@ use rustc::mir::traversal;
|
||||
use self::operand::{OperandRef, OperandValue};
|
||||
|
||||
/// Master context for codegenning from MIR.
|
||||
pub struct FunctionCx<'a, 'tcx:'a> {
|
||||
pub struct FunctionCx<'a, 'll: 'a, 'tcx: 'll> {
|
||||
instance: Instance<'tcx>,
|
||||
|
||||
mir: &'a mir::Mir<'tcx>,
|
||||
@ -52,7 +52,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
|
||||
|
||||
llfn: ValueRef,
|
||||
|
||||
cx: &'a CodegenCx<'a, 'tcx>,
|
||||
cx: &'a CodegenCx<'ll, 'tcx>,
|
||||
|
||||
fn_ty: FnType<'tcx, Ty<'tcx>>,
|
||||
|
||||
@ -106,7 +106,7 @@ pub struct FunctionCx<'a, 'tcx:'a> {
|
||||
param_substs: &'tcx Substs<'tcx>,
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
impl FunctionCx<'a, 'll, 'tcx> {
|
||||
pub fn monomorphize<T>(&self, value: &T) -> T
|
||||
where T: TypeFoldable<'tcx>
|
||||
{
|
||||
@ -198,8 +198,8 @@ impl<'a, 'tcx> LocalRef<'tcx> {
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
pub fn codegen_mir<'a, 'tcx: 'a>(
|
||||
cx: &'a CodegenCx<'a, 'tcx>,
|
||||
pub fn codegen_mir(
|
||||
cx: &'a CodegenCx<'ll, 'tcx>,
|
||||
llfn: ValueRef,
|
||||
mir: &'a Mir<'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>,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
cleanup_kinds: &IndexVec<mir::BasicBlock, CleanupKind>,
|
||||
block_bxs: &IndexVec<mir::BasicBlock, BasicBlockRef>)
|
||||
-> (IndexVec<mir::BasicBlock, Option<BasicBlockRef>>,
|
||||
@ -413,11 +413,12 @@ fn create_funclets<'a, 'tcx>(
|
||||
/// Produce, for each argument, a `ValueRef` pointing at the
|
||||
/// argument's value. As arguments are places, these are always
|
||||
/// indirect.
|
||||
fn arg_local_refs<'a, 'tcx>(bx: &Builder<'a, 'tcx>,
|
||||
fx: &FunctionCx<'a, 'tcx>,
|
||||
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
|
||||
memory_locals: &BitVector<mir::Local>)
|
||||
-> Vec<LocalRef<'tcx>> {
|
||||
fn arg_local_refs(
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
fx: &FunctionCx<'a, 'll, 'tcx>,
|
||||
scopes: &IndexVec<mir::SourceScope, debuginfo::MirDebugScope>,
|
||||
memory_locals: &BitVector<mir::Local>,
|
||||
) -> Vec<LocalRef<'tcx>> {
|
||||
let mir = fx.mir;
|
||||
let tcx = bx.tcx();
|
||||
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>)
|
||||
-> Result<OperandRef<'tcx>, Lrc<ConstEvalErr<'tcx>>> {
|
||||
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.
|
||||
/// 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 {
|
||||
let llty = self.layout.llvm_type(bx.cx);
|
||||
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`.
|
||||
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,
|
||||
layout: TyLayout<'tcx>)
|
||||
-> OperandRef<'tcx> {
|
||||
@ -208,7 +208,7 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
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 offset = self.layout.fields.offset(i);
|
||||
|
||||
@ -267,23 +267,23 @@ impl<'a, 'tcx> OperandRef<'tcx> {
|
||||
}
|
||||
|
||||
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());
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
// 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.
|
||||
@ -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,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
place: &mir::Place<'tcx>)
|
||||
-> Option<OperandRef<'tcx>>
|
||||
{
|
||||
@ -360,7 +360,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn codegen_consume(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
place: &mir::Place<'tcx>)
|
||||
-> OperandRef<'tcx>
|
||||
{
|
||||
@ -384,7 +384,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn codegen_operand(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
operand: &mir::Operand<'tcx>)
|
||||
-> OperandRef<'tcx>
|
||||
{
|
||||
|
@ -56,7 +56,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
}
|
||||
|
||||
pub fn from_const_alloc(
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
layout: TyLayout<'tcx>,
|
||||
alloc: &mir::interpret::Allocation,
|
||||
offset: Size,
|
||||
@ -73,7 +73,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
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> {
|
||||
debug!("alloca({:?}: {:?})", name, layout);
|
||||
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()
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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.
|
||||
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 field = self.layout.field(cx, ix);
|
||||
let offset = self.layout.fields.offset(ix);
|
||||
@ -266,7 +266,7 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
}
|
||||
|
||||
/// 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);
|
||||
if self.layout.abi == layout::Abi::Uninhabited {
|
||||
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
|
||||
/// 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 {
|
||||
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 {
|
||||
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> {
|
||||
let mut downcast = *self;
|
||||
downcast.layout = self.layout.for_variant(bx.cx, variant_index);
|
||||
@ -406,18 +406,18 @@ impl<'a, 'tcx> PlaceRef<'tcx> {
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
impl FunctionCx<'a, 'll, 'tcx> {
|
||||
pub fn codegen_place(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
place: &mir::Place<'tcx>)
|
||||
-> PlaceRef<'tcx> {
|
||||
debug!("codegen_place(place={:?})", place);
|
||||
|
@ -32,12 +32,12 @@ use super::{FunctionCx, LocalRef};
|
||||
use super::operand::{OperandRef, OperandValue};
|
||||
use super::place::PlaceRef;
|
||||
|
||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
impl FunctionCx<'a, 'll, 'tcx> {
|
||||
pub fn codegen_rvalue(&mut self,
|
||||
bx: Builder<'a, 'tcx>,
|
||||
bx: Builder<'a, 'll, 'tcx>,
|
||||
dest: PlaceRef<'tcx>,
|
||||
rvalue: &mir::Rvalue<'tcx>)
|
||||
-> Builder<'a, 'tcx>
|
||||
-> Builder<'a, 'll, 'tcx>
|
||||
{
|
||||
debug!("codegen_rvalue(dest.llval={:?}, rvalue={:?})",
|
||||
Value(dest.llval), rvalue);
|
||||
@ -176,9 +176,9 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn codegen_rvalue_operand(&mut self,
|
||||
bx: Builder<'a, 'tcx>,
|
||||
bx: Builder<'a, 'll, '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);
|
||||
|
||||
@ -512,7 +512,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
fn evaluate_array_len(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
place: &mir::Place<'tcx>) -> ValueRef
|
||||
{
|
||||
// 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,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
op: mir::BinOp,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
@ -597,7 +597,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn codegen_fat_ptr_binop(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
op: mir::BinOp,
|
||||
lhs_addr: ValueRef,
|
||||
lhs_extra: ValueRef,
|
||||
@ -644,7 +644,7 @@ impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
}
|
||||
|
||||
pub fn codegen_scalar_checked_binop(&mut self,
|
||||
bx: &Builder<'a, 'tcx>,
|
||||
bx: &Builder<'a, 'll, 'tcx>,
|
||||
op: mir::BinOp,
|
||||
lhs: ValueRef,
|
||||
rhs: ValueRef,
|
||||
@ -796,11 +796,11 @@ fn get_overflow_intrinsic(oop: OverflowOp, bx: &Builder, ty: Ty) -> ValueRef {
|
||||
bx.cx.get_intrinsic(&name)
|
||||
}
|
||||
|
||||
fn cast_int_to_float(bx: &Builder,
|
||||
fn cast_int_to_float(bx: &Builder<'_, 'll, '_>,
|
||||
signed: bool,
|
||||
x: ValueRef,
|
||||
int_ty: Type,
|
||||
float_ty: Type) -> ValueRef {
|
||||
int_ty: &'ll Type,
|
||||
float_ty: &'ll Type) -> ValueRef {
|
||||
// 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).
|
||||
// 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,
|
||||
x: ValueRef,
|
||||
float_ty: Type,
|
||||
int_ty: Type) -> ValueRef {
|
||||
float_ty: &'ll Type,
|
||||
int_ty: &'ll Type) -> ValueRef {
|
||||
let fptosui_result = if signed {
|
||||
bx.fptosi(x, int_ty)
|
||||
} 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
|
||||
// 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.
|
||||
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);
|
||||
assert_eq!(rounded_min.status, Status::OK);
|
||||
let rounded_max = F::from_u128_r(int_max(signed, int_ty), Round::TowardZero);
|
||||
assert!(rounded_max.value.is_finite());
|
||||
(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();
|
||||
if signed {
|
||||
i128::MAX as u128 >> shift_amount
|
||||
@ -874,7 +874,7 @@ fn cast_float_to_int(bx: &Builder,
|
||||
u128::MAX >> shift_amount
|
||||
}
|
||||
}
|
||||
fn int_min(signed: bool, int_ty: Type) -> i128 {
|
||||
fn int_min(signed: bool, int_ty: &Type) -> i128 {
|
||||
if signed {
|
||||
i128::MIN >> (128 - int_ty.int_width())
|
||||
} else {
|
||||
|
@ -16,11 +16,11 @@ use builder::Builder;
|
||||
use super::FunctionCx;
|
||||
use super::LocalRef;
|
||||
|
||||
impl<'a, 'tcx> FunctionCx<'a, 'tcx> {
|
||||
impl FunctionCx<'a, 'll, 'tcx> {
|
||||
pub fn codegen_statement(&mut self,
|
||||
bx: Builder<'a, 'tcx>,
|
||||
bx: Builder<'a, 'll, 'tcx>,
|
||||
statement: &mir::Statement<'tcx>)
|
||||
-> Builder<'a, 'tcx> {
|
||||
-> Builder<'a, 'll, 'tcx> {
|
||||
debug!("codegen_statement(statement={:?})", statement);
|
||||
|
||||
self.set_debug_loc(&bx, statement.source_info);
|
||||
|
@ -10,8 +10,10 @@
|
||||
|
||||
#![allow(non_upper_case_globals)]
|
||||
|
||||
pub use llvm::Type;
|
||||
|
||||
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 context::CodegenCx;
|
||||
@ -21,121 +23,125 @@ use rustc::ty::layout::{self, Align, Size};
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::fmt;
|
||||
use std::mem;
|
||||
|
||||
use libc::c_uint;
|
||||
|
||||
#[derive(Clone, Copy, PartialEq)]
|
||||
#[repr(C)]
|
||||
pub struct Type {
|
||||
rf: TypeRef
|
||||
impl PartialEq for Type {
|
||||
fn eq(&self, other: &Self) -> bool {
|
||||
self as *const _ == other as *const _
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Debug for Type {
|
||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||
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"))
|
||||
}
|
||||
}
|
||||
|
||||
macro_rules! ty {
|
||||
($e:expr) => ( Type::from_ref(unsafe { $e }))
|
||||
}
|
||||
|
||||
/// Wrapper for LLVM TypeRef
|
||||
impl Type {
|
||||
#[inline(always)]
|
||||
pub fn from_ref(r: TypeRef) -> Type {
|
||||
Type {
|
||||
rf: r
|
||||
pub fn void(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMVoidTypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
#[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler
|
||||
pub fn to_ref(&self) -> TypeRef {
|
||||
self.rf
|
||||
pub fn metadata(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMRustMetadataTypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_ref_slice(slice: &[Type]) -> &[TypeRef] {
|
||||
unsafe { mem::transmute(slice) }
|
||||
pub fn i1(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMInt1TypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn void(cx: &CodegenCx) -> Type {
|
||||
ty!(llvm::LLVMVoidTypeInContext(cx.llcx))
|
||||
pub fn i8(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMInt8TypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn metadata(cx: &CodegenCx) -> Type {
|
||||
ty!(llvm::LLVMRustMetadataTypeInContext(cx.llcx))
|
||||
pub fn i8_llcx(llcx: &llvm::Context) -> &Type {
|
||||
unsafe {
|
||||
llvm::LLVMInt8TypeInContext(llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn i1(cx: &CodegenCx) -> Type {
|
||||
ty!(llvm::LLVMInt1TypeInContext(cx.llcx))
|
||||
pub fn i16(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMInt16TypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn i8(cx: &CodegenCx) -> Type {
|
||||
ty!(llvm::LLVMInt8TypeInContext(cx.llcx))
|
||||
pub fn i32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMInt32TypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn i8_llcx(llcx: &llvm::Context) -> Type {
|
||||
ty!(llvm::LLVMInt8TypeInContext(llcx))
|
||||
pub fn i64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMInt64TypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn i16(cx: &CodegenCx) -> Type {
|
||||
ty!(llvm::LLVMInt16TypeInContext(cx.llcx))
|
||||
}
|
||||
|
||||
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))
|
||||
pub fn i128(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMIntTypeInContext(cx.llcx, 128)
|
||||
}
|
||||
}
|
||||
|
||||
// Creates an integer type with the given number of bits, e.g. i24
|
||||
pub fn ix(cx: &CodegenCx, num_bits: u64) -> Type {
|
||||
ty!(llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint))
|
||||
pub fn ix(cx: &CodegenCx<'ll, '_>, num_bits: u64) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMIntTypeInContext(cx.llcx, num_bits as c_uint)
|
||||
}
|
||||
}
|
||||
|
||||
// Creates an integer type with the given number of bits, e.g. i24
|
||||
pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> Type {
|
||||
ty!(llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint))
|
||||
pub fn ix_llcx(llcx: &llvm::Context, num_bits: u64) -> &Type {
|
||||
unsafe {
|
||||
llvm::LLVMIntTypeInContext(llcx, num_bits as c_uint)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn f32(cx: &CodegenCx) -> Type {
|
||||
ty!(llvm::LLVMFloatTypeInContext(cx.llcx))
|
||||
pub fn f32(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMFloatTypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn f64(cx: &CodegenCx) -> Type {
|
||||
ty!(llvm::LLVMDoubleTypeInContext(cx.llcx))
|
||||
pub fn f64(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMDoubleTypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn bool(cx: &CodegenCx) -> Type {
|
||||
pub fn bool(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
Type::i8(cx)
|
||||
}
|
||||
|
||||
pub fn char(cx: &CodegenCx) -> Type {
|
||||
pub fn char(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
Type::i32(cx)
|
||||
}
|
||||
|
||||
pub fn i8p(cx: &CodegenCx) -> Type {
|
||||
pub fn i8p(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
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()
|
||||
}
|
||||
|
||||
pub fn isize(cx: &CodegenCx) -> Type {
|
||||
pub fn isize(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
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[..] {
|
||||
"16" => Type::i16(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 {
|
||||
ast::IntTy::Isize => cx.isize_ty,
|
||||
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 {
|
||||
ast::UintTy::Usize => cx.isize_ty,
|
||||
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 {
|
||||
ast::FloatTy::F32 => Type::f32(cx),
|
||||
ast::FloatTy::F64 => Type::f64(cx),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn func(args: &[Type], ret: &Type) -> Type {
|
||||
let slice: &[TypeRef] = Type::to_ref_slice(args);
|
||||
ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
|
||||
args.len() as c_uint, False))
|
||||
pub fn func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
||||
args.len() as c_uint, False)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn variadic_func(args: &[Type], ret: &Type) -> Type {
|
||||
let slice: &[TypeRef] = Type::to_ref_slice(args);
|
||||
ty!(llvm::LLVMFunctionType(ret.to_ref(), slice.as_ptr(),
|
||||
args.len() as c_uint, True))
|
||||
pub fn variadic_func(args: &[&'ll Type], ret: &'ll Type) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMFunctionType(ret, args.as_ptr(),
|
||||
args.len() as c_uint, True)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn struct_(cx: &CodegenCx, els: &[Type], packed: bool) -> Type {
|
||||
let els: &[TypeRef] = Type::to_ref_slice(els);
|
||||
ty!(llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
|
||||
pub fn struct_(cx: &CodegenCx<'ll, '_>, els: &[&'ll Type], packed: bool) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMStructTypeInContext(cx.llcx, els.as_ptr(),
|
||||
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();
|
||||
ty!(llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr()))
|
||||
unsafe {
|
||||
llvm::LLVMStructCreateNamed(cx.llcx, name.as_ptr())
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
pub fn array(ty: &Type, len: u64) -> Type {
|
||||
ty!(llvm::LLVMRustArrayType(ty.to_ref(), len))
|
||||
pub fn array(ty: &Type, len: u64) -> &Type {
|
||||
unsafe {
|
||||
llvm::LLVMRustArrayType(ty, len)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vector(ty: &Type, len: u64) -> Type {
|
||||
ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint))
|
||||
pub fn vector(ty: &Type, len: u64) -> &Type {
|
||||
unsafe {
|
||||
llvm::LLVMVectorType(ty, len as c_uint)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn kind(&self) -> TypeKind {
|
||||
unsafe {
|
||||
llvm::LLVMRustGetTypeKind(self.to_ref())
|
||||
llvm::LLVMRustGetTypeKind(self)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_struct_body(&mut self, els: &[Type], packed: bool) {
|
||||
let slice: &[TypeRef] = Type::to_ref_slice(els);
|
||||
pub fn set_struct_body(&'ll self, els: &[&'ll Type], packed: bool) {
|
||||
unsafe {
|
||||
llvm::LLVMStructSetBody(self.to_ref(), slice.as_ptr(),
|
||||
llvm::LLVMStructSetBody(self, els.as_ptr(),
|
||||
els.len() as c_uint, packed as Bool)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ptr_to(&self) -> Type {
|
||||
ty!(llvm::LLVMPointerType(self.to_ref(), 0))
|
||||
pub fn ptr_to(&self) -> &Type {
|
||||
unsafe {
|
||||
llvm::LLVMPointerType(self, 0)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn element_type(&self) -> Type {
|
||||
pub fn element_type(&self) -> &Type {
|
||||
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.
|
||||
pub fn vector_length(&self) -> usize {
|
||||
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 {
|
||||
let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as usize;
|
||||
let mut args = vec![Type { rf: 0 as *mut _ }; n_args];
|
||||
llvm::LLVMGetParamTypes(self.to_ref(),
|
||||
args.as_mut_ptr() as *mut TypeRef);
|
||||
let n_args = llvm::LLVMCountParamTypes(self) as usize;
|
||||
let mut args = Vec::with_capacity(n_args);
|
||||
llvm::LLVMGetParamTypes(self, args.as_mut_ptr());
|
||||
args.set_len(n_args);
|
||||
args
|
||||
}
|
||||
}
|
||||
@ -260,11 +276,11 @@ impl Type {
|
||||
/// Retrieve the bit width of the integer type `self`.
|
||||
pub fn int_width(&self) -> u64 {
|
||||
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::*;
|
||||
match i {
|
||||
I8 => Type::i8(cx),
|
||||
@ -277,7 +293,7 @@ impl Type {
|
||||
|
||||
/// Return a LLVM type that has at most the required alignment,
|
||||
/// 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.
|
||||
let ity = layout::Integer::approximate_abi_align(cx, align);
|
||||
Type::from_integer(cx, ity)
|
||||
@ -285,15 +301,17 @@ impl Type {
|
||||
|
||||
/// Return a LLVM type that has at most the required alignment,
|
||||
/// 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 size = size.bytes();
|
||||
let unit_size = unit.size().bytes();
|
||||
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 {
|
||||
ty!(llvm::LLVMX86MMXTypeInContext(cx.llcx))
|
||||
pub fn x86_mmx(cx: &CodegenCx<'ll, '_>) -> &'ll Type {
|
||||
unsafe {
|
||||
llvm::LLVMX86MMXTypeInContext(cx.llcx)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -23,8 +23,8 @@ use std::fmt::Write;
|
||||
|
||||
fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
layout: TyLayout<'tcx>,
|
||||
defer: &mut Option<(Type, TyLayout<'tcx>)>)
|
||||
-> Type {
|
||||
defer: &mut Option<(&'a Type, TyLayout<'tcx>)>)
|
||||
-> &'a Type {
|
||||
match layout.abi {
|
||||
layout::Abi::Scalar(_) => bug!("handled elsewhere"),
|
||||
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)
|
||||
} else {
|
||||
let element = layout.scalar_llvm_type_at(cx, element, Size::ZERO);
|
||||
return Type::vector(&element, count);
|
||||
return Type::vector(element, count);
|
||||
}
|
||||
}
|
||||
layout::Abi::ScalarPair(..) => {
|
||||
@ -96,7 +96,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
|
||||
}
|
||||
}
|
||||
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 { .. } => {
|
||||
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>,
|
||||
layout: TyLayout<'tcx>)
|
||||
-> (Vec<Type>, bool) {
|
||||
-> (Vec<&'a Type>, bool) {
|
||||
debug!("struct_llfields: {:#?}", layout);
|
||||
let field_count = layout.fields.count();
|
||||
|
||||
let mut packed = false;
|
||||
let mut offset = Size::ZERO;
|
||||
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() {
|
||||
let field = layout.field(cx, i);
|
||||
packed |= layout.align.abi() < field.align.abi();
|
||||
@ -201,12 +201,12 @@ pub struct PointeeInfo {
|
||||
pub trait LayoutLlvmExt<'tcx> {
|
||||
fn is_llvm_immediate(&self) -> bool;
|
||||
fn is_llvm_scalar_pair<'a>(&self) -> bool;
|
||||
fn llvm_type<'a>(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
|
||||
fn immediate_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>) -> &'a Type;
|
||||
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>,
|
||||
index: usize, immediate: bool) -> Type;
|
||||
index: usize, immediate: bool) -> &'a Type;
|
||||
fn llvm_field_index(&self, index: usize) -> u64;
|
||||
fn pointee_info_at<'a>(&self, cx: &CodegenCx<'a, 'tcx>, offset: Size)
|
||||
-> Option<PointeeInfo>;
|
||||
@ -244,7 +244,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
||||
/// with the inner-most trailing unsized field using the "minimal unit"
|
||||
/// of that field's type - this is useful for taking the address of
|
||||
/// 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 {
|
||||
// Use a different cache for scalars because pointers to DSTs
|
||||
// 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);
|
||||
|
||||
if let Some((mut llty, layout)) = defer {
|
||||
if let Some((llty, layout)) = defer {
|
||||
let (llfields, packed) = struct_llfields(cx, layout);
|
||||
llty.set_struct_body(&llfields, packed)
|
||||
}
|
||||
@ -312,7 +312,7 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
|
||||
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 scalar.is_bool() {
|
||||
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>,
|
||||
scalar: &layout::Scalar, offset: Size) -> Type {
|
||||
scalar: &layout::Scalar, offset: Size) -> &'a Type {
|
||||
match scalar.value {
|
||||
layout::Int(i, _) => Type::from_integer(cx, i),
|
||||
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>,
|
||||
index: usize, immediate: bool) -> Type {
|
||||
index: usize, immediate: bool) -> &'a Type {
|
||||
// HACK(eddyb) special-case fat pointers until LLVM removes
|
||||
// pointee types, to avoid bitcasting every `OperandRef::deref`.
|
||||
match self.ty.sty {
|
||||
|
Loading…
Reference in New Issue
Block a user