Remove an unsafe closure invariant by inlining the closure wrapper into the called function
This commit is contained in:
parent
c182ce9cbc
commit
b2cd1b8ead
1 changed files with 50 additions and 80 deletions
|
@ -40,7 +40,7 @@ use crate::errors::{
|
||||||
WithLlvmError, WriteBytecode,
|
WithLlvmError, WriteBytecode,
|
||||||
};
|
};
|
||||||
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
|
use crate::llvm::diagnostic::OptimizationDiagnosticKind::*;
|
||||||
use crate::llvm::{self, DiagnosticInfo, PassManager};
|
use crate::llvm::{self, DiagnosticInfo};
|
||||||
use crate::type_::Type;
|
use crate::type_::Type;
|
||||||
use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util};
|
use crate::{LlvmCodegenBackend, ModuleLlvm, base, common, llvm_util};
|
||||||
|
|
||||||
|
@ -54,7 +54,7 @@ pub(crate) fn llvm_err<'a>(dcx: DiagCtxtHandle<'_>, err: LlvmError<'a>) -> Fatal
|
||||||
fn write_output_file<'ll>(
|
fn write_output_file<'ll>(
|
||||||
dcx: DiagCtxtHandle<'_>,
|
dcx: DiagCtxtHandle<'_>,
|
||||||
target: &'ll llvm::TargetMachine,
|
target: &'ll llvm::TargetMachine,
|
||||||
pm: &llvm::PassManager<'ll>,
|
no_builtins: bool,
|
||||||
m: &'ll llvm::Module,
|
m: &'ll llvm::Module,
|
||||||
output: &Path,
|
output: &Path,
|
||||||
dwo_output: Option<&Path>,
|
dwo_output: Option<&Path>,
|
||||||
|
@ -63,16 +63,19 @@ fn write_output_file<'ll>(
|
||||||
verify_llvm_ir: bool,
|
verify_llvm_ir: bool,
|
||||||
) -> Result<(), FatalError> {
|
) -> Result<(), FatalError> {
|
||||||
debug!("write_output_file output={:?} dwo_output={:?}", output, dwo_output);
|
debug!("write_output_file output={:?} dwo_output={:?}", output, dwo_output);
|
||||||
unsafe {
|
let output_c = path_to_c_string(output);
|
||||||
let output_c = path_to_c_string(output);
|
let dwo_output_c;
|
||||||
let dwo_output_c;
|
let dwo_output_ptr = if let Some(dwo_output) = dwo_output {
|
||||||
let dwo_output_ptr = if let Some(dwo_output) = dwo_output {
|
dwo_output_c = path_to_c_string(dwo_output);
|
||||||
dwo_output_c = path_to_c_string(dwo_output);
|
dwo_output_c.as_ptr()
|
||||||
dwo_output_c.as_ptr()
|
} else {
|
||||||
} else {
|
std::ptr::null()
|
||||||
std::ptr::null()
|
};
|
||||||
};
|
let result = unsafe {
|
||||||
let result = llvm::LLVMRustWriteOutputFile(
|
let pm = llvm::LLVMCreatePassManager();
|
||||||
|
llvm::LLVMAddAnalysisPasses(target, pm);
|
||||||
|
llvm::LLVMRustAddLibraryInfo(pm, m, no_builtins);
|
||||||
|
llvm::LLVMRustWriteOutputFile(
|
||||||
target,
|
target,
|
||||||
pm,
|
pm,
|
||||||
m,
|
m,
|
||||||
|
@ -80,22 +83,22 @@ fn write_output_file<'ll>(
|
||||||
dwo_output_ptr,
|
dwo_output_ptr,
|
||||||
file_type,
|
file_type,
|
||||||
verify_llvm_ir,
|
verify_llvm_ir,
|
||||||
);
|
)
|
||||||
|
};
|
||||||
|
|
||||||
// Record artifact sizes for self-profiling
|
// Record artifact sizes for self-profiling
|
||||||
if result == llvm::LLVMRustResult::Success {
|
if result == llvm::LLVMRustResult::Success {
|
||||||
let artifact_kind = match file_type {
|
let artifact_kind = match file_type {
|
||||||
llvm::FileType::ObjectFile => "object_file",
|
llvm::FileType::ObjectFile => "object_file",
|
||||||
llvm::FileType::AssemblyFile => "assembly_file",
|
llvm::FileType::AssemblyFile => "assembly_file",
|
||||||
};
|
};
|
||||||
record_artifact_size(self_profiler_ref, artifact_kind, output);
|
record_artifact_size(self_profiler_ref, artifact_kind, output);
|
||||||
if let Some(dwo_file) = dwo_output {
|
if let Some(dwo_file) = dwo_output {
|
||||||
record_artifact_size(self_profiler_ref, "dwo_file", dwo_file);
|
record_artifact_size(self_profiler_ref, "dwo_file", dwo_file);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteOutput { path: output }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.into_result().map_err(|()| llvm_err(dcx, LlvmError::WriteOutput { path: output }))
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn create_informational_target_machine(
|
pub(crate) fn create_informational_target_machine(
|
||||||
|
@ -755,31 +758,6 @@ pub(crate) unsafe fn codegen(
|
||||||
create_msvc_imps(cgcx, llcx, llmod);
|
create_msvc_imps(cgcx, llcx, llmod);
|
||||||
}
|
}
|
||||||
|
|
||||||
// A codegen-specific pass manager is used to generate object
|
|
||||||
// files for an LLVM module.
|
|
||||||
//
|
|
||||||
// Apparently each of these pass managers is a one-shot kind of
|
|
||||||
// thing, so we create a new one for each type of output. The
|
|
||||||
// pass manager passed to the closure should be ensured to not
|
|
||||||
// escape the closure itself, and the manager should only be
|
|
||||||
// used once.
|
|
||||||
unsafe fn with_codegen<'ll, F, R>(
|
|
||||||
tm: &'ll llvm::TargetMachine,
|
|
||||||
llmod: &'ll llvm::Module,
|
|
||||||
no_builtins: bool,
|
|
||||||
f: F,
|
|
||||||
) -> R
|
|
||||||
where
|
|
||||||
F: FnOnce(&'ll mut PassManager<'ll>) -> R,
|
|
||||||
{
|
|
||||||
unsafe {
|
|
||||||
let cpm = llvm::LLVMCreatePassManager();
|
|
||||||
llvm::LLVMAddAnalysisPasses(tm, cpm);
|
|
||||||
llvm::LLVMRustAddLibraryInfo(cpm, llmod, no_builtins);
|
|
||||||
f(cpm)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note that if object files are just LLVM bitcode we write bitcode,
|
// Note that if object files are just LLVM bitcode we write bitcode,
|
||||||
// copy it to the .o file, and delete the bitcode if it wasn't
|
// copy it to the .o file, and delete the bitcode if it wasn't
|
||||||
// otherwise requested.
|
// otherwise requested.
|
||||||
|
@ -898,21 +876,17 @@ pub(crate) unsafe fn codegen(
|
||||||
} else {
|
} else {
|
||||||
llmod
|
llmod
|
||||||
};
|
};
|
||||||
unsafe {
|
write_output_file(
|
||||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
dcx,
|
||||||
write_output_file(
|
tm,
|
||||||
dcx,
|
config.no_builtins,
|
||||||
tm,
|
llmod,
|
||||||
cpm,
|
&path,
|
||||||
llmod,
|
None,
|
||||||
&path,
|
llvm::FileType::AssemblyFile,
|
||||||
None,
|
&cgcx.prof,
|
||||||
llvm::FileType::AssemblyFile,
|
config.verify_llvm_ir,
|
||||||
&cgcx.prof,
|
)?;
|
||||||
config.verify_llvm_ir,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match config.emit_obj {
|
match config.emit_obj {
|
||||||
|
@ -936,21 +910,17 @@ pub(crate) unsafe fn codegen(
|
||||||
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
|
(_, SplitDwarfKind::Split) => Some(dwo_out.as_path()),
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
write_output_file(
|
||||||
with_codegen(tm, llmod, config.no_builtins, |cpm| {
|
dcx,
|
||||||
write_output_file(
|
tm,
|
||||||
dcx,
|
config.no_builtins,
|
||||||
tm,
|
llmod,
|
||||||
cpm,
|
&obj_out,
|
||||||
llmod,
|
dwo_out,
|
||||||
&obj_out,
|
llvm::FileType::ObjectFile,
|
||||||
dwo_out,
|
&cgcx.prof,
|
||||||
llvm::FileType::ObjectFile,
|
config.verify_llvm_ir,
|
||||||
&cgcx.prof,
|
)?;
|
||||||
config.verify_llvm_ir,
|
|
||||||
)
|
|
||||||
})?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
EmitObj::Bitcode => {
|
EmitObj::Bitcode => {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue