Skip to content
Permalink
Browse files

rustc_codegen_ssa: take a FnAbi instead of a FnSig in declare_fn.

  • Loading branch information
eddyb committed Oct 29, 2019
1 parent db477af commit 95b944210f8964f24a64dbb7d723b622eb3b0a4e
@@ -6,7 +6,7 @@ use rustc::hir::{CodegenFnAttrFlags, CodegenFnAttrs};
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::session::Session;
use rustc::session::config::{Sanitizer, OptLevel};
use rustc::ty::{self, TyCtxt, PolyFnSig};
use rustc::ty::TyCtxt;
use rustc::ty::layout::HasTyCtxt;
use rustc::ty::query::Providers;
use rustc_data_structures::small_c_str::SmallCStr;
@@ -203,7 +203,7 @@ pub fn from_fn_attrs(
cx: &CodegenCx<'ll, 'tcx>,
llfn: &'ll Value,
id: Option<DefId>,
sig: PolyFnSig<'tcx>,
abi: Abi,
) {
let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id))
.unwrap_or_else(|| CodegenFnAttrs::new());
@@ -276,8 +276,7 @@ pub fn from_fn_attrs(
// Special attribute for allocator functions, which can't unwind.
false
} else {
let sig = cx.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
if sig.abi == Abi::Rust || sig.abi == Abi::RustCall {
if abi == Abi::Rust || abi == Abi::RustCall {
// Any Rust method (or `extern "Rust" fn` or `extern
// "rust-call" fn`) is explicitly allowed to unwind
// (unless it has no-unwind attribute, handled above).
@@ -4,14 +4,15 @@
//! and methods are represented as just a fn ptr and not a full
//! closure.

use crate::abi::FnAbi;
use crate::attributes;
use crate::llvm;
use crate::context::CodegenCx;
use crate::value::Value;
use rustc_codegen_ssa::traits::*;

use rustc::ty::{TypeFoldable, Instance};
use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use rustc::ty::{self, TypeFoldable, Instance};
use rustc::ty::layout::{FnAbiExt, LayoutOf, HasTyCtxt};

/// Codegens a reference to a fn/method item, monomorphizing and
/// inlining as it goes.
@@ -32,19 +33,19 @@ pub fn get_fn(
assert!(!instance.substs.has_escaping_bound_vars());
assert!(!instance.substs.has_param_types());

let sig = instance.fn_sig(cx.tcx());
if let Some(&llfn) = cx.instances.borrow().get(&instance) {
return llfn;
}

let sig = instance.fn_sig(cx.tcx());
let sym = tcx.symbol_name(instance).name.as_str();
debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym);

// Create a fn pointer with the substituted signature.
let fn_ptr_ty = tcx.mk_fn_ptr(sig);
let llptrty = cx.backend_type(cx.layout_of(fn_ptr_ty));

let llfn = if let Some(llfn) = cx.get_declared_value(&sym) {
// Create a fn pointer with the substituted signature.
let fn_ptr_ty = tcx.mk_fn_ptr(sig);
let llptrty = cx.backend_type(cx.layout_of(fn_ptr_ty));

// This is subtle and surprising, but sometimes we have to bitcast
// the resulting fn pointer. The reason has to do with external
// functions. If you have two crates that both bind the same C
@@ -76,14 +77,15 @@ pub fn get_fn(
llfn
}
} else {
let llfn = cx.declare_fn(&sym, sig);
assert_eq!(cx.val_ty(llfn), llptrty);
let sig = tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
let fn_abi = FnAbi::new(cx, sig, &[]);
let llfn = cx.declare_fn(&sym, &fn_abi);
debug!("get_fn: not casting pointer!");

if instance.def.is_inline(tcx) {
attributes::inline(cx, llfn, attributes::InlineAttr::Hint);
}
attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id()), sig);
attributes::from_fn_attrs(cx, llfn, Some(instance.def.def_id()), sig.abi);

let instance_def_id = instance.def_id();

@@ -1,3 +1,4 @@
use crate::abi::FnAbi;
use crate::attributes;
use crate::llvm;
use crate::llvm_util;
@@ -15,7 +16,7 @@ use rustc::mir::mono::CodegenUnit;
use rustc::session::config::{self, DebugInfo};
use rustc::session::Session;
use rustc::ty::layout::{
LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx, HasParamEnv
FnAbiExt, LayoutError, LayoutOf, PointeeInfo, Size, TyLayout, VariantIdx, HasParamEnv
};
use rustc::ty::{self, Ty, TyCtxt, Instance};
use rustc::util::nodemap::FxHashMap;
@@ -412,15 +413,16 @@ impl MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
return llfn;
}

let sig = ty::Binder::bind(tcx.mk_fn_sig(
let sig = tcx.mk_fn_sig(
iter::once(tcx.mk_mut_ptr(tcx.types.u8)),
tcx.types.never,
false,
hir::Unsafety::Unsafe,
Abi::C
));
);

let llfn = self.declare_fn("rust_eh_unwind_resume", sig);
let fn_abi = FnAbi::new(self, sig, &[]);
let llfn = self.declare_fn("rust_eh_unwind_resume", &fn_abi);
attributes::apply_target_cpu_attr(self, llfn);
unwresume.set(Some(llfn));
llfn
@@ -18,8 +18,7 @@ use crate::attributes;
use crate::context::CodegenCx;
use crate::type_::Type;
use crate::value::Value;
use rustc::ty::{self, PolyFnSig};
use rustc::ty::layout::{FnAbiExt, LayoutOf};
use rustc::ty::Ty;
use rustc::session::config::Sanitizer;
use rustc_data_structures::small_c_str::SmallCStr;
use rustc_codegen_ssa::traits::*;
@@ -94,16 +93,14 @@ impl DeclareMethods<'tcx> for CodegenCx<'ll, 'tcx> {
fn declare_fn(
&self,
name: &str,
sig: PolyFnSig<'tcx>,
fn_abi: &FnAbi<'tcx, Ty<'tcx>>,
) -> &'ll Value {
debug!("declare_rust_fn(name={:?}, sig={:?})", name, sig);
let sig = self.tcx.normalize_erasing_late_bound_regions(ty::ParamEnv::reveal_all(), &sig);
debug!("declare_rust_fn (after region erasure) sig={:?}", sig);
debug!("declare_rust_fn(name={:?}, fn_abi={:?})", name, fn_abi);

let fn_abi = FnAbi::new(self, sig, &[]);
let llfn = declare_raw_fn(self, name, fn_abi.llvm_cconv(), fn_abi.llvm_type(self));

if self.layout_of(sig.output()).abi.is_uninhabited() {
// FIXME(eddyb) move into `FnAbi::apply_attrs_llfn`.
if fn_abi.ret.layout.abi.is_uninhabited() {
llvm::Attribute::NoReturn.apply_llfn(Function, llfn);
}

@@ -1,4 +1,3 @@
use crate::attributes;
use crate::llvm;
use crate::llvm_util;
use crate::abi::{Abi, FnAbi, LlvmType, PassMode};
@@ -14,7 +13,7 @@ use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
use rustc_codegen_ssa::glue;
use rustc_codegen_ssa::base::{to_immediate, wants_msvc_seh, compare_simd_types};
use rustc::ty::{self, Ty};
use rustc::ty::layout::{self, LayoutOf, HasTyCtxt, Primitive};
use rustc::ty::layout::{self, FnAbiExt, LayoutOf, HasTyCtxt, Primitive};
use rustc::mir::interpret::GlobalId;
use rustc_codegen_ssa::common::{IntPredicate, TypeKind};
use rustc::hir;
@@ -1006,17 +1005,17 @@ fn gen_fn<'ll, 'tcx>(
output: Ty<'tcx>,
codegen: &mut dyn FnMut(Builder<'_, 'll, 'tcx>),
) -> &'ll Value {
let rust_fn_sig = ty::Binder::bind(cx.tcx.mk_fn_sig(
let rust_fn_sig = cx.tcx.mk_fn_sig(
inputs.into_iter(),
output,
false,
hir::Unsafety::Unsafe,
Abi::Rust
));
let llfn = cx.declare_fn(name, rust_fn_sig);
);
let fn_abi = FnAbi::new(cx, rust_fn_sig, &[]);
let llfn = cx.declare_fn(name, &fn_abi);
// FIXME(eddyb) find a nicer way to do this.
unsafe { llvm::LLVMRustSetLinkage(llfn, llvm::Linkage::InternalLinkage) };
attributes::from_fn_attrs(cx, llfn, None, rust_fn_sig);
let bx = Builder::new_block(cx, llfn, "entry-block");
codegen(bx);
llfn
@@ -1,12 +1,13 @@
use crate::abi::FnAbi;
use crate::attributes;
use crate::base;
use crate::context::CodegenCx;
use crate::llvm;
use crate::type_of::LayoutLlvmExt;
use rustc::hir::def_id::{DefId, LOCAL_CRATE};
use rustc::mir::mono::{Linkage, Visibility};
use rustc::ty::{TypeFoldable, Instance};
use rustc::ty::layout::{LayoutOf, HasTyCtxt};
use rustc::ty::{self, TypeFoldable, Instance};
use rustc::ty::layout::{FnAbiExt, LayoutOf, HasTyCtxt};
use rustc_codegen_ssa::traits::*;

pub use rustc::mir::mono::MonoItem;
@@ -43,9 +44,14 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
!instance.substs.has_param_types());

let mono_sig = instance.fn_sig(self.tcx());
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
let lldecl = self.declare_fn(symbol_name, mono_sig);
let mono_sig = self.tcx().normalize_erasing_late_bound_regions(
ty::ParamEnv::reveal_all(),
&mono_sig,
);
let fn_abi = FnAbi::new(self, mono_sig, &[]);
let lldecl = self.declare_fn(symbol_name, &fn_abi);
unsafe { llvm::LLVMRustSetLinkage(lldecl, base::linkage_to_llvm(linkage)) };
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
base::set_link_section(lldecl, &attrs);
if linkage == Linkage::LinkOnceODR ||
linkage == Linkage::WeakODR {
@@ -75,7 +81,7 @@ impl PreDefineMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self,
lldecl,
Some(instance.def.def_id()),
mono_sig,
mono_sig.abi,
);

self.instances.borrow_mut().insert(instance, lldecl);
@@ -1,7 +1,8 @@
use super::BackendTypes;
use rustc::hir::def_id::DefId;
use rustc::mir::mono::{Linkage, Visibility};
use rustc::ty::{self, Instance};
use rustc::ty::{Instance, Ty};
use rustc_target::abi::call::FnAbi;

pub trait DeclareMethods<'tcx>: BackendTypes {
/// Declare a global value.
@@ -23,7 +24,7 @@ pub trait DeclareMethods<'tcx>: BackendTypes {
///
/// If there’s a value with the same name already declared, the function will
/// update the declaration and return existing Value instead.
fn declare_fn(&self, name: &str, sig: ty::PolyFnSig<'tcx>) -> Self::Function;
fn declare_fn(&self, name: &str, fn_abi: &FnAbi<'tcx, Ty<'tcx>>) -> Self::Function;

/// Declare a global with an intention to define it.
///

0 comments on commit 95b9442

Please sign in to comment.
You can’t perform that action at this time.