about summary refs log tree commit diff
path: root/compiler/rustc_codegen_gcc/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_codegen_gcc/src/lib.rs')
-rw-r--r--compiler/rustc_codegen_gcc/src/lib.rs240
1 files changed, 158 insertions, 82 deletions
diff --git a/compiler/rustc_codegen_gcc/src/lib.rs b/compiler/rustc_codegen_gcc/src/lib.rs
index 09ce059476e..a4ee3015b8d 100644
--- a/compiler/rustc_codegen_gcc/src/lib.rs
+++ b/compiler/rustc_codegen_gcc/src/lib.rs
@@ -4,6 +4,7 @@
  * 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).
  * 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.
+ * Or the new incremental LTO?
  *
  * 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.
@@ -24,9 +25,10 @@
     hash_raw_entry
 )]
 #![allow(broken_intra_doc_links)]
-#![recursion_limit="256"]
+#![recursion_limit = "256"]
 #![warn(rust_2018_idioms)]
 #![warn(unused_lifetimes)]
+#![deny(clippy::pattern_type_mismatch)]
 
 extern crate rustc_apfloat;
 extern crate rustc_ast;
@@ -37,7 +39,8 @@ extern crate rustc_errors;
 extern crate rustc_fluent_macro;
 extern crate rustc_fs_util;
 extern crate rustc_hir;
-#[cfg(feature="master")]
+extern crate rustc_index;
+#[cfg(feature = "master")]
 extern crate rustc_interface;
 extern crate rustc_macros;
 extern crate rustc_metadata;
@@ -77,36 +80,40 @@ mod type_of;
 
 use std::any::Any;
 use std::fmt::Debug;
-use std::sync::Arc;
-use std::sync::Mutex;
-#[cfg(not(feature="master"))]
+#[cfg(not(feature = "master"))]
 use std::sync::atomic::AtomicBool;
-#[cfg(not(feature="master"))]
+#[cfg(not(feature = "master"))]
 use std::sync::atomic::Ordering;
+use std::sync::Arc;
+use std::sync::Mutex;
 
+use errors::LTONotSupported;
+#[cfg(not(feature = "master"))]
+use gccjit::CType;
 use gccjit::{Context, OptimizationLevel};
-#[cfg(feature="master")]
+#[cfg(feature = "master")]
 use gccjit::{TargetInfo, Version};
-#[cfg(not(feature="master"))]
-use gccjit::CType;
-use errors::LTONotSupported;
 use rustc_ast::expand::allocator::AllocatorKind;
-use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
-use rustc_codegen_ssa::base::codegen_crate;
-use rustc_codegen_ssa::back::write::{CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn};
 use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
+use rustc_codegen_ssa::back::write::{
+    CodegenContext, FatLtoInput, ModuleConfig, TargetMachineFactoryFn,
+};
+use rustc_codegen_ssa::base::codegen_crate;
+use rustc_codegen_ssa::traits::{
+    CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods,
+};
+use rustc_codegen_ssa::{CodegenResults, CompiledModule, ModuleCodegen};
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::IntoDynSyncSend;
-use rustc_codegen_ssa::traits::{CodegenBackend, ExtraBackendMethods, ThinBufferMethods, WriteBackendMethods};
-use rustc_errors::{ErrorGuaranteed, DiagCtxt};
+use rustc_errors::{DiagCtxt, ErrorGuaranteed};
 use rustc_metadata::EncodedMetadata;
 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
-use rustc_middle::util::Providers;
 use rustc_middle::ty::TyCtxt;
+use rustc_middle::util::Providers;
 use rustc_session::config::{Lto, OptLevel, OutputFilenames};
 use rustc_session::Session;
-use rustc_span::Symbol;
 use rustc_span::fatal_error::FatalError;
+use rustc_span::Symbol;
 use tempfile::TempDir;
 
 use crate::back::lto::ModuleBuffer;
@@ -124,13 +131,13 @@ impl<F: Fn() -> String> Drop for PrintOnPanic<F> {
     }
 }
 
-#[cfg(not(feature="master"))]
+#[cfg(not(feature = "master"))]
 #[derive(Debug)]
 pub struct TargetInfo {
     supports_128bit_integers: AtomicBool,
 }
 
