Skip to content

Commit

Permalink
Auto merge of #52461 - irinagpopa:safe-llvm, r=nikomatsakis
Browse files Browse the repository at this point in the history
 rustc_codegen_llvm: use safe references for LLVM FFI types.

Part of #45274.
  • Loading branch information
bors committed Jul 31, 2018
2 parents ed8d14d + baff67d commit f898179
Show file tree
Hide file tree
Showing 51 changed files with 3,982 additions and 4,321 deletions.
3 changes: 0 additions & 3 deletions src/Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2222,11 +2222,8 @@ dependencies = [
name = "rustc_llvm"
version = "0.0.0"
dependencies = [
"bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"build_helper 0.1.0",
"cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
"rustc_cratesio_shim 0.0.0",
]

[[package]]
Expand Down
77 changes: 39 additions & 38 deletions src/librustc_codegen_llvm/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use llvm::{self, ValueRef, AttributePlace};
use llvm::{self, AttributePlace};
use base;
use builder::{Builder, MemFlags};
use common::{ty_fn_sig, C_usize};
Expand All @@ -17,6 +17,7 @@ use mir::place::PlaceRef;
use mir::operand::OperandValue;
use type_::Type;
use type_of::{LayoutLlvmExt, PointerKind};
use value::Value;

use rustc_target::abi::{LayoutOf, Size, TyLayout};
use rustc::ty::{self, Ty};
Expand Down Expand Up @@ -46,12 +47,12 @@ impl ArgAttributeExt for ArgAttribute {
}

pub trait ArgAttributesExt {
fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef);
fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef);
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value);
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value);
}

