use codegen_instance_attrs where an instance is (easily) available

This commit is contained in:
Folkert de Vries 2025-07-02 11:12:54 +02:00
parent ec0ff720d1
commit 9c8ab89187
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
18 changed files with 43 additions and 26 deletions

View file

@ -127,7 +127,7 @@ fn codegen_and_compile_fn<'tcx>(
module: &mut dyn Module,
instance: Instance<'tcx>,
) {
if tcx.codegen_fn_attrs(instance.def_id()).flags.contains(CodegenFnAttrFlags::NAKED) {
if tcx.codegen_instance_attrs(instance.def).flags.contains(CodegenFnAttrFlags::NAKED) {
tcx.dcx()
.span_fatal(tcx.def_span(instance.def_id()), "Naked asm is not supported in JIT mode");
}

View file

@ -35,7 +35,7 @@ fn predefine_mono_items<'tcx>(
is_compiler_builtins,
);
let is_naked = tcx
.codegen_fn_attrs(instance.def_id())
.codegen_instance_attrs(instance.def)
.flags
.contains(CodegenFnAttrFlags::NAKED);
module

View file

@ -87,7 +87,7 @@ pub fn from_fn_attrs<'gcc, 'tcx>(
#[cfg_attr(not(feature = "master"), allow(unused_variables))] func: Function<'gcc>,
instance: ty::Instance<'tcx>,
) {
let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
let codegen_fn_attrs = cx.tcx.codegen_instance_attrs(instance.def);
#[cfg(feature = "master")]
{

View file

@ -105,7 +105,7 @@ pub fn get_fn<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, instance: Instance<'tcx>)
let is_hidden = if is_generic {
// This is a monomorphization of a generic function.
if !(cx.tcx.sess.opts.share_generics()
|| tcx.codegen_fn_attrs(instance_def_id).inline
|| tcx.codegen_instance_attrs(instance.def).inline
== rustc_attr_data_structures::InlineAttr::Never)
{
// When not sharing generics, all instances are in the same

View file

@ -53,7 +53,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
self.linkage.set(base::linkage_to_gcc(linkage));
let decl = self.declare_fn(symbol_name, fn_abi);
//let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
//let attrs = self.tcx.codegen_instance_attrs(instance.def);
attributes::from_fn_attrs(self, decl, instance);

View file

@ -344,7 +344,7 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
llfn: &'ll Value,
instance: ty::Instance<'tcx>,
) {
let codegen_fn_attrs = cx.tcx.codegen_fn_attrs(instance.def_id());
let codegen_fn_attrs = cx.tcx.codegen_instance_attrs(instance.def);
let mut to_add = SmallVec::<[_; 16]>::new();

View file

@ -102,7 +102,7 @@ pub(crate) fn get_fn<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, instance: Instance<'t
let is_hidden = if is_generic {
// This is a monomorphization of a generic function.
if !(cx.tcx.sess.opts.share_generics()
|| tcx.codegen_fn_attrs(instance_def_id).inline
|| tcx.codegen_instance_attrs(instance.def).inline
== rustc_attr_data_structures::InlineAttr::Never)
{
// When not sharing generics, all instances are in the same

View file

@ -55,8 +55,8 @@ impl<'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'_, 'tcx> {
let fn_abi = self.fn_abi_of_instance(instance, ty::List::empty());
let lldecl = self.declare_fn(symbol_name, fn_abi, Some(instance));
llvm::set_linkage(lldecl, base::linkage_to_llvm(linkage));
let attrs = self.tcx.codegen_fn_attrs(instance.def_id());
base::set_link_section(lldecl, attrs);
let attrs = self.tcx.codegen_instance_attrs(instance.def);
base::set_link_section(lldecl, &attrs);
if (linkage == Linkage::LinkOnceODR || linkage == Linkage::WeakODR)
&& self.tcx.sess.target.supports_comdat()
{

View file

@ -114,7 +114,6 @@ fn codegen_fn_attrs(tcx: TyCtxt<'_>, did: LocalDefId) -> CodegenFnAttrs {
codegen_fn_attrs.export_name = Some(*name);
}
AttributeKind::Naked(_) => codegen_fn_attrs.flags |= CodegenFnAttrFlags::NAKED,
AttributeKind::Align { align, .. } => codegen_fn_attrs.alignment = Some(*align),
AttributeKind::LinkName { name, .. } => codegen_fn_attrs.link_name = Some(*name),
AttributeKind::LinkSection { name, .. } => {

View file

@ -128,7 +128,7 @@ fn prefix_and_suffix<'tcx>(
let is_arm = tcx.sess.target.arch == "arm";
let is_thumb = tcx.sess.unstable_target_features.contains(&sym::thumb_mode);
let attrs = tcx.codegen_fn_attrs(instance.def_id());
let attrs = tcx.codegen_instance_attrs(instance.def);
let link_section = attrs.link_section.map(|symbol| symbol.as_str().to_string());
// If no alignment is specified, an alignment of 4 bytes is used.

View file

@ -611,11 +611,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let fn_abi = bx.fn_abi_of_instance(instance, ty::List::empty());
let fn_ty = bx.fn_decl_backend_type(fn_abi);
let fn_attrs = if bx.tcx().def_kind(instance.def_id()).has_codegen_attrs() {
Some(bx.tcx().codegen_fn_attrs(instance.def_id()))
Some(bx.tcx().codegen_instance_attrs(instance.def))
} else {
None
};
bx.call(fn_ty, fn_attrs, Some(fn_abi), fn_ptr, &[], None, Some(instance))
bx.call(
fn_ty,
fn_attrs.as_deref(),
Some(fn_abi),
fn_ptr,
&[],
None,
Some(instance),
)
} else {
bx.get_static(def_id)
};

View file

@ -71,7 +71,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
cx.predefine_static(def_id, linkage, visibility, symbol_name);
}
MonoItem::Fn(instance) => {
let attrs = cx.tcx().codegen_fn_attrs(instance.def_id());
let attrs = cx.tcx().codegen_instance_attrs(instance.def);
if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
// do not define this function; it will become a global assembly block

View file

@ -890,7 +890,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
if let Some(fn_val) = self.get_fn_alloc(id) {
let align = match fn_val {
FnVal::Instance(instance) => {
self.tcx.codegen_fn_attrs(instance.def_id()).alignment.unwrap_or(Align::ONE)
self.tcx.codegen_instance_attrs(instance.def).alignment.unwrap_or(Align::ONE)
}
// Machine-specific extra functions currently do not support alignment restrictions.
FnVal::Other(_) => Align::ONE,

View file

@ -20,7 +20,9 @@ impl<'tcx> TyCtxt<'tcx> {
// Drop the `#[naked]` attribute on non-item `InstanceKind`s, like the shims that
// are generated for indirect function calls.
if !matches!(instance_kind, InstanceKind::Item(_)) {
attrs.to_mut().flags.remove(CodegenFnAttrFlags::NAKED);
if attrs.flags.contains(CodegenFnAttrFlags::NAKED) {
attrs.to_mut().flags.remove(CodegenFnAttrFlags::NAKED);
}
}
attrs

View file

@ -152,7 +152,7 @@ impl<'tcx> MonoItem<'tcx> {
// If the function is #[naked] or contains any other attribute that requires exactly-once
// instantiation:
// We emit an unused_attributes lint for this case, which should be kept in sync if possible.
let codegen_fn_attrs = tcx.codegen_fn_attrs(instance.def_id());
let codegen_fn_attrs = tcx.codegen_instance_attrs(instance.def);
if codegen_fn_attrs.contains_extern_indicator()
|| codegen_fn_attrs.flags.contains(CodegenFnAttrFlags::NAKED)
{
@ -219,7 +219,7 @@ impl<'tcx> MonoItem<'tcx> {
// functions the same as those that unconditionally get LocalCopy codegen. It's only when
// we get here that we can at least not codegen a #[inline(never)] generic function in all
// of our CGUs.
if let InlineAttr::Never = tcx.codegen_fn_attrs(instance.def_id()).inline
if let InlineAttr::Never = codegen_fn_attrs.inline
&& self.is_generic_fn()
{
return InstantiationMode::GloballyShared { may_conflict: true };
@ -234,14 +234,13 @@ impl<'tcx> MonoItem<'tcx> {
}
pub fn explicit_linkage(&self, tcx: TyCtxt<'tcx>) -> Option<Linkage> {
let def_id = match *self {
MonoItem::Fn(ref instance) => instance.def_id(),
MonoItem::Static(def_id) => def_id,
let instance_kind = match *self {
MonoItem::Fn(ref instance) => instance.def,
MonoItem::Static(def_id) => InstanceKind::Item(def_id),
MonoItem::GlobalAsm(..) => return None,
};
let codegen_fn_attrs = tcx.codegen_fn_attrs(def_id);
codegen_fn_attrs.linkage
tcx.codegen_instance_attrs(instance_kind).linkage
}
/// Returns `true` if this instance is instantiable - whether it has no unsatisfied

View file

@ -1505,6 +1505,15 @@ rustc_queries! {
separate_provide_extern
}
/// Returns the `CodegenFnAttrs` for the item at `def_id`.
///
/// If possible, use `tcx.codegen_instance_attrs` instead. That function takes the
/// instance kind into account.
///
/// For example, the `#[naked]` attribute should be applied for `InstanceKind::Item`,
/// but should not be applied if the instance kind is `InstanceKind::ReifyShim`.
/// Using this query would include the attribute regardless of the actual instance
/// kind at the call site.
query codegen_fn_attrs(def_id: DefId) -> &'tcx CodegenFnAttrs {
desc { |tcx| "computing codegen attributes of `{}`", tcx.def_path_str(def_id) }
arena_cache

View file

@ -180,7 +180,7 @@ fn compute_symbol_name<'tcx>(
// FIXME(eddyb) Precompute a custom symbol name based on attributes.
let attrs = if tcx.def_kind(def_id).has_codegen_attrs() {
tcx.codegen_fn_attrs(def_id)
&tcx.codegen_instance_attrs(instance.def)
} else {
CodegenFnAttrs::EMPTY
};

View file

@ -1086,7 +1086,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
ecx: &MiriInterpCx<'tcx>,
instance: ty::Instance<'tcx>,
) -> InterpResult<'tcx> {
let attrs = ecx.tcx.codegen_fn_attrs(instance.def_id());
let attrs = ecx.tcx.codegen_instance_attrs(instance.def);
if attrs
.target_features
.iter()
@ -1790,7 +1790,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
ecx.tcx.sess.opts.unstable_opts.cross_crate_inline_threshold,
InliningThreshold::Always
) || !matches!(
ecx.tcx.codegen_fn_attrs(instance.def_id()).inline,
ecx.tcx.codegen_instance_attrs(instance.def).inline,
InlineAttr::Never
);
!is_generic && !can_be_inlined