Skip to content

A variety of improvements to the codegen backends #141448

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Merged
merged 9 commits into from
May 30, 2025
7 changes: 3 additions & 4 deletions compiler/rustc_codegen_gcc/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ use rustc_target::callconv::{Conv, RiscvInterruptKind};

use crate::builder::Builder;
use crate::context::CodegenCx;
use crate::intrinsic::ArgAbiExt;
use crate::type_of::LayoutGccExt;

impl AbiBuilderMethods for Builder<'_, '_, '_> {
Expand Down Expand Up @@ -125,7 +124,7 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Direct(_) | PassMode::Pair(..) => self.ret.layout.immediate_gcc_type(cx),
PassMode::Cast { ref cast, .. } => cast.gcc_type(cx),
PassMode::Indirect { .. } => {
argument_tys.push(cx.type_ptr_to(self.ret.memory_ty(cx)));
argument_tys.push(cx.type_ptr_to(self.ret.layout.gcc_type(cx)));
cx.type_void()
}
};
Expand Down Expand Up @@ -176,13 +175,13 @@ impl<'gcc, 'tcx> FnAbiGccExt<'gcc, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
PassMode::Indirect { attrs: _, meta_attrs: None, on_stack: true } => {
// This is a "byval" argument, so we don't apply the `restrict` attribute on it.
on_stack_param_indices.insert(argument_tys.len());
arg.memory_ty(cx)
arg.layout.gcc_type(cx)
}
PassMode::Direct(attrs) => {
apply_attrs(arg.layout.immediate_gcc_type(cx), &attrs, argument_tys.len())
}
PassMode::Indirect { attrs, meta_attrs: None, on_stack: false } => {
apply_attrs(cx.type_ptr_to(arg.memory_ty(cx)), &attrs, argument_tys.len())
apply_attrs(cx.type_ptr_to(arg.layout.gcc_type(cx)), &attrs, argument_tys.len())
}
PassMode::Indirect { attrs, meta_attrs: Some(meta_attrs), on_stack } => {
assert!(!on_stack);
Expand Down
11 changes: 8 additions & 3 deletions compiler/rustc_codegen_gcc/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -219,17 +219,22 @@ pub fn compile_codegen_unit(

let mono_items = cgu.items_in_deterministic_order(tcx);
for &(mono_item, data) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
mono_item.predefine::<Builder<'_, '_, '_>>(
&mut cx,
cgu_name.as_str(),
data.linkage,
data.visibility,
);
}

// ... and now that we have everything pre-defined, fill out those definitions.
for &(mono_item, item_data) in &mono_items {
mono_item.define::<Builder<'_, '_, '_>>(&mut cx, item_data);
mono_item.define::<Builder<'_, '_, '_>>(&mut cx, cgu_name.as_str(), item_data);
}

// If this codegen unit contains the main function, also create the
// wrapper here
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx);
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx, cx.codegen_unit);

// Finalize debuginfo
if cx.sess().opts.debuginfo != DebugInfo::None {
Expand Down
13 changes: 4 additions & 9 deletions compiler/rustc_codegen_gcc/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
}

#[cfg_attr(not(feature = "master"), allow(unused_mut))]
fn codegen_static(&self, def_id: DefId) {
fn codegen_static(&mut self, def_id: DefId) {
let attrs = self.tcx.codegen_fn_attrs(def_id);

let Ok((value, alloc)) = codegen_static_initializer(self, def_id) else {
Expand Down Expand Up @@ -160,19 +160,14 @@ impl<'gcc, 'tcx> StaticCodegenMethods for CodegenCx<'gcc, 'tcx> {
self.add_used_global(global.to_rvalue());
}
}
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
/// Add a global value to a list to be stored in the `llvm.used` variable, an array of i8*.
fn add_used_global(&self, _global: RValue<'gcc>) {
pub fn add_used_global(&mut self, _global: RValue<'gcc>) {
// TODO(antoyo)
}

fn add_compiler_used_global(&self, global: RValue<'gcc>) {
// NOTE: seems like GCC does not make the distinction between compiler.used and used.
self.add_used_global(global);
}
}

impl<'gcc, 'tcx> CodegenCx<'gcc, 'tcx> {
#[cfg_attr(not(feature = "master"), allow(unused_variables))]
pub fn add_used_function(&self, function: Function<'gcc>) {
#[cfg(feature = "master")]
Expand Down
4 changes: 0 additions & 4 deletions compiler/rustc_codegen_gcc/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -470,10 +470,6 @@ impl<'gcc, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
self.tcx.sess
}

fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> {
self.codegen_unit
}

fn set_frame_pointer_type(&self, _llfn: RValue<'gcc>) {
// TODO(antoyo)
}
Expand Down
11 changes: 0 additions & 11 deletions compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -574,14 +574,9 @@ impl<'a, 'gcc, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
) {
arg_abi.store(self, val, dst)
}

fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> Type<'gcc> {
arg_abi.memory_ty(self)
}
}

