Skip to content

Commit be57423

Browse files
committed
Move compilation to worker threads
1 parent 49cd998 commit be57423

3 files changed

Lines changed: 106 additions & 55 deletions

File tree

src/driver/aot.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -245,7 +245,7 @@ fn codegen_cgu_content(
245245
tcx: TyCtxt<'_>,
246246
module: &mut dyn Module,
247247
cgu_name: rustc_span::Symbol,
248-
) -> (Vec<SerializableModule>, String) {
248+
) -> (Vec<(SerializableModule, Option<Fingerprint>)>, String) {
249249
let _timer = tcx.prof.generic_activity_with_arg("codegen cgu", cgu_name.as_str());
250250

251251
let cgu = tcx.codegen_unit(cgu_name);
@@ -290,7 +290,8 @@ fn codegen_cgu_content(
290290
&& tcx.dep_graph.try_mark_green(tcx, &dep_node).is_some()
291291
{
292292
let data = FileCache.get(&cache_key.to_le_bytes()).unwrap();
293-
codegened_functions.push(SerializableModule::deserialize(&data, isa.clone()));
293+
codegened_functions
294+
.push((SerializableModule::deserialize(&data, isa.clone()), None));
294295
continue;
295296
};
296297

@@ -320,15 +321,12 @@ fn codegen_cgu_content(
320321
);
321322
ser_module.add_global_asm(&global_asm);
322323

323-
let data = ser_module.serialize();
324-
FileCache.insert(&cache_key.to_le_bytes(), data.to_vec());
325-
326324
ser_module
327325
},
328326
Some(rustc_middle::dep_graph::hash_result),
329327
);
330328

331-
codegened_functions.push(ser_module);
329+
codegened_functions.push((ser_module, Some(cache_key)));
332330
}
333331
MonoItem::Static(def_id) => {
334332
crate::constant::codegen_static(tcx, module, def_id);
@@ -384,7 +382,7 @@ fn compile_cgu(
384382
producer: String,
385383
global_asm_config: GlobalAsmConfig,
386384
mut module: UnwindModule<ObjectModule>,
387-
codegened_functions: Vec<SerializableModule>,
385+
codegened_functions: Vec<(SerializableModule, Option<Fingerprint>)>,
388386
mut global_asm: String,
389387
cgu_name: String,
390388
) -> Result<CompiledModule, String> {
@@ -393,7 +391,12 @@ fn compile_cgu(
393391
prof.clone(),
394392
)));
395393

