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