pub trait ArgAbiExt<'gcc, 'tcx> {
fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc>;
fn store(
&self,
bx: &mut Builder<'_, 'gcc, 'tcx>,
Expand All @@ -597,12 +592,6 @@ pub trait ArgAbiExt<'gcc, 'tcx> {
}

impl<'gcc, 'tcx> ArgAbiExt<'gcc, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
/// Gets the LLVM type for a place of the original Rust type of
/// this argument/return, i.e., the result of `type_of::type_of`.
fn memory_ty(&self, cx: &CodegenCx<'gcc, 'tcx>) -> Type<'gcc> {
self.layout.gcc_type(cx)
}

/// Stores a direct/indirect value described by this ArgAbi into a
/// place for the original Rust type of this argument/return.
/// Can be used for both storing formal arguments into Rust variables
Expand Down
6 changes: 3 additions & 3 deletions compiler/rustc_codegen_gcc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -391,7 +391,7 @@ impl WriteBackendMethods for GccCodegenBackend {
unimplemented!()
}

unsafe fn optimize(
fn optimize(
_cgcx: &CodegenContext<Self>,
_dcx: DiagCtxtHandle<'_>,
module: &mut ModuleCodegen<Self::Module>,
Expand All @@ -409,14 +409,14 @@ impl WriteBackendMethods for GccCodegenBackend {
Ok(())
}

unsafe fn optimize_thin(
fn optimize_thin(
cgcx: &CodegenContext<Self>,
thin: ThinModule<Self>,
) -> Result<ModuleCodegen<Self::Module>, FatalError> {
back::lto::optimize_thin_module(thin, cgcx)
}

unsafe fn codegen(
fn codegen(
cgcx: &CodegenContext<Self>,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<Self::Module>,
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_gcc/src/mono_item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ use crate::{attributes, base};
impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {
#[cfg_attr(not(feature = "master"), allow(unused_variables))]
fn predefine_static(
&self,
&mut self,
def_id: DefId,
_linkage: Linkage,
visibility: Visibility,
Expand All @@ -42,7 +42,7 @@ impl<'gcc, 'tcx> PreDefineCodegenMethods<'tcx> for CodegenCx<'gcc, 'tcx> {

#[cfg_attr(not(feature = "master"), allow(unused_variables))]
fn predefine_fn(
&self,
&mut self,
instance: Instance<'tcx>,
linkage: Linkage,
visibility: Visibility,
Expand Down
10 changes: 0 additions & 10 deletions compiler/rustc_codegen_llvm/src/abi.rs
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ impl LlvmType for CastTarget {
}

trait ArgAbiExt<'ll, 'tcx> {
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type;
fn store(
&self,
bx: &mut Builder<'_, 'll, 'tcx>,
Expand All @@ -188,12 +187,6 @@ trait ArgAbiExt<'ll, 'tcx> {
}

impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
/// Gets the LLVM type for a place of the original Rust type of
/// this argument/return, i.e., the result of `type_of::type_of`.
fn memory_ty(&self, cx: &CodegenCx<'ll, 'tcx>) -> &'ll Type {
self.layout.llvm_type(cx)
}

/// Stores a direct/indirect value described by this ArgAbi into a
/// place for the original Rust type of this argument/return.
/// Can be used for both storing formal arguments into Rust variables
Expand Down Expand Up @@ -302,9 +295,6 @@ impl<'ll, 'tcx> ArgAbiBuilderMethods<'tcx> for Builder<'_, 'll, 'tcx> {
) {
arg_abi.store(self, val, dst)
}
fn arg_memory_ty(&self, arg_abi: &ArgAbi<'tcx, Ty<'tcx>>) -> &'ll Type {
arg_abi.memory_ty(self)
}
}

pub(crate) trait FnAbiLlvmExt<'ll, 'tcx> {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_codegen_llvm/src/back/lto.rs
Original file line number Diff line number Diff line change
Expand Up @@ -799,7 +799,7 @@ impl Drop for ThinBuffer {
}
}

pub(crate) unsafe fn optimize_thin_module(
pub(crate) fn optimize_thin_module(
thin_module: ThinModule<LlvmCodegenBackend>,
cgcx: &CodegenContext<LlvmCodegenBackend>,
) -> Result<ModuleCodegen<ModuleLlvm>, FatalError> {
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_codegen_llvm/src/back/write.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,7 +704,7 @@ pub(crate) unsafe fn llvm_optimize(
}

// Unsafe due to LLVM calls.
pub(crate) unsafe fn optimize(
pub(crate) fn optimize(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: DiagCtxtHandle<'_>,
module: &mut ModuleCodegen<ModuleLlvm>,
Expand Down Expand Up @@ -815,7 +815,7 @@ pub(crate) fn link(
Ok(modules.remove(0))
}

pub(crate) unsafe fn codegen(
pub(crate) fn codegen(
cgcx: &CodegenContext<LlvmCodegenBackend>,
dcx: DiagCtxtHandle<'_>,
module: ModuleCodegen<ModuleLlvm>,
Expand Down
24 changes: 14 additions & 10 deletions compiler/rustc_codegen_llvm/src/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,17 +86,24 @@ pub(crate) fn compile_codegen_unit(
let mut cx = CodegenCx::new(tcx, cgu, &llvm_module);
let mono_items = cx.codegen_unit.items_in_deterministic_order(cx.tcx);
for &(mono_item, data) in &mono_items {
mono_item.predefine::<Builder<'_, '_, '_>>(&cx, data.linkage, data.visibility);
mono_item.predefine::<Builder<'_, '_, '_>>(
&mut cx,
cgu_name.as_str(),
data.linkage,
data.visibility,
);
}

// ... and now that we have everything pre-defined, fill out those definitions.
for &(mono_item, item_data) in &mono_items {
mono_item.define::<Builder<'_, '_, '_>>(&mut cx, item_data);
mono_item.define::<Builder<'_, '_, '_>>(&mut cx, cgu_name.as_str(), item_data);
}

// If this codegen unit contains the main function, also create the
// wrapper here
if let Some(entry) = maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx) {
if let Some(entry) =
maybe_create_entry_wrapper::<Builder<'_, '_, '_>>(&cx, cx.codegen_unit)
{
let attrs = attributes::sanitize_attrs(&cx, SanitizerSet::empty());
attributes::apply_to_llfn(entry, llvm::AttributePlace::Function, &attrs);
}
Expand All @@ -108,14 +115,11 @@ pub(crate) fn compile_codegen_unit(
}

// Create the llvm.used and llvm.compiler.used variables.
if !cx.used_statics.borrow().is_empty() {
cx.create_used_variable_impl(c"llvm.used", &*cx.used_statics.borrow());
if !cx.used_statics.is_empty() {
cx.create_used_variable_impl(c"llvm.used", &cx.used_statics);
}
if !cx.compiler_used_statics.borrow().is_empty() {
cx.create_used_variable_impl(
c"llvm.compiler.used",
&*cx.compiler_used_statics.borrow(),
);
if !cx.compiler_used_statics.is_empty() {
cx.create_used_variable_impl(c"llvm.compiler.used", &cx.compiler_used_statics);
}

// Run replace-all-uses-with for statics that need it. This must
Expand Down
26 changes: 13 additions & 13 deletions compiler/rustc_codegen_llvm/src/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ impl<'ll> CodegenCx<'ll, '_> {
g
}

fn codegen_static_item(&self, def_id: DefId) {
fn codegen_static_item(&mut self, def_id: DefId) {
unsafe {
assert!(
llvm::LLVMGetInitializer(
Expand Down Expand Up @@ -557,6 +557,17 @@ impl<'ll> CodegenCx<'ll, '_> {
}
}
}

/// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr.
pub(crate) fn add_used_global(&mut self, global: &'ll Value) {
self.used_statics.push(global);
}

/// Add a global value to a list to be stored in the `llvm.compiler.used` variable,
/// an array of ptr.
pub(crate) fn add_compiler_used_global(&mut self, global: &'ll Value) {
self.compiler_used_statics.push(global);
}
}

impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> {
Expand All @@ -571,18 +582,7 @@ impl<'ll> StaticCodegenMethods for CodegenCx<'ll, '_> {
self.const_pointercast(gv, self.type_ptr())
}

fn codegen_static(&self, def_id: DefId) {
fn codegen_static(&mut self, def_id: DefId) {
self.codegen_static_item(def_id)
}

/// Add a global value to a list to be stored in the `llvm.used` variable, an array of ptr.
fn add_used_global(&self, global: &'ll Value) {
self.used_statics.borrow_mut().push(global);
}

/// Add a global value to a list to be stored in the `llvm.compiler.used` variable,
/// an array of ptr.
fn add_compiler_used_global(&self, global: &'ll Value) {
self.compiler_used_statics.borrow_mut().push(global);
}
}
21 changes: 12 additions & 9 deletions compiler/rustc_codegen_llvm/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use std::borrow::Borrow;
use std::cell::{Cell, RefCell};
use std::ffi::{CStr, c_char, c_uint};
use std::marker::PhantomData;
use std::ops::Deref;
use std::ops::{Deref, DerefMut};
use std::str;

use rustc_abi::{HasDataLayout, Size, TargetDataLayout, VariantIdx};
Expand Down Expand Up @@ -77,6 +77,13 @@ impl<'ll, T: Borrow<SCx<'ll>>> Deref for GenericCx<'ll, T> {
}
}

impl<'ll, T: Borrow<SCx<'ll>>> DerefMut for GenericCx<'ll, T> {
#[inline]
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}

pub(crate) type SimpleCx<'ll> = GenericCx<'ll, SCx<'ll>>;

/// There is one `CodegenCx` per codegen unit. Each one has its own LLVM
Expand Down Expand Up @@ -110,11 +117,11 @@ pub(crate) struct FullCx<'ll, 'tcx> {

/// Statics that will be placed in the llvm.used variable
/// See <https://llvm.org/docs/LangRef.html#the-llvm-used-global-variable> for details
pub used_statics: RefCell<Vec<&'ll Value>>,
pub used_statics: Vec<&'ll Value>,

/// Statics that will be placed in the llvm.compiler.used variable
/// See <https://llvm.org/docs/LangRef.html#the-llvm-compiler-used-global-variable> for details
pub compiler_used_statics: RefCell<Vec<&'ll Value>>,
pub compiler_used_statics: Vec<&'ll Value>,

/// Mapping of non-scalar types to llvm types.
pub type_lowering: RefCell<FxHashMap<(Ty<'tcx>, Option<VariantIdx>), &'ll Type>>,
Expand Down Expand Up @@ -606,8 +613,8 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
const_str_cache: Default::default(),
const_globals: Default::default(),
statics_to_rauw: RefCell::new(Vec::new()),
used_statics: RefCell::new(Vec::new()),
compiler_used_statics: RefCell::new(Vec::new()),
used_statics: Vec::new(),
compiler_used_statics: Vec::new(),
type_lowering: Default::default(),
scalar_lltypes: Default::default(),
coverage_cx,
Expand Down Expand Up @@ -801,10 +808,6 @@ impl<'ll, 'tcx> MiscCodegenMethods<'tcx> for CodegenCx<'ll, 'tcx> {
self.tcx.sess
}

fn codegen_unit(&self) -> &'tcx CodegenUnit<'tcx> {
self.codegen_unit
}

fn set_frame_pointer_type(&self, llfn: &'ll Value) {
if let Some(attr) = attributes::frame_pointer_type_attr(self) {
attributes::apply_to_llfn(llfn, llvm::AttributePlace::Function, &[attr]);
Expand Down
Loading
Loading