396-
for codegened_func in codegened_functions {
394+
for (codegened_func, cache_key) in codegened_functions {
395+
if let Some(cache_key) = cache_key {
396+
let data = codegened_func.serialize();
397+
FileCache.insert(&cache_key.to_le_bytes(), data.to_vec());
398+
}
399+
397400
let asm = codegened_func.apply_to(&mut module);
398401
global_asm.push_str(&asm);
399402
}

src/serializable_module.rs

Lines changed: 90 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
1+
use std::cell::RefCell;
12
use std::collections::BTreeMap;
3+
use std::mem;
24
use std::sync::{Arc, OnceLock};
35

46
use cranelift_codegen::control::ControlPlane;
57
use cranelift_codegen::entity::SecondaryMap;
6-
use cranelift_codegen::ir::{Signature, UserExternalName};
8+
use cranelift_codegen::ir::function::FunctionParameters;
9+
use cranelift_codegen::ir::{ExternalName, Signature, UserExternalName};
710
use cranelift_codegen::isa::TargetIsa;
11+
use cranelift_codegen::{Final, FinalizedMachReloc, FinalizedRelocTarget, MachBufferFinalized};
812
use cranelift_module::{
913
DataId, ModuleDeclarations, ModuleError, ModuleReloc, ModuleRelocTarget, ModuleResult,
1014
};
@@ -18,14 +22,20 @@ pub(super) struct SerializableModule {
1822
serialized: OnceLock<Vec<u8>>,
1923
}
2024

21-
#[derive(Debug, serde::Serialize, serde::Deserialize)]
25+
#[derive(serde::Serialize, serde::Deserialize)]
2226
struct SerializableModuleInner {
2327
declarations: ModuleDeclarations,
24-
functions: BTreeMap<FuncId, Function>,
28+
functions: BTreeMap<FuncId, RefCell<FunctionMaybeCompiled>>,
2529
data_objects: BTreeMap<DataId, DataDescription>,
2630
global_asm: String,
2731
}
2832

33+
#[derive(serde::Serialize, serde::Deserialize)]
34+
enum FunctionMaybeCompiled {
35+
Ir(Function),
36+
Compiled(MachBufferFinalized<Final>, FunctionParameters),
37+
}
38+
2939
impl StableHash for SerializableModule {
3040
fn stable_hash<Hcx: StableHashCtxt>(&self, hcx: &mut Hcx, hasher: &mut StableHasher) {
3141
self.serialize().stable_hash(hcx, hasher);
@@ -47,6 +57,7 @@ impl SerializableModule {
4757
}
4858

4959
pub(crate) fn serialize(&self) -> &[u8] {
60+
self.compile_funcs();
5061
self.serialized.get_or_init(|| postcard::to_stdvec(&self.inner).unwrap())
5162
}
5263

@@ -63,7 +74,26 @@ impl SerializableModule {
6374
self.inner.global_asm.push_str(asm);
6475
}
6576

77+
fn compile_funcs(&self) {
78+
let mut ctx = Context::new();
79+
for func in self.inner.functions.values() {
80+
let mut func = func.borrow_mut();
81+
match &mut *func {
82+
FunctionMaybeCompiled::Ir(ir_func) => {
83+
// FIXME lazily do this during serialize/apply_to
84+
ctx.func = mem::replace(ir_func, Function::new());
85+
let res = ctx.compile(&*self.isa, &mut ControlPlane::default()).unwrap();
86+
87+
let buffer = res.buffer.clone();
88+
*func = FunctionMaybeCompiled::Compiled(buffer, ctx.func.params);
89+
}
90+
FunctionMaybeCompiled::Compiled(_, _) => {}
91+
}
92+
}
93+
}
94+
6695
pub(crate) fn apply_to(self, module: &mut dyn Module) -> String {
96+
self.compile_funcs();
6797
let mut function_map: SecondaryMap<FuncId, Option<FuncId>> = SecondaryMap::new();
6898
let mut data_object_map: SecondaryMap<DataId, Option<DataId>> = SecondaryMap::new();
6999

@@ -93,41 +123,62 @@ impl SerializableModule {
93123
data_object_map[data_id].unwrap()
94124
};
95125

96-
for (func_id, mut func) in self.inner.functions {
126+
for (func_id, func) in self.inner.functions {
97127
let func_id = remap_func_id(module, &self.inner.declarations, func_id);
98-
let user_named_funcs = func.params.user_named_funcs().clone();
99-
for (ext_name_ref, ext_name) in user_named_funcs {
100-
if ext_name.namespace == 0 {
101-
func.params.reset_user_func_name(
102-
ext_name_ref,
103-
UserExternalName::new(
104-
0,
105-
remap_func_id(
106-
module,
107-
&self.inner.declarations,
108-
FuncId::from_u32(ext_name.index),
128+
129+
let FunctionMaybeCompiled::Compiled(buffer, params) = &*func.borrow() else {
130+
unreachable!()
131+
};
132+
133+
let remap_reloc = |reloc: &FinalizedMachReloc| {
134+
let name = match reloc.target {
135+
FinalizedRelocTarget::ExternalName(ExternalName::User(reff)) => {
136+
let ext_name = &params.user_named_funcs()[reff];
137+
let ext_name = if ext_name.namespace == 0 {
138+
UserExternalName::new(
139+
0,
140+
remap_func_id(
141+
module,
142+
&self.inner.declarations,
143+
FuncId::from_u32(ext_name.index),
144+
)
145+
.as_u32(),
109146
)
110-
.as_u32(),
111-
),
112-
);
113-
} else if ext_name.namespace == 1 {
114-
func.params.reset_user_func_name(
115-
ext_name_ref,
116-
UserExternalName::new(
117-
1,
118-
remap_data_id(
119-
module,
120-
&self.inner.declarations,
121-
DataId::from_u32(ext_name.index),
147+
} else if ext_name.namespace == 1 {
148+
UserExternalName::new(
149+
1,
150+
remap_data_id(
151+
module,
152+
&self.inner.declarations,
153+
DataId::from_u32(ext_name.index),
154+
)
155+
.as_u32(),
122156
)
123-
.as_u32(),
124-
),
125-
);
126-
} else {
127-
unreachable!();
128-
}
129-
}
130-
module.define_function(func_id, &mut Context::for_function(func)).unwrap();
157+
} else {
158+
unreachable!();
159+
};
160+
ModuleRelocTarget::user(ext_name.namespace, ext_name.index)
161+
}
162+
FinalizedRelocTarget::ExternalName(ExternalName::TestCase(_)) => {
163+
unimplemented!()
164+
}
165+
FinalizedRelocTarget::ExternalName(ExternalName::LibCall(libcall)) => {
166+
ModuleRelocTarget::LibCall(libcall)
167+
}
168+
FinalizedRelocTarget::ExternalName(ExternalName::KnownSymbol(ks)) => {
169+
ModuleRelocTarget::KnownSymbol(ks)
170+
}
171+
FinalizedRelocTarget::Func(offset) => {
172+
ModuleRelocTarget::FunctionOffset(func_id, offset)
173+
}
174+
};
175+
ModuleReloc { offset: reloc.offset, kind: reloc.kind, name, addend: reloc.addend }
176+
};
177+
178+
let relocs = buffer.relocs().iter().map(remap_reloc).collect::<Vec<_>>();
179+
module
180+
.define_function_bytes(func_id, buffer.alignment as u64, buffer.data(), &relocs)
181+
.unwrap();
131182
}
132183

133184
for (data_id, mut data) in self.inner.data_objects {
@@ -214,7 +265,7 @@ impl Module for SerializableModule {
214265
&mut self,
215266
func_id: FuncId,
216267
ctx: &mut Context,
217-
ctrl_plane: &mut ControlPlane,
268+
_ctrl_plane: &mut ControlPlane,
218269
) -> ModuleResult<()> {
219270
let decl = self.inner.declarations.get_function_decl(func_id);
220271
if !decl.linkage.is_definable() {
@@ -229,12 +280,9 @@ impl Module for SerializableModule {
229280
));
230281
}
231282

232-
ctx.verify_if(&*self.isa)?;
233-
ctx.optimize(&*self.isa, ctrl_plane)?;
234-
235-
// FIXME compile to machine code
236-
237-
self.inner.functions.insert(func_id, ctx.func.clone());
283+
self.inner
284+
.functions
285+
.insert(func_id, RefCell::new(FunctionMaybeCompiled::Ir(ctx.func.clone())));
238286

239287
Ok(())
240288
}

src/unwind_module.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -136,12 +136,12 @@ impl<T: Module> Module for UnwindModule<T> {
136136

137137
fn define_function_bytes(
138138
&mut self,
139-
_func_id: FuncId,
140-
_alignment: u64,
141-
_bytes: &[u8],
142-
_relocs: &[ModuleReloc],
139+
func_id: FuncId,
140+
alignment: u64,
141+
bytes: &[u8],
142+
relocs: &[ModuleReloc],
143143
) -> ModuleResult<()> {
144-
unimplemented!()
144+
self.module.define_function_bytes(func_id, alignment, bytes, relocs)
145145
}
146146

147147
fn define_data(&mut self, data_id: DataId, data: &DataDescription) -> ModuleResult<()> {

0 commit comments

Comments
 (0)