From 95b944210f8964f24a64dbb7d723b622eb3b0a4e Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 29 Oct 2019 18:34:50 +0200 Subject: [PATCH] rustc_codegen_ssa: take a FnAbi instead of a FnSig in declare_fn. --- src/librustc_codegen_llvm/attributes.rs | 7 +++---- src/librustc_codegen_llvm/callee.rs | 22 ++++++++++++---------- src/librustc_codegen_llvm/context.rs | 10 ++++++---- src/librustc_codegen_llvm/declare.rs | 13 +++++-------- src/librustc_codegen_llvm/intrinsic.rs | 11 +++++------ src/librustc_codegen_llvm/mono_item.rs | 16 +++++++++++----- src/librustc_codegen_ssa/traits/declare.rs | 5 +++-- 7 files changed, 45 insertions(+), 39 deletions(-) diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 6f4e7d0f0caf5..a295f2b240291 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -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, - 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). diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs index 08fa23f2a7c9e..b8e41b1f3dbfb 100644 --- a/src/librustc_codegen_llvm/callee.rs +++ b/src/librustc_codegen_llvm/callee.rs @@ -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(); diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs index 4a40349cb73e8..89e3195342ce8 100644 --- a/src/librustc_codegen_llvm/context.rs +++ b/src/librustc_codegen_llvm/context.rs @@ -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 diff --git a/src/librustc_codegen_llvm/declare.rs b/src/librustc_codegen_llvm/declare.rs index 61c1e0dffe677..772377617e2e1 100644 --- a/src/librustc_codegen_llvm/declare.rs +++ b/src/librustc_codegen_llvm/declare.rs @@ -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); } diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 26f3b4bbe2910..999fc857c15a2 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -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 diff --git a/src/librustc_codegen_llvm/mono_item.rs b/src/librustc_codegen_llvm/mono_item.rs index c1703ffd0c753..f9df0a00475d0 100644 --- a/src/librustc_codegen_llvm/mono_item.rs +++ b/src/librustc_codegen_llvm/mono_item.rs @@ -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); diff --git a/src/librustc_codegen_ssa/traits/declare.rs b/src/librustc_codegen_ssa/traits/declare.rs index e6cb82c8229f3..1dd2c74dd4fa2 100644 --- a/src/librustc_codegen_ssa/traits/declare.rs +++ b/src/librustc_codegen_ssa/traits/declare.rs @@ -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. ///