Skip to content

Commit 523f0db

Browse files
authored
Merge pull request #1264 from bjorn3/parallel_comp_refactor
Refactorings for enabling parallel compilation (part 1)
2 parents 484041c + 9461fd2 commit 523f0db

File tree

8 files changed

+482
-297
lines changed

8 files changed

+482
-297
lines changed

Readme.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -52,9 +52,7 @@ configuration options.
5252
## Not yet supported
5353

5454
* Inline assembly ([no cranelift support](https://github.com/bytecodealliance/wasmtime/issues/1041))
55-
* On Linux there is support for invoking an external assembler for `global_asm!` and `asm!`.
56-
`llvm_asm!` will remain unimplemented forever. `asm!` doesn't yet support reg classes. You
57-
have to specify specific registers instead.
55+
* On UNIX there is support for invoking an external assembler for `global_asm!` and `asm!`.
5856
* SIMD ([tracked here](https://github.com/bjorn3/rustc_codegen_cranelift/issues/171), some basic things work)
5957

6058
## License

example/mini_core_hello_world.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,7 @@ fn main() {
321321
#[cfg(not(any(jit, windows)))]
322322
test_tls();
323323

324-
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
324+
#[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "darwin")))]
325325
unsafe {
326326
global_asm_test();
327327
}
@@ -343,7 +343,7 @@ fn main() {
343343
}
344344
}
345345

346-
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "linux"))]
346+
#[cfg(all(not(jit), target_arch = "x86_64", any(target_os = "linux", target_os = "darwin")))]
347347
extern "C" {
348348
fn global_asm_test();
349349
}
@@ -358,6 +358,16 @@ global_asm! {
358358
"
359359
}
360360

361+
#[cfg(all(not(jit), target_arch = "x86_64", target_os = "darwin"))]
362+
global_asm! {
363+
"
364+
.global _global_asm_test
365+
_global_asm_test:
366+
// comment that would normally be removed by LLVM
367+
ret
368+
"
369+
}
370+
361371
#[repr(C)]
362372
enum c_void {
363373
_1,

src/base.rs

Lines changed: 71 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -5,24 +5,50 @@ use rustc_index::vec::IndexVec;
55
use rustc_middle::ty::adjustment::PointerCast;
66
use rustc_middle::ty::layout::FnAbiOf;
77
use rustc_middle::ty::print::with_no_trimmed_paths;
8+
use rustc_middle::ty::SymbolName;
89

910
use indexmap::IndexSet;
1011

1112
use crate::constant::ConstantCx;
1213
use crate::prelude::*;
1314
use crate::pretty_clif::CommentWriter;
1415

15-
pub(crate) fn codegen_fn<'tcx>(
16+
struct CodegenedFunction<'tcx> {
17+
instance: Instance<'tcx>,
18+
symbol_name: SymbolName<'tcx>,
19+
func_id: FuncId,
20+
func: Function,
21+
clif_comments: CommentWriter,
22+
source_info_set: IndexSet<SourceInfo>,
23+
local_map: IndexVec<mir::Local, CPlace<'tcx>>,
24+
}
25+
26+
pub(crate) fn codegen_and_compile_fn<'tcx>(
1627
cx: &mut crate::CodegenCx<'tcx>,
28+
cached_context: &mut Context,
1729
module: &mut dyn Module,
1830
instance: Instance<'tcx>,
1931
) {
2032
let tcx = cx.tcx;
21-
2233
let _inst_guard =
2334
crate::PrintOnPanic(|| format!("{:?} {}", instance, tcx.symbol_name(instance).name));
35+
36+
let cached_func = std::mem::replace(&mut cached_context.func, Function::new());
37+
let codegened_func = codegen_fn(cx, cached_func, module, instance);
38+
39+
compile_fn(cx, cached_context, module, codegened_func);
40+
}
41+
42+
fn codegen_fn<'tcx>(
43+
cx: &mut crate::CodegenCx<'tcx>,
44+
cached_func: Function,
45+
module: &mut dyn Module,
46+
instance: Instance<'tcx>,
47+
) -> CodegenedFunction<'tcx> {
2448
debug_assert!(!instance.substs.needs_infer());
2549

