Skip to content

Commit b2cd1b8

Browse files
committed
Remove an unsafe closure invariant by inlining the closure wrapper into the called function
1 parent c182ce9 commit b2cd1b8

File tree

1 file changed

+50
-80
lines changed
  • compiler/rustc_codegen_llvm/src/back

1 file changed

+50
-80
lines changed

compiler/rustc_codegen_llvm/src/back/write.rs

+50-80
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ use crate::errors::{
4040
WithLlvmError, WriteBytecode,
4141
};
4242
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
43-
use crate::llvm::{self, DiagnosticInfo, PassManager};
43+
use crate::llvm::{self, DiagnosticInfo};
4444
use crate::type_::Type;
4545
use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util};
4646

@@ -54,7 +54,7 @@ pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> Fatal
5454
fn write_output_file<'ll>(
5555
dcx: DiagCtxtHandle<'_>,
5656
target: &'ll llvm::TargetMachine,
57-
pm: &llvm::PassManager<'ll>,
57+
no_builtins: bool,
5858
m: &'ll llvm::Module,
5959
output: &Path,
6060
dwo_output: Option<&Path>,
@@ -63,39 +63,42 @@ fn write_output_file<'ll>(
6363
verify_llvm_ir: bool,
6464
) -> Result<(), FatalError> {
6565
debug!("write_output_file output={:?} dwo_output={:?}", output, dwo_output);
66-
unsafe {
67-
let output_c = path_to_c_string(output);
68-
let dwo_output_c;
69-
let dwo_output_ptr = if let Some(dwo_output) = dwo_output {
70-
dwo_output_c = path_to_c_string(dwo_output);
71-
dwo_output_c.as_ptr()
72-
} else {
73-
std::ptr::null()
74-
};
75-
let result = llvm::LLVMRustWriteOutputFile(
66+
let output_c = path_to_c_string(output);
67+
let dwo_output_c;
68+
let dwo_output_ptr = if let Some(dwo_output) = dwo_output {
69+
dwo_output_c = path_to_c_string(dwo_output);
70+
dwo_output_c.as_ptr()
71+
} else {
72+
std::ptr::null()
73+
};
74+
let result = unsafe {
75+
let pm = llvm::LLVMCreatePassManager();
76+
llvm::LLVMAddAnalysisPasses(target, pm);
77+
llvm::LLVMRustAddLibraryInfo(pm, m, no_builtins);
78+
llvm::LLVMRustWriteOutputFile(
7679
target,
7780
pm,
7881
m,
7982
output_c.as_ptr(),
8083
dwo_output_ptr,
8184
file_type,
8285
verify_llvm_ir,
83-
);
86+
)
87+
};
8488

85-
// Record artifact sizes for self-profiling
86-
if result == llvm::LLVMRustResult::Success {
87-
let artifact_kind = match file_type {
88-
llvm::FileType::ObjectFile => "object_file",
89-
llvm::FileType::AssemblyFile => "assembly_file",
90-
};
91-
record_artifact_size(self_profiler_ref, artifact_kind, output);
92-
if let Some(dwo_file) = dwo_output {
93-
record_artifact_size(self_profiler_ref, "dwo_file", dwo_file);
94-
}
89+
// Record artifact sizes for self-profiling
90+
if result == llvm::LLVMRustResult::Success {
91+
let artifact_kind = match file_type {
92+
llvm::FileType::ObjectFile => "object_file",
93+
llvm::FileType::AssemblyFile => "assembly_file",
94+
};
95+
record_artifact_size(self_profiler_ref, artifact_kind, output);
96+
if let Some(dwo_file) = dwo_output {
97+
record_artifact_size(self_profiler_ref, "dwo_file", dwo_file);
9598
}
96-
97-
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteOutput { path: output }))
9899
}
100+
101+
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteOutput { path: output }))
99102
}
100103

101104
pub(crate) fn create_informational_target_machine(
@@ -755,31 +758,6 @@ pub(crate) unsafe fn codegen(
755758
create_msvc_imps(cgcx, llcx, llmod);
756759
}
757760

758-
// A codegen-specific pass manager is used to generate object
759-
// files for an LLVM module.
760-
//
761-
// Apparently each of these pass managers is a one-shot kind of
762-
// thing, so we create a new one for each type of output. The
763-
// pass manager passed to the closure should be ensured to not
764-
// escape the closure itself, and the manager should only be
765-
// used once.
766-
unsafe fn with_codegen<'ll, F, R>(
767-
tm: &'ll llvm::TargetMachine,
768-
llmod: &'ll llvm::Module,
769-
no_builtins: bool,
770-
f: F,
771-
) -> R
772-
where
773-
F: FnOnce(&'ll mut PassManager<'ll>) -> R,
774-
{
775-
unsafe {
776-
let cpm = llvm::LLVMCreatePassManager();
777-
llvm::LLVMAddAnalysisPasses(tm, cpm);
778-
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
779-
f(cpm)
780-
}
781-
}
782-
783761
// Note that if object files are just LLVM bitcode we write bitcode,
784762
// copy it to the .o file, and delete the bitcode if it wasn't
785763
// otherwise requested.
@@ -898,21 +876,17 @@ pub(crate) unsafe fn codegen(
898876
} else {
899877
llmod
900878
};
901-
unsafe {
902-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
903-
write_output_file(
904-
dcx,
905-
tm,
906-
cpm,
907-
llmod,
908-
&path,
909-
None,
910-
llvm::FileType::AssemblyFile,
911-
&cgcx.prof,
912-
config.verify_llvm_ir,
913-
)
914-
})?;
915-
}
879+
write_output_file(
880+
dcx,
881+
tm,
882+
config.no_builtins,
883+
llmod,
884+
&path,
885+
None,
886+
llvm::FileType::AssemblyFile,
887+
&cgcx.prof,
888+
config.verify_llvm_ir,
889+
)?;
916890
}
917891

918892
match config.emit_obj {
@@ -936,21 +910,17 @@ pub(crate) unsafe fn codegen(
936910
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
937911
};
938912

939-
unsafe {
940-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
941-
write_output_file(
942-
dcx,
943-
tm,
944-
cpm,
945-
llmod,
946-
&obj_out,
947-
dwo_out,
948-
llvm::FileType::ObjectFile,
949-
&cgcx.prof,
950-
config.verify_llvm_ir,
951-
)
952-
})?;
953-
}
913+
write_output_file(
914+
dcx,
915+
tm,
916+
config.no_builtins,
917+
llmod,
918+
&obj_out,
919+
dwo_out,
920+
llvm::FileType::ObjectFile,
921+
&cgcx.prof,
922+
config.verify_llvm_ir,
923+
)?;
954924
}
955925

956926
EmitObj::Bitcode => {

0 commit comments

Comments
 (0)