rustc_codegen_ssa/traits/
backend.rs

1use std::any::Any;
2use std::hash::Hash;
3
4use rustc_ast::expand::allocator::AllocatorKind;
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, 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};
22
23pub trait BackendTypes {
24    type Value: CodegenObject;
25    type Metadata: CodegenObject;
26    type Function: CodegenObject;
27
28    type BasicBlock: Copy;
29    type Type: CodegenObject;
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 init(&self, _sess: &Session) {}
45
46    fn print(&self, _req: &PrintRequest, _out: &mut String, _sess: &Session) {}
47
48    /// Returns two feature sets:
49    /// - The first has the features that should be set in `cfg(target_features)`.
50    /// - The second is like the first, but also includes unstable features.
51    ///
52    /// RUSTC_SPECIFIC_FEATURES should be skipped here, those are handled outside codegen.
53    fn target_features_cfg(&self, _sess: &Session) -> (Vec<Symbol>, Vec<Symbol>) {
54        (vec![], vec![])
55    }
56
57    fn print_passes(&self) {}
58
59    fn print_version(&self) {}
60
61    /// The metadata loader used to load rlib and dylib metadata.
62    ///
63    /// Alternative codegen backends may want to use different rlib or dylib formats than the
64    /// default native static archives and dynamic libraries.
65    fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
66        Box::new(crate::back::metadata::DefaultMetadataLoader)
67    }
68
69    fn provide(&self, _providers: &mut Providers) {}
70
71    fn codegen_crate<'tcx>(
72        &self,
73        tcx: TyCtxt<'tcx>,
74        metadata: EncodedMetadata,
75        need_metadata_module: bool,
76    ) -> Box<dyn Any>;
77
78    /// This is called on the returned `Box<dyn Any>` from [`codegen_crate`](Self::codegen_crate)
79    ///
80    /// # Panics
81    ///
82    /// Panics when the passed `Box<dyn Any>` was not returned by [`codegen_crate`](Self::codegen_crate).
83    fn join_codegen(
84        &self,
85        ongoing_codegen: Box<dyn Any>,
86        sess: &Session,
87        outputs: &OutputFilenames,
88    ) -> (CodegenResults, FxIndexMap<WorkProductId, WorkProduct>);
89
90    /// This is called on the returned [`CodegenResults`] from [`join_codegen`](Self::join_codegen).
91    fn link(&self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames) {
92        link_binary(sess, &ArArchiveBuilderBuilder, codegen_results, outputs);
93    }
94
95    /// Returns `true` if this backend can be safely called from multiple threads.
96    ///
97    /// Defaults to `true`.
98    fn supports_parallel(&self) -> bool {
99        true
100    }
101}
102
103pub trait ExtraBackendMethods:
104    CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
105{
106    fn codegen_allocator<'tcx>(
107        &self,
108        tcx: TyCtxt<'tcx>,
109        module_name: &str,
110        kind: AllocatorKind,
111        alloc_error_handler_kind: AllocatorKind,
112    ) -> Self::Module;
113
114    /// This generates the codegen unit and returns it along with
115    /// a `u64` giving an estimate of the unit's processing cost.
116    fn compile_codegen_unit(
117        &self,
118        tcx: TyCtxt<'_>,
119        cgu_name: Symbol,
120    ) -> (ModuleCodegen<Self::Module>, u64);
121
122    fn target_machine_factory(
123        &self,
124        sess: &Session,
125        opt_level: config::OptLevel,
126        target_features: &[String],
127    ) -> TargetMachineFactoryFn<Self>;
128
129    fn spawn_named_thread<F, T>(
130        _time_trace: bool,
131        name: String,
132        f: F,
133    ) -> std::io::Result<std::thread::JoinHandle<T>>
134    where
135        F: FnOnce() -> T,
136        F: Send + 'static,
137        T: Send + 'static,
138    {
139        std::thread::Builder::new().name(name).spawn(f)
140    }
141}