• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use std::any::Any;
2 
3 use super::write::WriteBackendMethods;
4 use super::CodegenObject;
5 use crate::back::write::TargetMachineFactoryFn;
6 use crate::{CodegenResults, ModuleCodegen};
7 
8 use rustc_ast::expand::allocator::AllocatorKind;
9 use rustc_data_structures::fx::FxIndexMap;
10 use rustc_data_structures::sync::{DynSend, DynSync};
11 use rustc_errors::ErrorGuaranteed;
12 use rustc_metadata::EncodedMetadata;
13 use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
14 use rustc_middle::query::{ExternProviders, Providers};
15 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf, TyAndLayout};
16 use rustc_middle::ty::{Ty, TyCtxt};
17 use rustc_session::{
18     config::{self, OutputFilenames, PrintRequest},
19     cstore::MetadataLoaderDyn,
20     Session,
21 };
22 use rustc_span::symbol::Symbol;
23 use rustc_target::abi::call::FnAbi;
24 use rustc_target::spec::Target;
25 
26 pub trait BackendTypes {
27     type Value: CodegenObject;
28     type Function: CodegenObject;
29 
30     type BasicBlock: Copy;
31     type Type: CodegenObject;
32     type Funclet;
33 
34     // FIXME(eddyb) find a common convention for all of the debuginfo-related
35     // names (choose between `Dbg`, `Debug`, `DebugInfo`, `DI` etc.).
36     type DIScope: Copy;
37     type DILocation: Copy;
38     type DIVariable: Copy;
39 }
40 
41 pub trait Backend<'tcx>:
42     Sized
43     + BackendTypes
44     + HasTyCtxt<'tcx>
45     + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
46     + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
47 {
48 }
49 
50 impl<'tcx, T> Backend<'tcx> for T where
51     Self: BackendTypes
52         + HasTyCtxt<'tcx>
53         + LayoutOf<'tcx, LayoutOfResult = TyAndLayout<'tcx>>
54         + FnAbiOf<'tcx, FnAbiOfResult = &'tcx FnAbi<'tcx, Ty<'tcx>>>
55 {
56 }
57 
58 pub trait CodegenBackend {
59     /// Locale resources for diagnostic messages - a string the content of the Fluent resource.
60     /// Called before `init` so that all other functions are able to emit translatable diagnostics.
locale_resource(&self) -> &'static str61     fn locale_resource(&self) -> &'static str;
62 
init(&self, _sess: &Session)63     fn init(&self, _sess: &Session) {}
print(&self, _req: PrintRequest, _sess: &Session)64     fn print(&self, _req: PrintRequest, _sess: &Session) {}
target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol>65     fn target_features(&self, _sess: &Session, _allow_unstable: bool) -> Vec<Symbol> {
66         vec![]
67     }
print_passes(&self)68     fn print_passes(&self) {}
print_version(&self)69     fn print_version(&self) {}
70 
71     /// If this plugin provides additional builtin targets, provide the one enabled by the options here.
72     /// Be careful: this is called *before* init() is called.
target_override(&self, _opts: &config::Options) -> Option<Target>73     fn target_override(&self, _opts: &config::Options) -> Option<Target> {
74         None
75     }
76 
77     /// The metadata loader used to load rlib and dylib metadata.
78     ///
79     /// Alternative codegen backends may want to use different rlib or dylib formats than the
80     /// default native static archives and dynamic libraries.
metadata_loader(&self) -> Box<MetadataLoaderDyn>81     fn metadata_loader(&self) -> Box<MetadataLoaderDyn> {
82         Box::new(crate::back::metadata::DefaultMetadataLoader)
83     }
84 
provide(&self, _providers: &mut Providers)85     fn provide(&self, _providers: &mut Providers) {}
provide_extern(&self, _providers: &mut ExternProviders)86     fn provide_extern(&self, _providers: &mut ExternProviders) {}
codegen_crate<'tcx>( &self, tcx: TyCtxt<'tcx>, metadata: EncodedMetadata, need_metadata_module: bool, ) -> Box<dyn Any>87     fn codegen_crate<'tcx>(
88         &self,
89         tcx: TyCtxt<'tcx>,
90         metadata: EncodedMetadata,
91         need_metadata_module: bool,
92     ) -> Box<dyn Any>;
93 
94     /// This is called on the returned `Box<dyn Any>` from `codegen_backend`
95     ///
96     /// # Panics
97     ///
98     /// Panics when the passed `Box<dyn Any>` was not returned by `codegen_backend`.
join_codegen( &self, ongoing_codegen: Box<dyn Any>, sess: &Session, outputs: &OutputFilenames, ) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed>99     fn join_codegen(
100         &self,
101         ongoing_codegen: Box<dyn Any>,
102         sess: &Session,
103         outputs: &OutputFilenames,
104     ) -> Result<(CodegenResults, FxIndexMap<WorkProductId, WorkProduct>), ErrorGuaranteed>;
105 
106     /// This is called on the returned `Box<dyn Any>` from `join_codegen`
107     ///
108     /// # Panics
109     ///
110     /// Panics when the passed `Box<dyn Any>` was not returned by `join_codegen`.
link( &self, sess: &Session, codegen_results: CodegenResults, outputs: &OutputFilenames, ) -> Result<(), ErrorGuaranteed>111     fn link(
112         &self,
113         sess: &Session,
114         codegen_results: CodegenResults,
115         outputs: &OutputFilenames,
116     ) -> Result<(), ErrorGuaranteed>;
117 }
118 
119 pub trait ExtraBackendMethods:
120     CodegenBackend + WriteBackendMethods + Sized + Send + Sync + DynSend + DynSync
121 {
codegen_allocator<'tcx>( &self, tcx: TyCtxt<'tcx>, module_name: &str, kind: AllocatorKind, alloc_error_handler_kind: AllocatorKind, ) -> Self::Module122     fn codegen_allocator<'tcx>(
123         &self,
124         tcx: TyCtxt<'tcx>,
125         module_name: &str,
126         kind: AllocatorKind,
127         alloc_error_handler_kind: AllocatorKind,
128     ) -> Self::Module;
129     /// This generates the codegen unit and returns it along with
130     /// a `u64` giving an estimate of the unit's processing cost.
compile_codegen_unit( &self, tcx: TyCtxt<'_>, cgu_name: Symbol, ) -> (ModuleCodegen<Self::Module>, u64)131     fn compile_codegen_unit(
132         &self,
133         tcx: TyCtxt<'_>,
134         cgu_name: Symbol,
135     ) -> (ModuleCodegen<Self::Module>, u64);
target_machine_factory( &self, sess: &Session, opt_level: config::OptLevel, target_features: &[String], ) -> TargetMachineFactoryFn<Self>136     fn target_machine_factory(
137         &self,
138         sess: &Session,
139         opt_level: config::OptLevel,
140         target_features: &[String],
141     ) -> TargetMachineFactoryFn<Self>;
142 
spawn_thread<F, T>(_time_trace: bool, f: F) -> std::thread::JoinHandle<T> where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static,143     fn spawn_thread<F, T>(_time_trace: bool, f: F) -> std::thread::JoinHandle<T>
144     where
145         F: FnOnce() -> T,
146         F: Send + 'static,
147         T: Send + 'static,
148     {
149         std::thread::spawn(f)
150     }
151 
spawn_named_thread<F, T>( _time_trace: bool, name: String, f: F, ) -> std::io::Result<std::thread::JoinHandle<T>> where F: FnOnce() -> T, F: Send + 'static, T: Send + 'static,152     fn spawn_named_thread<F, T>(
153         _time_trace: bool,
154         name: String,
155         f: F,
156     ) -> std::io::Result<std::thread::JoinHandle<T>>
157     where
158         F: FnOnce() -> T,
159         F: Send + 'static,
160         T: Send + 'static,
161     {
162         std::thread::Builder::new().name(name).spawn(f)
163     }
164 }
165