50+
let tcx = cx.tcx;
51+
2652
let mir = tcx.instance_mir(instance.def);
2753
let _mir_guard = crate::PrintOnPanic(|| {
2854
let mut buf = Vec::new();
@@ -38,11 +64,10 @@ pub(crate) fn codegen_fn<'tcx>(
3864
let sig = get_function_sig(tcx, module.isa().triple(), instance);
3965
let func_id = module.declare_function(symbol_name.name, Linkage::Local, &sig).unwrap();
4066

41-
cx.cached_context.clear();
42-
4367
// Make the FunctionBuilder
4468
let mut func_ctx = FunctionBuilderContext::new();
45-
let mut func = std::mem::replace(&mut cx.cached_context.func, Function::new());
69+
let mut func = cached_func;
70+
func.clear();
4671
func.name = ExternalName::user(0, func_id.as_u32());
4772
func.signature = sig;
4873
func.collect_debug_info();
@@ -82,27 +107,7 @@ pub(crate) fn codegen_fn<'tcx>(
82107
next_ssa_var: 0,
83108
};
84109

85-
let arg_uninhabited = fx
86-
.mir
87-
.args_iter()
88-
.any(|arg| fx.layout_of(fx.monomorphize(fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
89-
90-
if !crate::constant::check_constants(&mut fx) {
91-
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
92-
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
93-
// compilation should have been aborted
94-
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
95-
} else if arg_uninhabited {
96-
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
97-
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
98-
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
99-
} else {
100-
tcx.sess.time("codegen clif ir", || {
101-
tcx.sess
102-
.time("codegen prelude", || crate::abi::codegen_fn_prelude(&mut fx, start_block));
103-
codegen_fn_content(&mut fx);
104-
});
105-
}
110+
tcx.sess.time("codegen clif ir", || codegen_fn_body(&mut fx, start_block));
106111

107112
// Recover all necessary data from fx, before accessing func will prevent future access to it.
108113
let instance = fx.instance;
@@ -124,36 +129,31 @@ pub(crate) fn codegen_fn<'tcx>(
124129
// Verify function
125130
verify_func(tcx, &clif_comments, &func);
126131

127-
compile_fn(
128-
cx,
129-
module,
132+
CodegenedFunction {
130133
instance,
131-
symbol_name.name,
134+
symbol_name,
132135
func_id,
133136
func,
134137
clif_comments,
135138
source_info_set,
136139
local_map,
137-
);
140+
}
138141
}
139142

140143
fn compile_fn<'tcx>(
141144
cx: &mut crate::CodegenCx<'tcx>,
145+
cached_context: &mut Context,
142146
module: &mut dyn Module,
143-
instance: Instance<'tcx>,
144-
symbol_name: &str,
145-
func_id: FuncId,
146-
func: Function,
147-
mut clif_comments: CommentWriter,
148-
source_info_set: IndexSet<SourceInfo>,
149-
local_map: IndexVec<mir::Local, CPlace<'tcx>>,
147+
codegened_func: CodegenedFunction<'tcx>,
150148
) {
151149
let tcx = cx.tcx;
152150

151+
let mut clif_comments = codegened_func.clif_comments;
152+
153153
// Store function in context
154-
let context = &mut cx.cached_context;
154+
let context = cached_context;
155155
context.clear();
156-
context.func = func;
156+
context.func = codegened_func.func;
157157

158158
// If the return block is not reachable, then the SSA builder may have inserted an `iconst.i128`
159159
// instruction, which doesn't have an encoding.
@@ -170,7 +170,7 @@ fn compile_fn<'tcx>(
170170
crate::optimize::optimize_function(
171171
tcx,
172172
module.isa(),
173-
instance,
173+
codegened_func.instance,
174174
context,
175175
&mut clif_comments,
176176
);
@@ -206,23 +206,23 @@ fn compile_fn<'tcx>(
206206
// Define function
207207
tcx.sess.time("define function", || {
208208
context.want_disasm = crate::pretty_clif::should_write_ir(tcx);
209-
module.define_function(func_id, context).unwrap();
209+
module.define_function(codegened_func.func_id, context).unwrap();
210210
});
211211

212212
// Write optimized function to file for debugging
213213
crate::pretty_clif::write_clif_file(
214214
tcx,
215215
"opt",
216216
module.isa(),
217-
instance,
217+
codegened_func.instance,
218218
&context.func,
219219
&clif_comments,
220220
);
221221

222222
if let Some(disasm) = &context.mach_compile_result.as_ref().unwrap().disasm {
223223
crate::pretty_clif::write_ir_file(
224224
tcx,
225-
|| format!("{}.vcode", tcx.symbol_name(instance).name),
225+
|| format!("{}.vcode", tcx.symbol_name(codegened_func.instance).name),
226226
|file| file.write_all(disasm.as_bytes()),
227227
)
228228
}
@@ -234,16 +234,16 @@ fn compile_fn<'tcx>(
234234
tcx.sess.time("generate debug info", || {
235235
if let Some(debug_context) = debug_context {
236236
debug_context.define_function(
237-
instance,
238-
func_id,
239-
symbol_name,
237+
codegened_func.instance,
238+
codegened_func.func_id,
239+
codegened_func.symbol_name.name,
240240
isa,
241241
context,
242-
&source_info_set,
243-
local_map,
242+
&codegened_func.source_info_set,
243+
codegened_func.local_map,
244244
);
245245
}
246-
unwind_context.add_function(func_id, &context, isa);
246+
unwind_context.add_function(codegened_func.func_id, &context, isa);
247247
});
248248
}
249249

@@ -269,7 +269,27 @@ pub(crate) fn verify_func(
269269
});
270270
}
271271

272-
fn codegen_fn_content(fx: &mut FunctionCx<'_, '_, '_>) {
272+
fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
273+
if !crate::constant::check_constants(fx) {
274+
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
275+
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
276+
// compilation should have been aborted
277+
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
278+
return;
279+
}
280+
281+
let arg_uninhabited = fx
282+
.mir
283+
.args_iter()
284+
.any(|arg| fx.layout_of(fx.monomorphize(fx.mir.local_decls[arg].ty)).abi.is_uninhabited());
285+
if arg_uninhabited {
286+
fx.bcx.append_block_params_for_function_params(fx.block_map[START_BLOCK]);
287+
fx.bcx.switch_to_block(fx.block_map[START_BLOCK]);
288+
fx.bcx.ins().trap(TrapCode::UnreachableCodeReached);
289+
return;
290+
}
291+
fx.tcx.sess.time("codegen prelude", || crate::abi::codegen_fn_prelude(fx, start_block));
292+
273293
for (bb, bb_data) in fx.mir.basic_blocks().iter_enumerated() {
274294
let block = fx.get_block(bb);
275295
fx.bcx.switch_to_block(block);

0 commit comments

Comments
 (0)