-#[cfg(not(feature="master"))]
+#[cfg(not(feature = "master"))]
 impl TargetInfo {
     fn cpu_supports(&self, _feature: &str) -> bool {
         false
@@ -173,26 +180,26 @@ impl CodegenBackend for GccCodegenBackend {
     }
 
     fn init(&self, sess: &Session) {
-        #[cfg(feature="master")]
+        #[cfg(feature = "master")]
         {
             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" {
-                context.add_command_line_option(&format!("-march={}", target_cpu));
+                context.add_command_line_option(format!("-march={}", target_cpu));
             }
 
             **self.target_info.info.lock().expect("lock") = context.get_target_info();
         }
 
-        #[cfg(feature="master")]
+        #[cfg(feature = "master")]
         gccjit::set_global_personality_function_name(b"rust_eh_personality\0");
         if sess.lto() == Lto::Thin {
             sess.dcx().emit_warn(LTONotSupported {});
         }
 
-        #[cfg(not(feature="master"))]
+        #[cfg(not(feature = "master"))]
         {
             let temp_dir = TempDir::new().expect("cannot create temporary directory");
             let temp_file = temp_dir.into_path().join("result.asm");
@@ -200,39 +207,62 @@ impl CodegenBackend for GccCodegenBackend {
             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.
-            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);
+            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);
         }
     }
 
     fn provide(&self, providers: &mut Providers) {
-        providers.global_backend_features =
-            |tcx, ()| gcc_util::global_gcc_features(tcx.sess, true)
+        providers.global_backend_features = |tcx, ()| gcc_util::global_gcc_features(tcx.sess, true)
     }
 
-    fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>, metadata: EncodedMetadata, need_metadata_module: bool) -> Box<dyn Any> {
+    fn codegen_crate(
+        &self,
+        tcx: TyCtxt<'_>,
+        metadata: EncodedMetadata,
+        need_metadata_module: bool,
+    ) -> Box<dyn Any> {
         let target_cpu = target_cpu(tcx.sess);
-        let res = codegen_crate(self.clone(), tcx, target_cpu.to_string(), metadata, need_metadata_module);
+        let res = codegen_crate(
+            self.clone(),
+            tcx,
+            target_cpu.to_string(),
+            metadata,
+            need_metadata_module,
+        );
 
         Box::new(res)
     }
 
-    fn join_codegen(&self, ongoing_codegen: Box<dyn Any>, sess: &Session, _outputs: &OutputFilenames) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
+    fn join_codegen(
+        &self,
+        ongoing_codegen: Box<dyn Any>,
+        sess: &Session,
+        _outputs: &OutputFilenames,
+    ) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>) {
         ongoing_codegen
             .downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<GccCodegenBackend>>()
             .expect("Expected GccCodegenBackend's OngoingCodegen, found Box<Any>")
             .join(sess)
     }
 
