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::{self, 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::back::write::TargetMachineFactoryFn;
21use crate::{CodegenResults, ModuleCodegen, TargetConfig};
22
23pub trait BackendTypes {
24    type Value: CodegenObject + PartialEq;
25    type Metadata: CodegenObject;
26    type Function: CodegenObject;
27
28    type BasicBlock: Copy;
29    type Type: CodegenObject + PartialEq;
30    type Funclet;
31
32    // FIXME(eddyb) find a common convention for all of the debuginfo-related
33    // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.).
34    type DIScope: Copy + Hash + PartialEq + Eq;
35    type DILocation: Copy;
36    type DIVariable: Copy;
37}
38
39pub trait CodegenBackend {
40    /// Locale resources for diagnostic messages - a string the content of the Fluent resource.
41    /// Called before `init` so that all other functions are able to emit translatable diagnostics.
42    fn locale_resource(&self) -> &'static str;
43
44    fn name(&self) -> &'static str;
45
46    fn init(&self, _sess: &Session) {}
47
48    fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
49
50    /// Collect target-specific options that should be set in `cfg(...)`, including
51    /// `target_feature` and support for unstable float types.
52    fn target_config(&self, _sess: &Session) -> TargetConfig {
53        TargetConfig {
54            target_features: vec![],
55            unstable_target_features: vec![],
56            // `true` is used as a default so backends need to acknowledge when they do not
57            // support the float types, rather than accidentally quietly skipping all tests.
58            has_reliable_f16: true,
59            has_reliable_f16_math: true,
60            has_reliable_f128: true,
61            has_reliable_f128_math: true,
62        }
63    }
64
65    fn supported_crate_types(&self, _sess: &Session) -> Vec<CrateType> {
66        vec![
67            CrateType::Executable,
68            CrateType::Dylib,
69            CrateType::Rlib,
70            CrateType::Staticlib,
71            CrateType::Cdylib,
72            CrateType::ProcMacro,
73            CrateType::Sdylib,
74        ]
75    }
76
77    fn print_passes(&self) {}
78
79    fn print_version(&self) {}
80
81    /// The metadata loader used to load rlib and dylib metadata.
82    ///
83    /// Alternative codegen backends may want to use different rlib or dylib formats than the
84    /// default native static archives and dynamic libraries.
85    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
86        Box::new(crate::back::metadata::DefaultMetadataLoader)
87    }
88
89    fn provide(&self, _providers: &mut Providers) {}
90
91    fn codegen_crate<'tcx>(&self, tcx: TyCtxt<'tcx>) -> Box<dyn Any>;
92
93    /// This is called on the returned `Box<dyn Any>` from [`codegen_crate`](Self::codegen_crate)
94    ///
95    /// # Panics
96    ///
97    /// Panics when the passed `Box<dyn Any>` was not returned by [`codegen_crate`](Self::codegen_crate).
98    fn join_codegen(
99        &self,
100        ongoing_codegen: Box<dyn Any>,
101        sess: &Session,
102        outputs: &OutputFilenames,
103    ) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>);
104
105    /// This is called on the returned [`CodegenResults`] from [`join_codegen`](Self::join_codegen).
106    fn link(
107        &self,
108        sess: &Session,
109        codegen_results: CodegenResults,
110        metadata: EncodedMetadata,
111        outputs: &OutputFilenames,
112    ) {
113        link_binary(
114            sess,
115            &ArArchiveBuilderBuilder,
116            codegen_results,
117            metadata,
118            outputs,
119            self.name(),
120        );
121    }
122}
123
124pub trait ExtraBackendMethods:
125    CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
126{
127    fn codegen_allocator<'tcx>(
128        &self,
129        tcx: TyCtxt<'tcx>,
130        module_name: &str,
131        methods: &[AllocatorMethod],
132    ) -> Self::Module;
133
134    /// This generates the codegen unit and returns it along with
135    /// a `u64` giving an estimate of the unit's processing cost.
136    fn compile_codegen_unit(
137        &self,
138        tcx: TyCtxt<'_>,
139        cgu_name: Symbol,
140    ) -> (ModuleCodegen<Self::Module>, u64);
141
142    fn target_machine_factory(
143        &self,
144        sess: &Session,
145        opt_level: config::OptLevel,
146        target_features: &[String],
147    ) -> TargetMachineFactoryFn<Self>;
148
149    fn spawn_named_thread<F, T>(
150        _time_trace: bool,
151        name: String,
152        f: F,
153    ) -> std::io::Result<std::thread::JoinHandle<T>>
154    where
155        F: FnOnce() -> T,
156        F: Send + 'static,
157        T: Send + 'static,
158    {
159        std::thread::Builder::new().name(name).spawn(f)
160    }
161
162    /// Returns `true` if this backend can be safely called from multiple threads.
163    ///
164    /// Defaults to `true`.
165    fn supports_parallel(&self) -> bool {
166        true
167    }
168}