rustc_codegen_ssa: take a FnAbi instead of a FnSig in declare_fn.
This commit is contained in:
parent
db477af9ad
commit
95b944210f
@ -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,3 +1,4 @@
|
||||
use crate::abi::FnAbi;
|
||||
use crate::attributes;
|
||||
use crate::base;
|
||||
use crate::context::CodegenCx;
|
||||
@ -5,8 +6,8 @@ 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.
|
||||
///
|
||||
|
Loading…
x
Reference in New Issue
Block a user