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::fx::FxIndexMap;
6use rustc_data_structures::sync::{DynSend, DynSync};
7use rustc_metadata::EncodedMetadata;
8use rustc_metadata::creader::MetadataLoaderDyn;
9use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
10use rustc_middle::ty::TyCtxt;
11use rustc_middle::util::Providers;
12use rustc_session::Session;
13use rustc_session::config::{CrateType, OutputFilenames, PrintRequest};
14use rustc_span::Symbol;
15
16use super::CodegenObject;
17use super::write::WriteBackendMethods;
18use crate::back::archive::ArArchiveBuilderBuilder;
19use crate::back::link::link_binary;
20use crate::{CompiledModules, CrateInfo, ModuleCodegen, TargetConfig};
21
22pub trait BackendTypes {
23    type Function: CodegenObject;
24    type BasicBlock: Copy;
25    type Funclet;
26
27    type Value: CodegenObject + PartialEq;
28    type Type: CodegenObject + PartialEq;
29    type FunctionSignature: CodegenObject + PartialEq;
30
31    // FIXME(eddyb) find a common convention for all of the debuginfo-related
32    // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.).
33    type DIScope: Copy + Hash + PartialEq + Eq;
34    type DILocation: Copy;
35    type DIVariable: Copy;
36}
37
38pub trait CodegenBackend {
39    fn name(&self) -> &'static str;
40
41    fn init(&self, _sess: &Session) {}
42
43    fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
44
45    /// Collect target-specific options that should be set in `cfg(...)`, including
46    /// `target_feature` and support for unstable float types.
47    fn target_config(&self, _sess: &Session) -> TargetConfig {
48        TargetConfig {
49            target_features: ::alloc::vec::Vec::new()vec![],
50            unstable_target_features: ::alloc::vec::Vec::new()vec![],
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_f128: true,
56            has_reliable_f128_math: true,
57        }
58    }
59
60    fn supported_crate_types(&self, _sess: &Session) -> Vec<CrateType> {
61        ::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![
62            CrateType::Executable,
63            CrateType::Dylib,
64            CrateType::Rlib,
65            CrateType::StaticLib,
66            CrateType::Cdylib,
67            CrateType::ProcMacro,
68            CrateType::Sdylib,
69        ]
70    }
71
72    fn print_passes(&self) {}
73
74    fn print_version(&self) {}
75
76    /// Returns a list of all intrinsics that this backend definitely
77    /// replaces, which means their fallback bodies do not need to be monomorphized.
78    fn replaced_intrinsics(&self) -> Vec<Symbol> {
79        ::alloc::vec::Vec::new()vec![]
80    }
81
82    /// Is ThinLTO supported by this backend?
83    fn thin_lto_supported(&self) -> bool {
84        true
85    }
86
87    /// Value printed by `--print=backend-has-zstd`.
88    ///
89    /// Used by compiletest to determine whether tests involving zstd compression
90    /// (e.g. `-Zdebuginfo-compression=zstd`) should be executed or skipped.
91    fn has_zstd(&self) -> bool {
92        false
93    }
94
95    /// The metadata loader used to load rlib and dylib metadata.
96    ///
97    /// Alternative codegen backends may want to use different rlib or dylib formats than the
98    /// default native static archives and dynamic libraries.
99    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
100        Box::new(crate::back::metadata::DefaultMetadataLoader)
101    }
102
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>, crate_info: &CrateInfo) -> 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        outputs: &OutputFilenames,
119    ) -> (CompiledModules, FxIndexMap<WorkProductId, WorkProduct>);
120
121    fn print_pass_timings(&self) {}
122
123    fn print_statistics(&self) {}
124
125    /// This is called on the returned [`CompiledModules`] from [`join_codegen`](Self::join_codegen).
126    fn link(
127        &self,
128        sess: &Session,
129        compiled_modules: CompiledModules,
130        crate_info: CrateInfo,
131        metadata: EncodedMetadata,
132        outputs: &OutputFilenames,
133    ) {
134        link_binary(
135            sess,
136            &ArArchiveBuilderBuilder,
137            compiled_modules,
138            crate_info,
139            metadata,
140            outputs,
141            self.name(),
142        );
143    }
144}
145
146pub trait ExtraBackendMethods:
147    WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
148{
149    fn codegen_allocator<'tcx>(
150        &self,
151        tcx: TyCtxt<'tcx>,
152        module_name: &str,
153        methods: &[AllocatorMethod],
154    ) -> Self::Module;
155
156    /// This generates the codegen unit and returns it along with
157    /// a `u64` giving an estimate of the unit's processing cost.
158    fn compile_codegen_unit(
159        &self,
160        tcx: TyCtxt<'_>,
161        cgu_name: Symbol,
162    ) -> (ModuleCodegen<Self::Module>, u64);
163
164    /// Returns `true` if this backend can be safely called from multiple threads.
165    ///
166    /// Defaults to `true`.
167    fn supports_parallel(&self) -> bool {
168        true
169    }
170}