2020-05-10 14:54:30 +00:00
/*
2022-03-26 17:29:37 +00:00
* TODO ( antoyo ) : implement equality in libgccjit based on https ://zpz.github.io/blog/overloading-equality-operator-in-cpp-class-hierarchy/ (for type equality?)
2021-08-15 12:28:46 +00:00
* TODO ( antoyo ) : support #[ inline ] attributes .
2023-03-05 17:03:19 +00:00
* TODO ( antoyo ) : support LTO ( gcc ' s equivalent to Full LTO is - flto - flto - partition = one — https ://documentation.suse.com/sbp/all/html/SBP-GCC-10/index.html).
2023-10-09 19:53:34 +00:00
* For Thin LTO , this might be helpful :
* In gcc 4.6 - fwhopr was removed and became default with - flto . The non - whopr path can still be executed via - flto - partition = none .
2024-07-10 10:44:23 +00:00
* Or the new incremental LTO ( https ://www.phoronix.com/news/GCC-Incremental-LTO-Patches)?
2023-10-09 19:53:34 +00:00
*
* Maybe some missing optizations enabled by rustc ' s LTO is in there : https ://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html
* Like - fipa - icf ( should be already enabled ) and maybe - fdevirtualize - at - ltrans .
* TODO : disable debug info always being emitted . Perhaps this slows down things ?
2020-05-10 14:54:30 +00:00
*
2021-08-15 12:28:46 +00:00
* TODO ( antoyo ) : remove the patches .
2020-05-10 14:54:30 +00:00
* /
2023-11-13 12:39:17 +00:00
#![ allow(internal_features) ]
#![ doc(rust_logo) ]
#![ feature(rustdoc_internals) ]
2024-07-10 10:44:23 +00:00
#![ feature(rustc_private, decl_macro, never_type, trusted_len, hash_raw_entry, let_chains) ]
2020-05-10 14:54:30 +00:00
#![ allow(broken_intra_doc_links) ]
2024-03-05 18:58:36 +00:00
#![ recursion_limit = " 256 " ]
2020-05-10 14:54:30 +00:00
#![ warn(rust_2018_idioms) ]
#![ warn(unused_lifetimes) ]
2024-03-05 18:58:36 +00:00
#![ deny(clippy::pattern_type_mismatch) ]
2024-07-10 10:44:23 +00:00
#![ allow(clippy::needless_lifetimes) ]
2020-05-10 14:54:30 +00:00
2024-09-02 03:59:12 +00:00
// Some "regular" crates we want to share with rustc
extern crate object ;
extern crate smallvec ;
2025-01-10 19:32:01 +00:00
// FIXME(antoyo): clippy bug: remove the #[allow] when it's fixed.
2024-12-11 18:49:37 +00:00
#[ allow(unused_extern_crates) ]
2024-09-02 03:59:12 +00:00
extern crate tempfile ;
#[ macro_use ]
extern crate tracing ;
// The rustc crates we need
2024-10-09 00:27:02 +00:00
extern crate rustc_abi ;
2022-08-16 22:46:17 +00:00
extern crate rustc_apfloat ;
2020-05-10 14:54:30 +00:00
extern crate rustc_ast ;
2024-12-13 13:47:11 +00:00
extern crate rustc_attr_parsing ;
2020-05-10 14:54:30 +00:00
extern crate rustc_codegen_ssa ;
extern crate rustc_data_structures ;
extern crate rustc_errors ;
2023-04-16 12:33:00 +00:00
extern crate rustc_fluent_macro ;
2023-10-09 19:53:34 +00:00
extern crate rustc_fs_util ;
2020-05-10 14:54:30 +00:00
extern crate rustc_hir ;
2024-03-05 18:58:36 +00:00
extern crate rustc_index ;
#[ cfg(feature = " master " ) ]
2023-11-19 18:42:13 +00:00
extern crate rustc_interface ;
2022-08-27 02:32:04 +00:00
extern crate rustc_macros ;
2020-05-10 14:54:30 +00:00
extern crate rustc_metadata ;
extern crate rustc_middle ;
extern crate rustc_session ;
extern crate rustc_span ;
extern crate rustc_target ;
// This prevents duplicating functions and statics that are already part of the host rustc process.
#[ allow(unused_extern_crates) ]
extern crate rustc_driver ;
mod abi ;
mod allocator ;
mod asm ;
2023-03-05 17:03:19 +00:00
mod attributes ;
2020-05-10 14:54:30 +00:00
mod back ;
mod base ;
mod builder ;
mod callee ;
mod common ;
mod consts ;
mod context ;
mod coverageinfo ;
mod debuginfo ;
mod declare ;
2022-08-27 02:32:04 +00:00
mod errors ;
2023-10-09 19:53:34 +00:00
mod gcc_util ;
2022-03-26 17:29:37 +00:00
mod int ;
2020-05-10 14:54:30 +00:00
mod intrinsic ;
mod mono_item ;
mod type_ ;
mod type_of ;
use std ::any ::Any ;
2023-10-09 20:45:46 +00:00
use std ::fmt ::Debug ;
2024-07-10 10:44:23 +00:00
use std ::ops ::Deref ;
2024-03-05 18:58:36 +00:00
#[ cfg(not(feature = " master " )) ]
2023-10-09 19:53:34 +00:00
use std ::sync ::atomic ::AtomicBool ;
2024-03-05 18:58:36 +00:00
#[ cfg(not(feature = " master " )) ]
2023-10-09 19:53:34 +00:00
use std ::sync ::atomic ::Ordering ;
2024-07-28 22:13:50 +00:00
use std ::sync ::{ Arc , Mutex } ;
2023-10-09 19:53:34 +00:00
2024-07-28 22:13:50 +00:00
use back ::lto ::{ ThinBuffer , ThinData } ;
use gccjit ::{ CType , Context , OptimizationLevel } ;
2024-03-05 18:58:36 +00:00
#[ cfg(feature = " master " ) ]
2023-11-19 18:42:13 +00:00
use gccjit ::{ TargetInfo , Version } ;
2020-05-10 14:54:30 +00:00
use rustc_ast ::expand ::allocator ::AllocatorKind ;
2025-01-01 20:42:45 +00:00
use rustc_ast ::expand ::autodiff_attrs ::AutoDiffItem ;
2020-05-10 14:54:30 +00:00
use rustc_codegen_ssa ::back ::lto ::{ LtoModuleCodegen , SerializedModule , ThinModule } ;
2024-03-05 18:58:36 +00:00
use rustc_codegen_ssa ::back ::write ::{
CodegenContext , FatLtoInput , ModuleConfig , TargetMachineFactoryFn ,
} ;
use rustc_codegen_ssa ::base ::codegen_crate ;
2024-07-10 10:44:23 +00:00
use rustc_codegen_ssa ::traits ::{ CodegenBackend , ExtraBackendMethods , WriteBackendMethods } ;
2024-03-05 18:58:36 +00:00
use rustc_codegen_ssa ::{ CodegenResults , CompiledModule , ModuleCodegen } ;
2023-04-07 19:56:33 +00:00
use rustc_data_structures ::fx ::FxIndexMap ;
2023-10-09 20:45:46 +00:00
use rustc_data_structures ::sync ::IntoDynSyncSend ;
2024-11-09 20:42:56 +00:00
use rustc_errors ::DiagCtxtHandle ;
2021-09-30 18:22:42 +00:00
use rustc_metadata ::EncodedMetadata ;
2020-05-10 14:54:30 +00:00
use rustc_middle ::dep_graph ::{ WorkProduct , WorkProductId } ;
use rustc_middle ::ty ::TyCtxt ;
2024-03-05 18:58:36 +00:00
use rustc_middle ::util ::Providers ;
2020-05-10 14:54:30 +00:00
use rustc_session ::Session ;
2025-01-12 14:06:40 +00:00
use rustc_session ::config ::{ OptLevel , OutputFilenames } ;
2024-03-05 18:58:36 +00:00
use rustc_span ::Symbol ;
2024-09-22 23:05:04 +00:00
use rustc_span ::fatal_error ::FatalError ;
2025-01-11 01:51:23 +00:00
use rustc_target ::spec ::RelocModel ;
2022-03-26 17:29:37 +00:00
use tempfile ::TempDir ;
2020-05-10 14:54:30 +00:00
2023-10-09 19:53:34 +00:00
use crate ::back ::lto ::ModuleBuffer ;
use crate ::gcc_util ::target_cpu ;
2023-11-21 22:53:07 +00:00
rustc_fluent_macro ::fluent_messages! { " ../messages.ftl " }
2022-10-13 09:13:02 +00:00
2020-05-10 14:54:30 +00:00
pub struct PrintOnPanic < F : Fn ( ) -> String > ( pub F ) ;
impl < F : Fn ( ) -> String > Drop for PrintOnPanic < F > {
fn drop ( & mut self ) {
if ::std ::thread ::panicking ( ) {
println! ( " {} " , ( self . 0 ) ( ) ) ;
}
}
}
2024-03-05 18:58:36 +00:00
#[ cfg(not(feature = " master " )) ]
2023-10-09 19:53:34 +00:00
#[ derive(Debug) ]
pub struct TargetInfo {
supports_128bit_integers : AtomicBool ,
}
2024-03-05 18:58:36 +00:00
#[ cfg(not(feature = " master " )) ]
2023-10-09 19:53:34 +00:00
impl TargetInfo {
fn cpu_supports ( & self , _feature : & str ) -> bool {
false
}
2024-10-17 00:55:56 +00:00
fn supports_target_dependent_type ( & self , typ : CType ) -> bool {
match typ {
CType ::UInt128t | CType ::Int128t = > {
if self . supports_128bit_integers . load ( Ordering ::SeqCst ) {
return true ;
}
}
_ = > ( ) ,
}
2024-07-10 10:44:23 +00:00
false
}
2023-10-09 19:53:34 +00:00
}
2023-10-09 20:45:46 +00:00
#[ derive(Clone) ]
2023-10-09 19:53:34 +00:00
pub struct LockedTargetInfo {
2023-10-09 20:45:46 +00:00
info : Arc < Mutex < IntoDynSyncSend < TargetInfo > > > ,
}
impl Debug for LockedTargetInfo {
fn fmt ( & self , formatter : & mut std ::fmt ::Formatter < '_ > ) -> std ::fmt ::Result {
self . info . lock ( ) . expect ( " lock " ) . fmt ( formatter )
}
2023-10-09 19:53:34 +00:00
}
impl LockedTargetInfo {
fn cpu_supports ( & self , feature : & str ) -> bool {
self . info . lock ( ) . expect ( " lock " ) . cpu_supports ( feature )
}
2024-07-10 10:44:23 +00:00
fn supports_target_dependent_type ( & self , typ : CType ) -> bool {
self . info . lock ( ) . expect ( " lock " ) . supports_target_dependent_type ( typ )
}
2023-10-09 19:53:34 +00:00
}
2020-05-10 14:54:30 +00:00
#[ derive(Clone) ]
2022-03-26 17:29:37 +00:00
pub struct GccCodegenBackend {
2023-10-09 19:53:34 +00:00
target_info : LockedTargetInfo ,
2022-03-26 17:29:37 +00:00
}
2020-05-10 14:54:30 +00:00
impl CodegenBackend for GccCodegenBackend {
2022-10-17 13:11:26 +00:00
fn locale_resource ( & self ) -> & 'static str {
crate ::DEFAULT_LOCALE_RESOURCE
}
2020-05-10 14:54:30 +00:00
fn init ( & self , sess : & Session ) {
2024-03-05 18:58:36 +00:00
#[ cfg(feature = " master " ) ]
2023-10-09 19:53:34 +00:00
{
let target_cpu = target_cpu ( sess ) ;
// Get the second TargetInfo with the correct CPU features by setting the arch.
let context = Context ::default ( ) ;
if target_cpu ! = " generic " {
2024-03-05 18:58:36 +00:00
context . add_command_line_option ( format! ( " -march= {} " , target_cpu ) ) ;
2023-10-09 19:53:34 +00:00
}
2023-10-09 20:45:46 +00:00
* * self . target_info . info . lock ( ) . expect ( " lock " ) = context . get_target_info ( ) ;
2023-10-09 19:53:34 +00:00
}
2024-03-05 18:58:36 +00:00
#[ cfg(feature = " master " ) ]
2023-06-19 22:51:02 +00:00
gccjit ::set_global_personality_function_name ( b " rust_eh_personality \0 " ) ;
2024-07-10 10:44:23 +00:00
2024-03-05 18:58:36 +00:00
#[ cfg(not(feature = " master " )) ]
2023-10-09 19:53:34 +00:00
{
let temp_dir = TempDir ::new ( ) . expect ( " cannot create temporary directory " ) ;
let temp_file = temp_dir . into_path ( ) . join ( " result.asm " ) ;
let check_context = Context ::default ( ) ;
check_context . set_print_errors_to_stderr ( false ) ;
let _int128_ty = check_context . new_c_type ( CType ::UInt128t ) ;
// NOTE: we cannot just call compile() as this would require other files than libgccjit.so.
2024-03-05 18:58:36 +00:00
check_context . compile_to_file (
gccjit ::OutputKind ::Assembler ,
temp_file . to_str ( ) . expect ( " path to str " ) ,
) ;
self . target_info
. info
. lock ( )
. expect ( " lock " )
. supports_128bit_integers
. store ( check_context . get_last_error ( ) = = Ok ( None ) , Ordering ::SeqCst ) ;
2023-10-09 19:53:34 +00:00
}
2022-03-26 17:29:37 +00:00
}
2023-09-22 16:26:20 +00:00
fn provide ( & self , providers : & mut Providers ) {
2024-03-05 18:58:36 +00:00
providers . global_backend_features = | tcx , ( ) | gcc_util ::global_gcc_features ( tcx . sess , true )
2020-05-10 14:54:30 +00:00
}
2024-03-05 18:58:36 +00:00
fn codegen_crate (
& self ,
tcx : TyCtxt < '_ > ,
metadata : EncodedMetadata ,
need_metadata_module : bool ,
) -> Box < dyn Any > {
2020-05-10 14:54:30 +00:00
let target_cpu = target_cpu ( tcx . sess ) ;
2024-03-05 18:58:36 +00:00
let res = codegen_crate (
self . clone ( ) ,
tcx ,
target_cpu . to_string ( ) ,
metadata ,
need_metadata_module ,
) ;
2020-05-10 14:54:30 +00:00
Box ::new ( res )
}
2024-03-05 18:58:36 +00:00
fn join_codegen (
& self ,
ongoing_codegen : Box < dyn Any > ,
sess : & Session ,
_outputs : & OutputFilenames ,
) -> ( CodegenResults , FxIndexMap < WorkProductId , WorkProduct > ) {
2024-02-16 23:51:35 +00:00
ongoing_codegen
2020-05-10 14:54:30 +00:00
. downcast ::< rustc_codegen_ssa ::back ::write ::OngoingCodegen < GccCodegenBackend > > ( )
. expect ( " Expected GccCodegenBackend's OngoingCodegen, found Box<Any> " )
2024-02-16 23:51:35 +00:00
. join ( sess )
2020-05-10 14:54:30 +00:00
}
2024-11-16 09:00:16 +00:00
fn target_features_cfg ( & self , sess : & Session , allow_unstable : bool ) -> Vec < Symbol > {
target_features_cfg ( sess , allow_unstable , & self . target_info )
2020-05-10 14:54:30 +00:00
}
}
2023-11-19 18:51:56 +00:00
fn new_context < ' gcc , ' tcx > ( tcx : TyCtxt < ' tcx > ) -> Context < ' gcc > {
2023-11-19 18:42:13 +00:00
let context = Context ::default ( ) ;
if tcx . sess . target . arch = = " x86 " | | tcx . sess . target . arch = = " x86_64 " {
context . add_command_line_option ( " -masm=intel " ) ;
}
2024-03-05 18:58:36 +00:00
#[ cfg(feature = " master " ) ]
2023-11-19 18:42:13 +00:00
{
2024-03-05 18:58:36 +00:00
context . set_special_chars_allowed_in_func_names ( " $.* " ) ;
2023-11-19 18:42:13 +00:00
let version = Version ::get ( ) ;
let version = format! ( " {} . {} . {} " , version . major , version . minor , version . patch ) ;
2024-03-05 18:58:36 +00:00
context . set_output_ident ( & format! (
" rustc version {} with libgccjit {} " ,
rustc_interface ::util ::rustc_version_str ( ) . unwrap_or ( " unknown version " ) ,
version ,
2023-11-19 18:42:13 +00:00
) ) ;
}
// TODO(antoyo): check if this should only be added when using -Cforce-unwind-tables=n.
context . add_command_line_option ( " -fno-asynchronous-unwind-tables " ) ;
context
}
2020-05-10 14:54:30 +00:00
impl ExtraBackendMethods for GccCodegenBackend {
2024-03-05 18:58:36 +00:00
fn codegen_allocator (
& self ,
tcx : TyCtxt < '_ > ,
module_name : & str ,
kind : AllocatorKind ,
alloc_error_handler_kind : AllocatorKind ,
) -> Self ::Module {
2022-04-30 19:20:08 +00:00
let mut mods = GccContext {
2024-07-10 10:44:23 +00:00
context : Arc ::new ( SyncContext ::new ( new_context ( tcx ) ) ) ,
2025-01-11 01:51:23 +00:00
relocation_model : tcx . sess . relocation_model ( ) ,
2023-10-09 19:53:34 +00:00
should_combine_object_files : false ,
temp_dir : None ,
2022-04-30 19:20:08 +00:00
} ;
2023-10-09 19:53:34 +00:00
2024-03-05 18:58:36 +00:00
unsafe {
allocator ::codegen ( tcx , & mut mods , module_name , kind , alloc_error_handler_kind ) ;
}
2022-04-30 19:20:08 +00:00
mods
2020-05-10 14:54:30 +00:00
}
2024-03-05 18:58:36 +00:00
fn compile_codegen_unit (
& self ,
tcx : TyCtxt < '_ > ,
cgu_name : Symbol ,
) -> ( ModuleCodegen < Self ::Module > , u64 ) {
2023-10-09 19:53:34 +00:00
base ::compile_codegen_unit ( tcx , cgu_name , self . target_info . clone ( ) )
2020-05-10 14:54:30 +00:00
}
2024-03-05 18:58:36 +00:00
fn target_machine_factory (
& self ,
_sess : & Session ,
_opt_level : OptLevel ,
_features : & [ String ] ,
) -> TargetMachineFactoryFn < Self > {
2021-08-15 12:28:46 +00:00
// TODO(antoyo): set opt level.
2024-03-05 18:58:36 +00:00
Arc ::new ( | _ | Ok ( ( ) ) )
2020-05-10 14:54:30 +00:00
}
}
2024-07-10 10:44:23 +00:00
pub struct GccContext {
context : Arc < SyncContext > ,
2025-01-11 01:51:23 +00:00
/// This field is needed in order to be able to set the flag -fPIC when necessary when doing
/// LTO.
relocation_model : RelocModel ,
2024-07-10 10:44:23 +00:00
should_combine_object_files : bool ,
// Temporary directory used by LTO. We keep it here so that it's not removed before linking.
temp_dir : Option < TempDir > ,
}
2020-05-10 14:54:30 +00:00
2024-07-10 10:44:23 +00:00
struct SyncContext {
context : Context < 'static > ,
}
2024-01-19 19:42:43 +00:00
2024-07-10 10:44:23 +00:00
impl SyncContext {
fn new ( context : Context < 'static > ) -> Self {
Self { context }
2024-01-19 19:42:43 +00:00
}
2020-05-10 14:54:30 +00:00
}
2024-07-10 10:44:23 +00:00
impl Deref for SyncContext {
type Target = Context < 'static > ;
fn deref ( & self ) -> & Self ::Target {
& self . context
}
2020-05-10 14:54:30 +00:00
}
2024-07-10 10:44:23 +00:00
unsafe impl Send for SyncContext { }
// FIXME(antoyo): that shouldn't be Sync. Parallel compilation is currently disabled with "-Zno-parallel-llvm".
2024-09-27 20:00:17 +00:00
// TODO: disable it here by returning false in CodegenBackend::supports_parallel().
2024-07-10 10:44:23 +00:00
unsafe impl Sync for SyncContext { }
2020-05-10 14:54:30 +00:00
impl WriteBackendMethods for GccCodegenBackend {
type Module = GccContext ;
type TargetMachine = ( ) ;
2022-08-19 13:48:15 +00:00
type TargetMachineError = ( ) ;
2020-05-10 14:54:30 +00:00
type ModuleBuffer = ModuleBuffer ;
2024-07-10 10:44:23 +00:00
type ThinData = ThinData ;
2020-05-10 14:54:30 +00:00
type ThinBuffer = ThinBuffer ;
2024-03-05 18:58:36 +00:00
fn run_fat_lto (
cgcx : & CodegenContext < Self > ,
modules : Vec < FatLtoInput < Self > > ,
cached_modules : Vec < ( SerializedModule < Self ::ModuleBuffer > , WorkProduct ) > ,
) -> Result < LtoModuleCodegen < Self > , FatalError > {
2023-10-09 19:53:34 +00:00
back ::lto ::run_fat ( cgcx , modules , cached_modules )
2020-05-10 14:54:30 +00:00
}
2024-03-05 18:58:36 +00:00
fn run_thin_lto (
2024-07-10 10:44:23 +00:00
cgcx : & CodegenContext < Self > ,
modules : Vec < ( String , Self ::ThinBuffer ) > ,
cached_modules : Vec < ( SerializedModule < Self ::ModuleBuffer > , WorkProduct ) > ,
2024-03-05 18:58:36 +00:00
) -> Result < ( Vec < LtoModuleCodegen < Self > > , Vec < WorkProduct > ) , FatalError > {
2024-07-10 10:44:23 +00:00
back ::lto ::run_thin ( cgcx , modules , cached_modules )
2020-05-10 14:54:30 +00:00
}
fn print_pass_timings ( & self ) {
unimplemented! ( ) ;
}
2022-11-05 08:08:57 +00:00
fn print_statistics ( & self ) {
unimplemented! ( )
}
2024-03-05 18:58:36 +00:00
unsafe fn optimize (
_cgcx : & CodegenContext < Self > ,
2024-06-18 10:35:56 +00:00
_dcx : DiagCtxtHandle < '_ > ,
2025-02-06 14:00:19 +00:00
module : & mut ModuleCodegen < Self ::Module > ,
2024-03-05 18:58:36 +00:00
config : & ModuleConfig ,
) -> Result < ( ) , FatalError > {
2020-05-10 14:54:30 +00:00
module . module_llvm . context . set_optimization_level ( to_gcc_opt_level ( config . opt_level ) ) ;
Ok ( ( ) )
}
2024-03-05 18:58:36 +00:00
fn optimize_fat (
_cgcx : & CodegenContext < Self > ,
_module : & mut ModuleCodegen < Self ::Module > ,
) -> Result < ( ) , FatalError > {
2022-04-30 18:50:17 +00:00
// TODO(antoyo)
Ok ( ( ) )
}
2024-03-05 18:58:36 +00:00
unsafe fn optimize_thin (
2024-07-10 10:44:23 +00:00
cgcx : & CodegenContext < Self > ,
thin : ThinModule < Self > ,
2024-03-05 18:58:36 +00:00
) -> Result < ModuleCodegen < Self ::Module > , FatalError > {
2024-07-10 10:44:23 +00:00
back ::lto ::optimize_thin_module ( thin , cgcx )
2020-05-10 14:54:30 +00:00
}
2024-03-05 18:58:36 +00:00
unsafe fn codegen (
cgcx : & CodegenContext < Self > ,
2024-06-18 10:35:56 +00:00
dcx : DiagCtxtHandle < '_ > ,
2024-03-05 18:58:36 +00:00
module : ModuleCodegen < Self ::Module > ,
config : & ModuleConfig ,
) -> Result < CompiledModule , FatalError > {
2023-12-17 23:15:45 +00:00
back ::write ::codegen ( cgcx , dcx , module , config )
2020-05-10 14:54:30 +00:00
}
2024-06-18 10:35:56 +00:00
fn prepare_thin (
2024-07-10 10:44:23 +00:00
module : ModuleCodegen < Self ::Module > ,
emit_summary : bool ,
2024-06-18 10:35:56 +00:00
) -> ( String , Self ::ThinBuffer ) {
2024-07-10 10:44:23 +00:00
back ::lto ::prepare_thin ( module , emit_summary )
2020-05-10 14:54:30 +00:00
}
fn serialize_module ( _module : ModuleCodegen < Self ::Module > ) -> ( String , Self ::ModuleBuffer ) {
unimplemented! ( ) ;
}
2024-03-05 18:58:36 +00:00
fn run_link (
cgcx : & CodegenContext < Self > ,
2024-06-18 10:35:56 +00:00
dcx : DiagCtxtHandle < '_ > ,
2024-03-05 18:58:36 +00:00
modules : Vec < ModuleCodegen < Self ::Module > > ,
) -> Result < ModuleCodegen < Self ::Module > , FatalError > {
2023-12-17 23:15:45 +00:00
back ::write ::link ( cgcx , dcx , modules )
2020-05-10 14:54:30 +00:00
}
2025-01-01 20:42:45 +00:00
fn autodiff (
_cgcx : & CodegenContext < Self > ,
_module : & ModuleCodegen < Self ::Module > ,
_diff_fncs : Vec < AutoDiffItem > ,
_config : & ModuleConfig ,
) -> Result < ( ) , FatalError > {
unimplemented! ( )
}
2020-05-10 14:54:30 +00:00
}
/// This is the entrypoint for a hot plugged rustc_codegen_gccjit
#[ no_mangle ]
pub fn __rustc_codegen_backend ( ) -> Box < dyn CodegenBackend > {
2024-03-05 18:58:36 +00:00
#[ cfg(feature = " master " ) ]
2023-10-09 19:53:34 +00:00
let info = {
2024-07-10 10:44:23 +00:00
// Check whether the target supports 128-bit integers, and sized floating point types (like
// Float16).
2023-10-09 19:53:34 +00:00
let context = Context ::default ( ) ;
2023-10-09 20:45:46 +00:00
Arc ::new ( Mutex ::new ( IntoDynSyncSend ( context . get_target_info ( ) ) ) )
2023-10-09 19:53:34 +00:00
} ;
2024-03-05 18:58:36 +00:00
#[ cfg(not(feature = " master " )) ]
2023-10-09 20:45:46 +00:00
let info = Arc ::new ( Mutex ::new ( IntoDynSyncSend ( TargetInfo {
2023-10-09 19:53:34 +00:00
supports_128bit_integers : AtomicBool ::new ( false ) ,
2023-10-09 20:45:46 +00:00
} ) ) ) ;
2023-10-09 19:53:34 +00:00
2024-03-05 18:58:36 +00:00
Box ::new ( GccCodegenBackend { target_info : LockedTargetInfo { info } } )
2020-05-10 14:54:30 +00:00
}
fn to_gcc_opt_level ( optlevel : Option < OptLevel > ) -> OptimizationLevel {
match optlevel {
None = > OptimizationLevel ::None ,
2024-03-05 18:58:36 +00:00
Some ( level ) = > match level {
OptLevel ::No = > OptimizationLevel ::None ,
OptLevel ::Less = > OptimizationLevel ::Limited ,
2025-01-13 15:52:08 +00:00
OptLevel ::More = > OptimizationLevel ::Standard ,
2024-03-05 18:58:36 +00:00
OptLevel ::Aggressive = > OptimizationLevel ::Aggressive ,
OptLevel ::Size | OptLevel ::SizeMin = > OptimizationLevel ::Limited ,
2020-05-10 14:54:30 +00:00
} ,
}
}
2024-11-16 09:00:16 +00:00
/// Returns the features that should be set in `cfg(target_feature)`.
fn target_features_cfg (
2024-03-05 18:58:36 +00:00
sess : & Session ,
allow_unstable : bool ,
target_info : & LockedTargetInfo ,
) -> Vec < Symbol > {
2024-07-10 10:44:23 +00:00
// TODO(antoyo): use global_gcc_features.
2024-03-05 18:58:36 +00:00
sess . target
2024-09-02 09:45:59 +00:00
. rust_target_features ( )
2020-05-10 14:54:30 +00:00
. iter ( )
2025-01-13 00:47:47 +00:00
. filter_map ( | & ( feature , gate , _ ) | {
2025-01-27 17:30:17 +00:00
if allow_unstable
| | ( gate . in_cfg ( ) & & ( sess . is_nightly_build ( ) | | gate . requires_nightly ( ) . is_none ( ) ) )
{
2025-01-13 00:47:47 +00:00
Some ( feature )
2024-03-05 18:58:36 +00:00
} else {
None
}
} )
2024-07-10 10:44:23 +00:00
. filter ( | feature | {
// TODO: we disable Neon for now since we don't support the LLVM intrinsics for it.
if * feature = = " neon " {
return false ;
}
target_info . cpu_supports ( feature )
2022-06-07 02:04:37 +00:00
/*
2024-03-05 18:58:36 +00:00
adx , aes , avx , avx2 , avx512bf16 , avx512bitalg , avx512bw , avx512cd , avx512dq , avx512er , avx512f , avx512fp16 , avx512ifma ,
avx512pf , avx512vbmi , avx512vbmi2 , avx512vl , avx512vnni , avx512vp2intersect , avx512vpopcntdq ,
bmi1 , bmi2 , cmpxchg16b , ermsb , f16c , fma , fxsr , gfni , lzcnt , movbe , pclmulqdq , popcnt , rdrand , rdseed , rtm ,
sha , sse , sse2 , sse3 , sse4 . 1 , sse4 . 2 , sse4a , ssse3 , tbm , vaes , vpclmulqdq , xsave , xsavec , xsaveopt , xsaves
* /
2020-05-10 14:54:30 +00:00
} )
2024-03-05 18:58:36 +00:00
. map ( Symbol ::intern )
2020-05-10 14:54:30 +00:00
. collect ( )
}