impl ArgAttributesExt for ArgAttributes {
fn apply_llfn(&self, idx: AttributePlace, llfn: ValueRef) {
fn apply_llfn(&self, idx: AttributePlace, llfn: &Value) {
let mut regular = self.regular;
unsafe {
let deref = self.pointee_size.bytes();
Expand All @@ -76,7 +77,7 @@ impl ArgAttributesExt for ArgAttributes {
}
}

fn apply_callsite(&self, idx: AttributePlace, callsite: ValueRef) {
fn apply_callsite(&self, idx: AttributePlace, callsite: &Value) {
let mut regular = self.regular;
unsafe {
let deref = self.pointee_size.bytes();
Expand All @@ -103,11 +104,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 => {
Expand All @@ -118,14 +119,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)
Expand All @@ -142,7 +143,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);
}
}

Expand All @@ -164,24 +165,24 @@ 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>);
pub trait ArgTypeExt<'ll, 'tcx> {
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
fn store(&self, bx: &Builder<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>);
fn store_fn_arg(&self, bx: &Builder<'_, 'll, 'tcx>, idx: &mut usize, dst: PlaceRef<'ll, 'tcx>);
}

impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
impl ArgTypeExt<'ll, '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<'ll, 'tcx>) -> &'ll Type {
self.layout.llvm_type(cx)
}

/// Store a direct/indirect value described by this ArgType into a
/// 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<'_, 'll, 'tcx>, val: &'ll Value, dst: PlaceRef<'ll, 'tcx>) {
if self.is_ignore() {
return;
}
Expand Down Expand Up @@ -234,7 +235,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<'ll, 'tcx>) {
let mut next = || {
let val = llvm::get_param(bx.llfn(), *idx as c_uint);
*idx += 1;
Expand All @@ -252,48 +253,48 @@ impl<'a, 'tcx> ArgTypeExt<'a, 'tcx> for ArgType<'tcx, Ty<'tcx>> {
}
}

pub trait FnTypeExt<'a, 'tcx> {
fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>)
pub trait FnTypeExt<'tcx> {
fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>)
-> Self;
fn new(cx: &CodegenCx<'a, 'tcx>,
fn new(cx: &CodegenCx<'ll, 'tcx>,
sig: ty::FnSig<'tcx>,
extra_args: &[Ty<'tcx>]) -> Self;
fn new_vtable(cx: &CodegenCx<'a, 'tcx>,
fn new_vtable(cx: &CodegenCx<'ll, 'tcx>,
sig: ty::FnSig<'tcx>,
extra_args: &[Ty<'tcx>]) -> Self;
fn new_internal(
cx: &CodegenCx<'a, 'tcx>,
cx: &CodegenCx<'ll, 'tcx>,
sig: ty::FnSig<'tcx>,
extra_args: &[Ty<'tcx>],
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
) -> Self;
fn adjust_for_abi(&mut self,
cx: &CodegenCx<'a, 'tcx>,
cx: &CodegenCx<'ll, 'tcx>,
abi: Abi);
fn llvm_type(&self, cx: &CodegenCx<'a, 'tcx>) -> Type;
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll 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_llfn(&self, llfn: &'ll Value);
fn apply_attrs_callsite(&self, bx: &Builder<'a, 'll, 'tcx>, callsite: &'ll Value);
}

impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
fn of_instance(cx: &CodegenCx<'a, 'tcx>, instance: &ty::Instance<'tcx>)
impl<'tcx> FnTypeExt<'tcx> for FnType<'tcx, Ty<'tcx>> {
fn of_instance(cx: &CodegenCx<'ll, 'tcx>, instance: &ty::Instance<'tcx>)
-> Self {
let fn_ty = instance.ty(cx.tcx);
let sig = ty_fn_sig(cx, fn_ty);
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
FnType::new(cx, sig, &[])
}

fn new(cx: &CodegenCx<'a, 'tcx>,
fn new(cx: &CodegenCx<'ll, 'tcx>,
sig: ty::FnSig<'tcx>,
extra_args: &[Ty<'tcx>]) -> Self {
FnType::new_internal(cx, sig, extra_args, |ty, _| {
ArgType::new(cx.layout_of(ty))
})
}

fn new_vtable(cx: &CodegenCx<'a, 'tcx>,
fn new_vtable(cx: &CodegenCx<'ll, 'tcx>,
sig: ty::FnSig<'tcx>,
extra_args: &[Ty<'tcx>]) -> Self {
FnType::new_internal(cx, sig, extra_args, |ty, arg_idx| {
Expand All @@ -316,7 +317,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
}

fn new_internal(
cx: &CodegenCx<'a, 'tcx>,
cx: &CodegenCx<'ll, 'tcx>,
sig: ty::FnSig<'tcx>,
extra_args: &[Ty<'tcx>],
mk_arg_type: impl Fn(Ty<'tcx>, Option<usize>) -> ArgType<'tcx, Ty<'tcx>>,
Expand Down Expand Up @@ -497,7 +498,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
}

fn adjust_for_abi(&mut self,
cx: &CodegenCx<'a, 'tcx>,
cx: &CodegenCx<'ll, 'tcx>,
abi: Abi) {
if abi == Abi::Unadjusted { return }

Expand Down Expand Up @@ -564,7 +565,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<'ll, 'tcx>) -> &'ll 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 }
Expand Down Expand Up @@ -606,9 +607,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)
}
}

Expand All @@ -629,7 +630,7 @@ impl<'a, 'tcx> FnTypeExt<'a, 'tcx> for FnType<'tcx, Ty<'tcx>> {
}
}

fn apply_attrs_llfn(&self, llfn: ValueRef) {
fn apply_attrs_llfn(&self, llfn: &'ll Value) {
let mut i = 0;
let mut apply = |attrs: &ArgAttributes| {
attrs.apply_llfn(llvm::AttributePlace::Argument(i), llfn);
Expand Down Expand Up @@ -659,7 +660,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: &'ll Value) {
let mut i = 0;
let mut apply = |attrs: &ArgAttributes| {
attrs.apply_callsite(llvm::AttributePlace::Argument(i), callsite);
Expand Down
7 changes: 3 additions & 4 deletions src/librustc_codegen_llvm/allocator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
// except according to those terms.

use std::ffi::CString;
use std::ptr;

use attributes;
use libc::c_uint;
Expand All @@ -21,8 +20,8 @@ use ModuleLlvm;
use llvm::{self, False, True};

pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind) {
let llcx = mods.llcx;
let llmod = mods.llmod;
let llcx = &*mods.llcx;
let llmod = mods.llmod();
let usize = match &tcx.sess.target.target.target_pointer_width[..] {
"16" => llvm::LLVMInt16TypeInContext(llcx),
"32" => llvm::LLVMInt32TypeInContext(llcx),
Expand Down Expand Up @@ -90,7 +89,7 @@ pub(crate) unsafe fn codegen(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind
callee,
args.as_ptr(),
args.len() as c_uint,
ptr::null_mut(),
None,
"\0".as_ptr() as *const _);
llvm::LLVMSetTailCall(ret, True);
if output.is_some() {
Expand Down
13 changes: 7 additions & 6 deletions src/librustc_codegen_llvm/asm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,12 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use llvm::{self, ValueRef};
use llvm;
use common::*;
use type_::Type;
use type_of::LayoutLlvmExt;
use builder::Builder;
use value::Value;

use rustc::hir;

Expand All @@ -24,11 +25,11 @@ 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>
outputs: Vec<PlaceRef<'ll, 'tcx>>,
mut inputs: Vec<&'ll Value>
) {
let mut ext_constraints = vec![];
let mut output_types = vec![];
Expand Down Expand Up @@ -111,7 +112,7 @@ pub fn codegen_inline_asm<'a, 'tcx>(
let kind = llvm::LLVMGetMDKindIDInContext(bx.cx.llcx,
key.as_ptr() as *const c_char, key.len() as c_uint);

let val: llvm::ValueRef = C_i32(bx.cx, ia.ctxt.outer().as_u32() as i32);
let val: &'ll Value = C_i32(bx.cx, ia.ctxt.outer().as_u32() as i32);

llvm::LLVMSetMetadata(r, kind,
llvm::LLVMMDNodeInContext(bx.cx.llcx, &val, 1));
Expand Down
20 changes: 11 additions & 9 deletions src/librustc_codegen_llvm/attributes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,17 @@ use rustc_data_structures::fx::FxHashMap;
use rustc_target::spec::PanicStrategy;

use attributes;
use llvm::{self, Attribute, ValueRef};
use llvm::{self, Attribute};
use llvm::AttributePlace::Function;
use llvm_util;
pub use syntax::attr::{self, InlineAttr};

use context::CodegenCx;
use value::Value;

/// Mark LLVM function to use provided inline heuristic.
#[inline]
pub fn inline(val: ValueRef, inline: InlineAttr) {
pub fn inline(val: &'ll Value, inline: InlineAttr) {
use self::InlineAttr::*;
match inline {
Hint => Attribute::InlineHint.apply_llfn(Function, val),
Expand All @@ -46,38 +48,38 @@ pub fn inline(val: ValueRef, inline: InlineAttr) {

/// Tell LLVM to emit or not emit the information necessary to unwind the stack for the function.
#[inline]
pub fn emit_uwtable(val: ValueRef, emit: bool) {
pub fn emit_uwtable(val: &'ll Value, emit: bool) {
Attribute::UWTable.toggle_llfn(Function, val, emit);
}

/// Tell LLVM whether the function can or cannot unwind.
#[inline]
pub fn unwind(val: ValueRef, can_unwind: bool) {
pub fn unwind(val: &'ll Value, can_unwind: bool) {
Attribute::NoUnwind.toggle_llfn(Function, val, !can_unwind);
}

/// Tell LLVM whether it should optimize function for size.
#[inline]
#[allow(dead_code)] // possibly useful function
pub fn set_optimize_for_size(val: ValueRef, optimize: bool) {
pub fn set_optimize_for_size(val: &'ll Value, optimize: bool) {
Attribute::OptimizeForSize.toggle_llfn(Function, val, optimize);
}

/// Tell LLVM if this function should be 'naked', i.e. skip the epilogue and prologue.
#[inline]
pub fn naked(val: ValueRef, is_naked: bool) {
pub fn naked(val: &'ll Value, is_naked: bool) {
Attribute::Naked.toggle_llfn(Function, val, is_naked);
}

pub fn set_frame_pointer_elimination(cx: &CodegenCx, llfn: ValueRef) {
pub fn set_frame_pointer_elimination(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
if cx.sess().must_not_eliminate_frame_pointers() {
llvm::AddFunctionAttrStringValue(
llfn, llvm::AttributePlace::Function,
cstr("no-frame-pointer-elim\0"), cstr("true\0"));
}
}

pub fn set_probestack(cx: &CodegenCx, llfn: ValueRef) {
pub fn set_probestack(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value) {
// Only use stack probes if the target specification indicates that we
// should be using stack probes
if !cx.sess().target.target.options.stack_probes {
Expand Down Expand Up @@ -123,7 +125,7 @@ pub fn llvm_target_features(sess: &Session) -> impl Iterator<Item = &str> {

/// Composite function which sets LLVM attributes for function depending on its AST (#[attribute])
/// attributes.
pub fn from_fn_attrs(cx: &CodegenCx, llfn: ValueRef, id: DefId) {
pub fn from_fn_attrs(cx: &CodegenCx<'ll, '_>, llfn: &'ll Value, id: DefId) {
let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(id);

inline(llfn, codegen_fn_attrs.inline);
Expand Down
Loading

0 comments on commit f898179

Please sign in to comment.