-    fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) -> Result<(), ErrorGuaranteed> {
+    fn link(
+        &self,
+        sess: &Session,
+        codegen_results: CodegenResults,
+        outputs: &OutputFilenames,
+    ) -> Result<(), ErrorGuaranteed> {
         use rustc_codegen_ssa::back::link::link_binary;
 
-        link_binary(
-            sess,
-            &crate::archive::ArArchiveBuilderBuilder,
-            &codegen_results,
-            outputs,
-        )
+        link_binary(sess, &crate::archive::ArArchiveBuilderBuilder, &codegen_results, outputs)
     }
 
     fn target_features(&self, sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
@@ -245,13 +275,15 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> {
     if tcx.sess.target.arch == "x86" || tcx.sess.target.arch == "x86_64" {
         context.add_command_line_option("-masm=intel");
     }
-    #[cfg(feature="master")]
+    #[cfg(feature = "master")]
     {
+        context.set_special_chars_allowed_in_func_names("$.*");
         let version = Version::get();
         let version = format!("{}.{}.{}", version.major, version.minor, version.patch);
-        context.set_output_ident(&format!("rustc version {} with libgccjit {}",
-                rustc_interface::util::rustc_version_str().unwrap_or("unknown version"),
-                version,
+        context.set_output_ident(&format!(
+            "rustc version {} with libgccjit {}",
+            rustc_interface::util::rustc_version_str().unwrap_or("unknown version"),
+            version,
         ));
     }
     // TODO(antoyo): check if this should only be added when using -Cforce-unwind-tables=n.
@@ -260,26 +292,41 @@ fn new_context<'gcc, 'tcx>(tcx: TyCtxt<'tcx>) -> Context<'gcc> {
 }
 
 impl ExtraBackendMethods for GccCodegenBackend {
-    fn codegen_allocator<'tcx>(&self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind) -> Self::Module {
+    fn codegen_allocator(
+        &self,
+        tcx: TyCtxt<'_>,
+        module_name: &str,
+        kind: AllocatorKind,
+        alloc_error_handler_kind: AllocatorKind,
+    ) -> Self::Module {
         let mut mods = GccContext {
             context: new_context(tcx),
             should_combine_object_files: false,
             temp_dir: None,
         };
 
-        unsafe { allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind); }
+        unsafe {
+            allocator::codegen(tcx, &mut mods, module_name, kind, alloc_error_handler_kind);
+        }
         mods
     }
 
-    fn compile_codegen_unit(&self, tcx: TyCtxt<'_>, cgu_name: Symbol) -> (ModuleCodegen<Self::Module>, u64) {
+    fn compile_codegen_unit(
+        &self,
+        tcx: TyCtxt<'_>,
+        cgu_name: Symbol,
+    ) -> (ModuleCodegen<Self::Module>, u64) {
         base::compile_codegen_unit(tcx, cgu_name, self.target_info.clone())
     }
 
-    fn target_machine_factory(&self, _sess: &Session, _opt_level: OptLevel, _features: &[String]) -> TargetMachineFactoryFn<Self> {
+    fn target_machine_factory(
+        &self,
+        _sess: &Session,
+        _opt_level: OptLevel,
+        _features: &[String],
+    ) -> TargetMachineFactoryFn<Self> {
         // TODO(antoyo): set opt level.
-        Arc::new(|_| {
-            Ok(())
-        })
+        Arc::new(|_| Ok(()))
     }
 }
 
@@ -310,11 +357,19 @@ impl WriteBackendMethods for GccCodegenBackend {
     type ThinData = ();
     type ThinBuffer = ThinBuffer;
 
-    fn run_fat_lto(cgcx: &CodegenContext<Self>, modules: Vec<FatLtoInput<Self>>, cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>) -> Result<LtoModuleCodegen<Self>, FatalError> {
+    fn run_fat_lto(
+        cgcx: &CodegenContext<Self>,
+        modules: Vec<FatLtoInput<Self>>,
+        cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
+    ) -> Result<LtoModuleCodegen<Self>, FatalError> {
         back::lto::run_fat(cgcx, modules, cached_modules)
     }
 
-    fn run_thin_lto(_cgcx: &CodegenContext<Self>, _modules: Vec<(String, Self::ThinBuffer)>, _cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
+    fn run_thin_lto(
+        _cgcx: &CodegenContext<Self>,
+        _modules: Vec<(String, Self::ThinBuffer)>,
+        _cached_modules: Vec<(SerializedModule<Self::ModuleBuffer>, WorkProduct)>,
+    ) -> Result<(Vec<LtoModuleCodegen<Self>>, Vec<WorkProduct>), FatalError> {
         unimplemented!();
     }
 
@@ -326,21 +381,37 @@ impl WriteBackendMethods for GccCodegenBackend {
         unimplemented!()
     }
 
-    unsafe fn optimize(_cgcx: &CodegenContext<Self>, _dcx: &DiagCtxt, module: &ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<(), FatalError> {
+    unsafe fn optimize(
+        _cgcx: &CodegenContext<Self>,
+        _dcx: &DiagCtxt,
+        module: &ModuleCodegen<Self::Module>,
+        config: &ModuleConfig,
+    ) -> Result<(), FatalError> {
         module.module_llvm.context.set_optimization_level(to_gcc_opt_level(config.opt_level));
         Ok(())
     }
 
-    fn optimize_fat(_cgcx: &CodegenContext<Self>, _module: &mut ModuleCodegen<Self::Module>) -> Result<(), FatalError> {
+    fn optimize_fat(
+        _cgcx: &CodegenContext<Self>,
+        _module: &mut ModuleCodegen<Self::Module>,
+    ) -> Result<(), FatalError> {
         // TODO(antoyo)
         Ok(())
     }
 
-    unsafe fn optimize_thin(_cgcx: &CodegenContext<Self>, _thin: ThinModule<Self>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
+    unsafe fn optimize_thin(
+        _cgcx: &CodegenContext<Self>,
+        _thin: ThinModule<Self>,
+    ) -> Result<ModuleCodegen<Self::Module>, FatalError> {
         unimplemented!();
     }
 
-    unsafe fn codegen(cgcx: &CodegenContext<Self>, dcx: &DiagCtxt, module: ModuleCodegen<Self::Module>, config: &ModuleConfig) -> Result<CompiledModule, FatalError> {
+    unsafe fn codegen(
+        cgcx: &CodegenContext<Self>,
+        dcx: &DiagCtxt,
+        module: ModuleCodegen<Self::Module>,
+        config: &ModuleConfig,
+    ) -> Result<CompiledModule, FatalError> {
         back::write::codegen(cgcx, dcx, module, config)
     }
 
@@ -352,7 +423,11 @@ impl WriteBackendMethods for GccCodegenBackend {
         unimplemented!();
     }
 
-    fn run_link(cgcx: &CodegenContext<Self>, dcx: &DiagCtxt, modules: Vec<ModuleCodegen<Self::Module>>) -> Result<ModuleCodegen<Self::Module>, FatalError> {
+    fn run_link(
+        cgcx: &CodegenContext<Self>,
+        dcx: &DiagCtxt,
+        modules: Vec<ModuleCodegen<Self::Module>>,
+    ) -> Result<ModuleCodegen<Self::Module>, FatalError> {
         back::write::link(cgcx, dcx, modules)
     }
 }
@@ -360,56 +435,57 @@ impl WriteBackendMethods for GccCodegenBackend {
 /// This is the entrypoint for a hot plugged rustc_codegen_gccjit
 #[no_mangle]
 pub fn __rustc_codegen_backend() -> Box<dyn CodegenBackend> {
-    #[cfg(feature="master")]
+    #[cfg(feature = "master")]
     let info = {
         // Check whether the target supports 128-bit integers.
         let context = Context::default();
         Arc::new(Mutex::new(IntoDynSyncSend(context.get_target_info())))
     };
-    #[cfg(not(feature="master"))]
+    #[cfg(not(feature = "master"))]
     let info = Arc::new(Mutex::new(IntoDynSyncSend(TargetInfo {
         supports_128bit_integers: AtomicBool::new(false),
     })));
 
-    Box::new(GccCodegenBackend {
-        target_info: LockedTargetInfo { info },
-    })
+    Box::new(GccCodegenBackend { target_info: LockedTargetInfo { info } })
 }
 
 fn to_gcc_opt_level(optlevel: Option<OptLevel>) -> OptimizationLevel {
     match optlevel {
         None => OptimizationLevel::None,
-        Some(level) => {
-            match level {
-                OptLevel::No => OptimizationLevel::None,
-                OptLevel::Less => OptimizationLevel::Limited,
-                OptLevel::Default => OptimizationLevel::Standard,
-                OptLevel::Aggressive => OptimizationLevel::Aggressive,
-                OptLevel::Size | OptLevel::SizeMin => OptimizationLevel::Limited,
-            }
+        Some(level) => match level {
+            OptLevel::No => OptimizationLevel::None,
+            OptLevel::Less => OptimizationLevel::Limited,
+            OptLevel::Default => OptimizationLevel::Standard,
+            OptLevel::Aggressive => OptimizationLevel::Aggressive,
+            OptLevel::Size | OptLevel::SizeMin => OptimizationLevel::Limited,
         },
     }
 }
 
-pub fn target_features(sess: &Session, allow_unstable: bool, target_info: &LockedTargetInfo) -> Vec<Symbol> {
-    sess
-        .target
+pub fn target_features(
+    sess: &Session,
+    allow_unstable: bool,
+    target_info: &LockedTargetInfo,
+) -> Vec<Symbol> {
+    sess.target
         .supported_target_features()
         .iter()
-        .filter_map(
-            |&(feature, gate)| {
-                if sess.is_nightly_build() || allow_unstable || gate.is_stable() { Some(feature) } else { None }
-            },
-        )
+        .filter_map(|&(feature, gate)| {
+            if sess.is_nightly_build() || allow_unstable || gate.is_stable() {
+                Some(feature)
+            } else {
+                None
+            }
+        })
         .filter(|_feature| {
             target_info.cpu_supports(_feature)
             /*
-               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
-             */
+              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
+            */
         })
-        .map(|feature| Symbol::intern(feature))
+        .map(Symbol::intern)
         .collect()
 }