Improve generating Custom entry function
This commit is aimed at making compiler generated entry functions (Basically just C `main` right now) more generic so other targets can do similar things for custom entry. This was initially implemented as part of https://github.com/rust-lang/rust/pull/100316. Currently, this moves the entry function name and Call convention to the target spec. Signed-off-by: Ayush Singh <ayushsingh1325@gmail.com>
This commit is contained in:
parent
5b3e909075
commit
9f0a8620bd
7 changed files with 135 additions and 20 deletions
|
@ -398,23 +398,7 @@ impl<'ll, 'tcx> FnAbiLlvmExt<'ll, 'tcx> for FnAbi<'tcx, Ty<'tcx>> {
|
|||
}
|
||||
|
||||
fn llvm_cconv(&self) -> llvm::CallConv {
|
||||
match self.conv {
|
||||
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
|
||||
Conv::RustCold => llvm::ColdCallConv,
|
||||
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
|
||||
Conv::AvrInterrupt => llvm::AvrInterrupt,
|
||||
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
|
||||
Conv::ArmAapcs => llvm::ArmAapcsCallConv,
|
||||
Conv::Msp430Intr => llvm::Msp430Intr,
|
||||
Conv::PtxKernel => llvm::PtxKernel,
|
||||
Conv::X86Fastcall => llvm::X86FastcallCallConv,
|
||||
Conv::X86Intr => llvm::X86_Intr,
|
||||
Conv::X86Stdcall => llvm::X86StdcallCallConv,
|
||||
Conv::X86ThisCall => llvm::X86_ThisCall,
|
||||
Conv::X86VectorCall => llvm::X86_VectorCall,
|
||||
Conv::X86_64SysV => llvm::X86_64_SysV,
|
||||
Conv::X86_64Win64 => llvm::X86_64_Win64,
|
||||
}
|
||||
self.conv.into()
|
||||
}
|
||||
|
||||
fn apply_attrs_llfn(&self, cx: &CodegenCx<'ll, 'tcx>, llfn: &'ll Value) {
|
||||
|
@ -596,3 +580,25 @@ impl<'tcx> AbiBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
|
|||
llvm::get_param(self.llfn(), index as c_uint)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Conv> for llvm::CallConv {
|
||||
fn from(conv: Conv) -> Self {
|
||||
match conv {
|
||||
Conv::C | Conv::Rust | Conv::CCmseNonSecureCall => llvm::CCallConv,
|
||||
Conv::RustCold => llvm::ColdCallConv,
|
||||
Conv::AmdGpuKernel => llvm::AmdGpuKernel,
|
||||
Conv::AvrInterrupt => llvm::AvrInterrupt,
|
||||
Conv::AvrNonBlockingInterrupt => llvm::AvrNonBlockingInterrupt,
|
||||
Conv::ArmAapcs => llvm::ArmAapcsCallConv,
|
||||
Conv::Msp430Intr => llvm::Msp430Intr,
|
||||
Conv::PtxKernel => llvm::PtxKernel,
|
||||
Conv::X86Fastcall => llvm::X86FastcallCallConv,
|
||||
Conv::X86Intr => llvm::X86_Intr,
|
||||
Conv::X86Stdcall => llvm::X86StdcallCallConv,
|
||||
Conv::X86ThisCall => llvm::X86_ThisCall,
|
||||
Conv::X86VectorCall => llvm::X86_VectorCall,
|
||||
Conv::X86_64SysV => llvm::X86_64_SysV,
|
||||
Conv::X86_64Win64 => llvm::X86_64_Win64,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -570,8 +570,14 @@ impl<'ll, 'tcx> MiscMethods<'tcx> for CodegenCx<'ll, 'tcx> {
|
|||
}
|
||||
|
||||
fn declare_c_main(&self, fn_type: Self::Type) -> Option<Self::Function> {
|
||||
if self.get_declared_value("main").is_none() {
|
||||
Some(self.declare_cfn("main", llvm::UnnamedAddr::Global, fn_type))
|
||||
let entry_name = self.sess().target.entry_name.as_ref();
|
||||
if self.get_declared_value(entry_name).is_none() {
|
||||
Some(self.declare_entry_fn(
|
||||
entry_name,
|
||||
self.sess().target.entry_abi.into(),
|
||||
llvm::UnnamedAddr::Global,
|
||||
fn_type,
|
||||
))
|
||||
} else {
|
||||
// If the symbol already exists, it is an error: for example, the user wrote
|
||||
// #[no_mangle] extern "C" fn main(..) {..}
|
||||
|
|
|
@ -90,6 +90,28 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
|
|||
declare_raw_fn(self, name, llvm::CCallConv, unnamed, visibility, fn_type)
|
||||
}
|
||||
|
||||
/// Declare an entry Function
|
||||
///
|
||||
/// The ABI of this function can change depending on the target (although for now the same as
|
||||
/// `declare_cfn`)
|
||||
///
|
||||
/// If there’s a value with the same name already declared, the function will
|
||||
/// update the declaration and return existing Value instead.
|
||||
pub fn declare_entry_fn(
|
||||
&self,
|
||||
name: &str,
|
||||
callconv: llvm::CallConv,
|
||||
unnamed: llvm::UnnamedAddr,
|
||||
fn_type: &'ll Type,
|
||||
) -> &'ll Value {
|
||||
let visibility = if self.tcx.sess.target.default_hidden_visibility {
|
||||
llvm::Visibility::Hidden
|
||||
} else {
|
||||
llvm::Visibility::Default
|
||||
};
|
||||
declare_raw_fn(self, name, callconv, unnamed, visibility, fn_type)
|
||||
}
|
||||
|
||||
/// Declare a Rust function.
|
||||
///
|
||||
/// If there’s a value with the same name already declared, the function will
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue