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 unsafe fn optimize(
65 self,
66 cgcx: &CodegenContext<B>,
67 ) -> Result<ModuleCodegen<B::Module>, FatalError> {
68 match self {
69 LtoModuleCodegen::Fat(mut module) => {
70 B::optimize_fat(cgcx, &mut module)?;
71 Ok(module)
72 }
73 LtoModuleCodegen::Thin(thin) => unsafe { B::optimize_thin(cgcx, thin) },
74 }
75 }
76
77 pub fn cost(&self) -> u64 {
80 match *self {
81 LtoModuleCodegen::Fat(_) => 0,
83 LtoModuleCodegen::Thin(ref m) => m.cost(),
84 }
85 }
86
87 pub unsafe fn autodiff(
89 self,
90 cgcx: &CodegenContext<B>,
91 diff_fncs: Vec<AutoDiffItem>,
92 config: &ModuleConfig,
93 ) -> Result<LtoModuleCodegen<B>, FatalError> {
94 match &self {
95 LtoModuleCodegen::Fat(module) => {
96 B::autodiff(cgcx, &module, diff_fncs, config)?;
97 }
98 _ => panic!("autodiff called with non-fat LTO module"),
99 }
100
101 Ok(self)
102 }
103}
104
105pub enum SerializedModule<M: ModuleBufferMethods> {
106 Local(M),
107 FromRlib(Vec<u8>),
108 FromUncompressedFile(Mmap),
109}
110
111impl<M: ModuleBufferMethods> SerializedModule<M> {
112 pub fn data(&self) -> &[u8] {
113 match *self {
114 SerializedModule::Local(ref m) => m.data(),
115 SerializedModule::FromRlib(ref m) => m,
116 SerializedModule::FromUncompressedFile(ref m) => m,
117 }
118 }
119}