Skip to content

Commit b3e7022

Browse files
committed
Remove an unsafe closure invariant by inlining the closure wrapper into the called function
1 parent 2776bdf commit b3e7022

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(
@@ -744,31 +747,6 @@ pub(crate) unsafe fn codegen(
744747
create_msvc_imps(cgcx, llcx, llmod);
745748
}
746749

747-
// A codegen-specific pass manager is used to generate object
748-
// files for an LLVM module.
749-
//
750-
// Apparently each of these pass managers is a one-shot kind of
751-
// thing, so we create a new one for each type of output. The
752-
// pass manager passed to the closure should be ensured to not
753-
// escape the closure itself, and the manager should only be
754-
// used once.
755-
unsafe fn with_codegen<'ll, F, R>(
756-
tm: &'ll llvm::TargetMachine,
757-
llmod: &'ll llvm::Module,
758-
no_builtins: bool,
759-
f: F,
760-
) -> R
761-
where
762-
F: FnOnce(&'ll mut PassManager<'ll>) -> R,
763-
{
764-
unsafe {
765-
let cpm = llvm::LLVMCreatePassManager();
766-
llvm::LLVMAddAnalysisPasses(tm, cpm);
767-
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
768-
f(cpm)
769-
}
770-
}
771-
772750
// Two things to note:
773751
// - If object files are just LLVM bitcode we write bitcode, copy it to
774752
// the .o file, and delete the bitcode if it wasn't otherwise
@@ -890,21 +868,17 @@ pub(crate) unsafe fn codegen(
890868
} else {
891869
llmod
892870
};
893-
unsafe {
894-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
895-
write_output_file(
896-
dcx,
897-
tm,
898-
cpm,
899-
llmod,
900-
&path,
901-
None,
902-
llvm::FileType::AssemblyFile,
903-
&cgcx.prof,
904-
config.verify_llvm_ir,
905-
)
906-
})?;
907-
}
871+
write_output_file(
872+
dcx,
873+
tm,
874+
config.no_builtins,
875+
llmod,
876+
&path,
877+
None,
878+
llvm::FileType::AssemblyFile,
879+
&cgcx.prof,
880+
config.verify_llvm_ir,
881+
)?;
908882
}
909883

910884
match config.emit_obj {
@@ -928,21 +902,17 @@ pub(crate) unsafe fn codegen(
928902
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
929903
};
930904

931-
unsafe {
932-
with_codegen(tm, llmod, config.no_builtins, |cpm| {
933-
write_output_file(
934-
dcx,
935-
tm,
936-
cpm,
937-
llmod,
938-
&obj_out,
939-
dwo_out,
940-
llvm::FileType::ObjectFile,
941-
&cgcx.prof,
942-
config.verify_llvm_ir,
943-
)
944-
})?;
945-
}
905+
write_output_file(
906+
dcx,
907+
tm,
908+
config.no_builtins,
909+
llmod,
910+
&obj_out,
911+
dwo_out,
912+
llvm::FileType::ObjectFile,
913+
&cgcx.prof,
914+
config.verify_llvm_ir,
915+
)?;
946916
}
947917

948918
EmitObj::Bitcode => {

0 commit comments

Comments
 (0)