rustc_codegen_ssa/back/
lto.rs1use std::ffi::CString;
2use std::sync::Arc;
3
4use rustc_ast::expand::autodiff_attrs::AutoDiffItem;
5use rustc_data_structures::memmap::Mmap;
6use rustc_errors::FatalError;
7
8use super::write::CodegenContext;
9use crate::ModuleCodegen;
10use crate::back::write::ModuleConfig;
11use crate::traits::*;
12
13pub struct ThinModule<B: WriteBackendMethods> {
14 pub shared: Arc<ThinShared<B>>,
15 pub idx: usize,
16}
17
18impl<B: WriteBackendMethods> ThinModule<B> {
19 pub fn name(&self) -> &str {
20 self.shared.module_names[self.idx].to_str().unwrap()
21 }
22
23 pub fn cost(&self) -> u64 {
24 self.data().len() as u64
27 }
28
29 pub fn data(&self) -> &[u8] {
30 let a = self.shared.thin_buffers.get(self.idx).map(|b| b.data());
31 a.unwrap_or_else(|| {
32 let len = self.shared.thin_buffers.len();
33 self.shared.serialized_modules[self.idx - len].data()
34 })
35 }
36}
37
38pub struct ThinShared<B: WriteBackendMethods> {
39 pub data: B::ThinData,
40 pub thin_buffers: Vec<B::ThinBuffer>,
41 pub serialized_modules: Vec<SerializedModule<B::ModuleBuffer>>,
42 pub module_names: Vec<CString>,
43}
44
45pub enum LtoModuleCodegen<B: WriteBackendMethods> {
46 Fat(ModuleCodegen<B::Module>),
47 Thin(ThinModule<B>),
48}
49
50impl<B: WriteBackendMethods> LtoModuleCodegen<B> {
51 pub fn name(&self) -> &str {
52 match *self {
53 LtoModuleCodegen::Fat(_) => "everything",
54 LtoModuleCodegen::Thin(ref m) => m.name(),
55 }
56 }
57
58 pub fn optimize(
60 self,
61 cgcx: &CodegenContext<B>,
62 ) -> Result<ModuleCodegen<B::Module>, FatalError> {
63 match self {
64 LtoModuleCodegen::Fat(mut module) => {
65 B::optimize_fat(cgcx, &mut module)?;
66 Ok(module)
67 }
68 LtoModuleCodegen::Thin(thin) => B::optimize_thin(cgcx, thin),
69 }
70 }
71
72 pub fn cost(&self) -> u64 {
75 match *self {
76 LtoModuleCodegen::Fat(_) => 0,
78 LtoModuleCodegen::Thin(ref m) => m.cost(),
79 }
80 }
81
82 pub fn autodiff(
84 self,
85 cgcx: &CodegenContext<B>,
86 diff_fncs: Vec<AutoDiffItem>,
87 config: &ModuleConfig,
88 ) -> Result<LtoModuleCodegen<B>, FatalError> {
89 match &self {
90 LtoModuleCodegen::Fat(module) => {
91 B::autodiff(cgcx, &module, diff_fncs, config)?;
92 }
93 _ => panic!("autodiff called with non-fat LTO module"),
94 }
95
96 Ok(self)
97 }
98}
99
100pub enum SerializedModule<M: ModuleBufferMethods> {
101 Local(M),
102 FromRlib(Vec<u8>),
103 FromUncompressedFile(Mmap),
104}
105
106impl<M: ModuleBufferMethods> SerializedModule<M> {
107 pub fn data(&self) -> &[u8] {
108 match *self {
109 SerializedModule::Local(ref m) => m.data(),
110 SerializedModule::FromRlib(ref m) => m,
111 SerializedModule::FromUncompressedFile(ref m) => m,
112 }
113 }
114}