codegen: better centralize function attribute computation

This commit is contained in:
Ralf Jung 2024-08-05 12:49:31 +02:00
parent 8d0066922b
commit 273c67db83
5 changed files with 28 additions and 11 deletions

View File

@ -5,10 +5,10 @@ use rustc_codegen_ssa::mir::operand::{OperandRef, OperandValue};
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 @@ pub use rustc_target::spec::abi::Abi;
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 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
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 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
} }
} }
} }
// 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) {

View File

@ -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>,

View File

@ -10,8 +10,8 @@ use rustc_middle::ty::{self, Instance, TypeVisitableExt};
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.
// //

View File

@ -137,7 +137,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
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 {

View File

@ -12,7 +12,7 @@ use tracing::debug;
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 @@ impl<'tcx> PreDefineMethods<'tcx> for CodegenCx<'_, 'tcx> {
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);