Rollup merge of #128679 - RalfJung:codegen-fn-attrs, r=nikic
codegen: better centralize function declaration attribute computation For some reason, the codegen backend has two functions that compute which attributes a function declaration gets: `apply_attrs_llfn` and `attributes::from_fn_attrs`. They are called in different places, on entirely different layers of abstraction. To me the code seems cleaner if we centralize this entirely in `apply_attrs_llfn`, so that's what this PR does.
This commit is contained in:
commit
8f39b86a6a
@ -5,10 +5,10 @@
|
|||||||
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
|
use rustc_codegen_ssa::mir::place::{PlaceRef, PlaceValue};
|
||||||
use rustc_codegen_ssa::traits::*;
|
use rustc_codegen_ssa::traits::*;
|
||||||
use rustc_codegen_ssa::MemFlags;
|
use rustc_codegen_ssa::MemFlags;
|
||||||
use rustc_middle::bug;
|
|
||||||
use rustc_middle::ty::layout::LayoutOf;
|
use rustc_middle::ty::layout::LayoutOf;
|
||||||
pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
|
pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
|
||||||
use rustc_middle::ty::Ty;
|
use rustc_middle::ty::Ty;
|
||||||
|
use rustc_middle::{bug, ty};
|
||||||
use rustc_session::config;
|
use rustc_session::config;
|
||||||
pub use rustc_target::abi::call::*;
|
pub use rustc_target::abi::call::*;
|
||||||
use rustc_target::abi::{self, HasDataLayout, Int, Size};
|
use rustc_target::abi::{self, HasDataLayout, Int, Size};
|
||||||
@ -16,6 +16,7 @@
|
|||||||
use rustc_target::spec::SanitizerSet;
|
use rustc_target::spec::SanitizerSet;
|
||||||
use smallvec::SmallVec;
|
use smallvec::SmallVec;
|
||||||
|
|
||||||
|
use crate::attributes::llfn_attrs_from_instance;
|
||||||
use crate::builder::Builder;
|
use crate::builder::Builder;
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
use crate::llvm::{self, Attribute, AttributePlace};
|
use crate::llvm::{self, Attribute, AttributePlace};
|
||||||
@ -310,7 +311,16 @@ pub trait FnAbiLlvmExt<'ll, 'tcx> {
|
|||||||
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
fn llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||||
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
fn ptr_to_llvm_type(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
|
||||||
fn llvm_cconv(&self) -> llvm::CallConv;
|
fn llvm_cconv(&self) -> llvm::CallConv;
|
||||||
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value);
|
|
||||||
|
/// Apply attributes to a function declaration/definition.
|
||||||
|
fn apply_attrs_llfn(
|
||||||
|
&self,
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
|
llfn: &'ll Value,
|
||||||
|
instance: Option<ty::Instance<'tcx>>,
|
||||||
|
);
|
||||||
|
|
||||||
|
/// Apply attributes to a function call.
|
||||||
fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value);
|
fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,7 +406,12 @@ fn llvm_cconv(&self) -> llvm::CallConv {
|
|||||||
self.conv.into()
|
self.conv.into()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
|
fn apply_attrs_llfn(
|
||||||
|
&self,
|
||||||
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
|
llfn: &'ll Value,
|
||||||
|
instance: Option<ty::Instance<'tcx>>,
|
||||||
|
) {
|
||||||
let mut func_attrs = SmallVec::<[_; 3]>::new();
|
let mut func_attrs = SmallVec::<[_; 3]>::new();
|
||||||
if self.ret.layout.abi.is_uninhabited() {
|
if self.ret.layout.abi.is_uninhabited() {
|
||||||
func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx));
|
func_attrs.push(llvm::AttributeKind::NoReturn.create_attr(cx.llcx));
|
||||||
@ -477,6 +492,11 @@ fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the declaration has an associated instance, compute extra attributes based on that.
|
||||||
|
if let Some(instance) = instance {
|
||||||
|
llfn_attrs_from_instance(cx, llfn, instance);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value) {
|
fn apply_attrs_callsite(&self, bx: &mut Builder<'_, 'll, 'tcx>, callsite: &'ll Value) {
|
||||||
|
@ -324,9 +324,10 @@ fn create_alloc_family_attr(llcx: &llvm::Context) -> &llvm::Attribute {
|
|||||||
llvm::CreateAttrStringValue(llcx, "alloc-family", "__rust_alloc")
|
llvm::CreateAttrStringValue(llcx, "alloc-family", "__rust_alloc")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Helper for `FnAbi::apply_attrs_llfn`:
|
||||||
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
|
/// Composite function which sets LLVM attributes for function depending on its AST (`#[attribute]`)
|
||||||
/// attributes.
|
/// attributes.
|
||||||
pub fn from_fn_attrs<'ll, 'tcx>(
|
pub fn llfn_attrs_from_instance<'ll, 'tcx>(
|
||||||
cx: &CodegenCx<'ll, 'tcx>,
|
cx: &CodegenCx<'ll, 'tcx>,
|
||||||
llfn: &'ll Value,
|
llfn: &'ll Value,
|
||||||
instance: ty::Instance<'tcx>,
|
instance: ty::Instance<'tcx>,
|
||||||
|
@ -10,8 +10,8 @@
|
|||||||
use tracing::debug;
|
use tracing::debug;
|
||||||
|
|
||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
|
use crate::llvm;
|
||||||
use crate::value::Value;
|
use crate::value::Value;
|
||||||
use crate::{attributes, llvm};
|
|
||||||
|
|
||||||
/// Codegens a reference to a fn/method item, monomorphizing and
|
/// Codegens a reference to a fn/method item, monomorphizing and
|
||||||
/// inlining as it goes.
|
/// inlining as it goes.
|
||||||
@ -78,8 +78,6 @@ pub fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'tcx>) ->
|
|||||||
};
|
};
|
||||||
debug!("get_fn: not casting pointer!");
|
debug!("get_fn: not casting pointer!");
|
||||||
|
|
||||||
attributes::from_fn_attrs(cx, llfn, instance);
|
|
||||||
|
|
||||||
// Apply an appropriate linkage/visibility value to our item that we
|
// Apply an appropriate linkage/visibility value to our item that we
|
||||||
// just declared.
|
// just declared.
|
||||||
//
|
//
|
||||||
|
@ -137,7 +137,7 @@ pub fn declare_fn(
|
|||||||
llvm::Visibility::Default,
|
llvm::Visibility::Default,
|
||||||
fn_abi.llvm_type(self),
|
fn_abi.llvm_type(self),
|
||||||
);
|
);
|
||||||
fn_abi.apply_attrs_llfn(self, llfn);
|
fn_abi.apply_attrs_llfn(self, llfn, instance);
|
||||||
|
|
||||||
if self.tcx.sess.is_sanitizer_cfi_enabled() {
|
if self.tcx.sess.is_sanitizer_cfi_enabled() {
|
||||||
if let Some(instance) = instance {
|
if let Some(instance) = instance {
|
||||||
|
@ -12,7 +12,7 @@
|
|||||||
use crate::context::CodegenCx;
|
use crate::context::CodegenCx;
|
||||||
use crate::errors::SymbolAlreadyDefined;
|
use crate::errors::SymbolAlreadyDefined;
|
||||||
use crate::type_of::LayoutLlvmExt;
|
use crate::type_of::LayoutLlvmExt;
|
||||||
use crate::{attributes, base, llvm};
|
use crate::{base, llvm};
|
||||||
|
|
||||||
impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
|
||||||
fn predefine_static(
|
fn predefine_static(
|
||||||
@ -87,8 +87,6 @@ fn predefine_fn(
|
|||||||
|
|
||||||
debug!("predefine_fn: instance = {:?}", instance);
|
debug!("predefine_fn: instance = {:?}", instance);
|
||||||
|
|
||||||
attributes::from_fn_attrs(self, lldecl, instance);
|
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
if self.should_assume_dso_local(lldecl, false) {
|
if self.should_assume_dso_local(lldecl, false) {
|
||||||
llvm::LLVMRustSetDSOLocal(lldecl, true);
|
llvm::LLVMRustSetDSOLocal(lldecl, true);
|
||||||
|
Loading…
Reference in New Issue
Block a user