Skip to main content

rustc_codegen_ssa/traits/
backend.rs

1use std::any::Any;
2use std::hash::Hash;
3
4use rustc_ast::expand::allocator::AllocatorMethod;
5use rustc_data_structures::sync::{DynSend, DynSync};
6use rustc_metadata::EncodedMetadata;
7use rustc_metadata::creader::MetadataLoaderDyn;
8use rustc_middle::dep_graph::WorkProductMap;
9use rustc_middle::ty::TyCtxt;
10use rustc_middle::util::Providers;
11use rustc_session::config::{OutputFilenames, PrintRequest};
12use rustc_session::{CodegenBackendInit, EarlySession, IncrCompSession, Session};
13use rustc_span::Symbol;
14use rustc_structures::CrateType;
15
16use super::CodegenObject;
17use crate::back::archive::ArArchiveBuilderBuilder;
18use crate::back::link::link_binary;
19use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
20
21pub trait BackendTypes {
22    type Function: CodegenObject;
23    type BasicBlock: Copy;
24    type Funclet;
25
26    type Value: CodegenObject + PartialEq;
27    type Type: CodegenObject + PartialEq;
28    type FunctionSignature: CodegenObject + PartialEq;
29
30    // FIXME(eddyb) find a common convention for all of the debuginfo-related
31    // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.).
32    type DIScope: Copy + Hash + PartialEq + Eq;
33    type DILocation: Copy;
34    type DIVariable: Copy;
35}
36
37pub trait CodegenBackend {
38    fn name(&self) -> &'static str;
39
40    fn init(&mut self, _sess: &EarlySession) -> CodegenBackendInit {
41        Default::default()
42    }
43
44    fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
45
46    /// Collect target-specific options that should be set in `cfg(...)`, including
47    /// `target_feature` and support for unstable float types.
48    fn target_config(&self, _sess: &EarlySession) -> TargetConfig {
49        TargetConfig {
50            internal_target_features: Default::default(),
51            // `true` is used as a default so backends need to acknowledge when they do not
52            // support the float types, rather than accidentally quietly skipping all tests.
53            has_reliable_f16: true,
54            has_reliable_f16_math: true,
55            has_reliable_f16b: true,
56            has_reliable_f128: true,
57            has_reliable_f128_math: true,
58        }
59    }
60
61    fn supported_crate_types(&self, _sess: &Session) -> Vec<CrateType> {
62        ::alloc::boxed::box_assume_init_into_vec_unsafe(::alloc::intrinsics::write_box_via_move(::alloc::boxed::Box::new_uninit(),
        [CrateType::Executable, CrateType::Dylib, CrateType::Rlib,
                CrateType::StaticLib, CrateType::Cdylib, CrateType::ProcMacro,
                CrateType::Sdylib]))vec![
63            CrateType::Executable,
64            CrateType::Dylib,
65            CrateType::Rlib,
66            CrateType::StaticLib,
67            CrateType::Cdylib,
68            CrateType::ProcMacro,
69            CrateType::Sdylib,
70        ]
71    }
72
73    fn print_passes(&self) {}
74
75    fn print_version(&self) {}
76
77    /// Value printed by `--print=backend-has-zstd`.
78    ///
79    /// Used by compiletest to determine whether tests involving zstd compression
80    /// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped.
81    fn has_zstd(&self) -> bool {
82        false
83    }
84
85    /// Value printed by `--print=backend-has-mnemonic:...`.
86    ///
87    /// Used by compiletest to determine whether tests involving `asm!()` should
88    /// be executed or skipped.
89    fn has_mnemonic(&self, _sess: &Session, _mnemonic: &str) -> bool {
90        false
91    }
92
93    /// The metadata loader used to load rlib and dylib metadata.
94    ///
95    /// Alternative codegen backends may want to use different rlib or dylib formats than the
96    /// default native static archives and dynamic libraries.
97    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
98        Box::new(crate::back::metadata::DefaultMetadataLoader)
99    }
100
101    /// Allows queries to be overridden. Not used by any in-tree backends, but rustc_codegen_spirv
102    /// and rustc_codegen_nvvm use it.
103    fn provide(&self, _providers: &mut Providers) {}
104
105    fn target_cpu(&self, sess: &Session) -> String;
106
107    fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any>;
108
109    /// This is called on the returned `Box<dyn Any>` from [`codegen_crate`](Self::codegen_crate)
110    ///
111    /// # Panics
112    ///
113    /// Panics when the passed `Box<dyn Any>` was not returned by [`codegen_crate`](Self::codegen_crate).
114    fn join_codegen(
115        &self,
116        ongoing_codegen: Box<dyn Any>,
117        sess: &Session,
118        incr_comp_session: Option<&IncrCompSession>,
119        outputs: &OutputFilenames,
120        crate_info: &CrateInfo,
121    ) -> (CompiledModules, WorkProductMap);
122
123    fn print_pass_timings(&self) {}
124
125    fn print_statistics(&self) {}
126
127    fn print_statistics_json(&self) -> String {
128        String::new()
129    }
130
131    /// This is called on the returned [`CompiledModules`] from [`join_codegen`](Self::join_codegen).
132    fn link(
133        &self,
134        sess: &Session,
135        compiled_modules: CompiledModules,
136        crate_info: CrateInfo,
137        metadata: EncodedMetadata,
138        outputs: &OutputFilenames,
139    ) {
140        link_binary(
141            sess,
142            &ArArchiveBuilderBuilder,
143            compiled_modules,
144            crate_info,
145            metadata,
146            outputs,
147            self.name(),
148        );
149    }
150}
151
152pub trait ExtraBackendMethods: Send + Sync + DynSend + DynSync {
153    type Module;
154
155    fn codegen_allocator<'tcx>(
156        &self,
157        tcx: TyCtxt<'tcx>,
158        module_name: &str,
159        methods: &[AllocatorMethod],
160    ) -> Self::Module;
161
162    /// This generates the codegen unit and returns it along with
163    /// a `u64` giving an estimate of the unit's processing cost.
164    fn compile_codegen_unit(
165        &self,
166        tcx: TyCtxt<'_>,
167        cgu_name: Symbol,
168        bitcode_needed: bool,
169    ) -> (ModuleCodegen<Self::Module>, u64);
170}