Don't take TyCtxt as argument for compile_global_asm

This allows it to be executed on a background thread.
This commit is contained in:
bjorn3 2022-08-12 09:55:59 +00:00
parent 066f844fff
commit 48b312f04a
2 changed files with 61 additions and 37 deletions

View File

@ -1,6 +1,8 @@
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
//! standalone executable.
use std::sync::Arc;
use rustc_codegen_ssa::back::metadata::create_compressed_metadata_file;
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
@ -14,6 +16,7 @@ use rustc_session::Session;
use cranelift_codegen::isa::TargetIsa;
use cranelift_object::{ObjectBuilder, ObjectModule};
use crate::global_asm::GlobalAsmConfig;
use crate::{prelude::*, BackendConfig};
struct ModuleCodegenResult(CompiledModule, Option<(WorkProductId, WorkProduct)>);
@ -141,7 +144,11 @@ fn reuse_workproduct_for_cgu(tcx: TyCtxt<'_>, cgu: &CodegenUnit<'_>) -> ModuleCo
fn module_codegen(
tcx: TyCtxt<'_>,
(backend_config, cgu_name): (BackendConfig, rustc_span::Symbol),
(backend_config, global_asm_config, cgu_name): (
BackendConfig,
Arc<GlobalAsmConfig>,
rustc_span::Symbol,
),
) -> ModuleCodegenResult {
let cgu = tcx.codegen_unit(cgu_name);
let mono_items = cgu.items_in_deterministic_order(tcx);
@ -198,9 +205,13 @@ fn module_codegen(
)
});
match crate::global_asm::compile_global_asm(tcx, cgu.name().as_str(), &cx.global_asm) {
match crate::global_asm::compile_global_asm(
&global_asm_config,
cgu.name().as_str(),
&cx.global_asm,
) {
Ok(()) => {}
Err(err) => tcx.sess.fatal(&err.to_string()),
Err(err) => tcx.sess.fatal(&err),
}
codegen_result
@ -226,6 +237,8 @@ pub(crate) fn run_aot(
}
}
let global_asm_config = Arc::new(crate::global_asm::GlobalAsmConfig::new(tcx));
let modules = super::time(tcx, backend_config.display_cg_time, "codegen mono items", || {
cgus.iter()
.map(|cgu| {
@ -243,7 +256,7 @@ pub(crate) fn run_aot(
.with_task(
dep_node,
tcx,
(backend_config.clone(), cgu.name()),
(backend_config.clone(), global_asm_config.clone(), cgu.name()),
module_codegen,
Some(rustc_middle::dep_graph::hash_result),
)

View File

@ -1,13 +1,14 @@
//! The AOT driver uses [`cranelift_object`] to write object files suitable for linking into a
//! standalone executable.
use std::io::{self, Write};
use std::io::Write;
use std::path::PathBuf;
use std::process::{Command, Stdio};
use std::sync::Arc;
use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
use rustc_hir::ItemId;
use rustc_session::config::OutputType;
use rustc_session::config::{OutputFilenames, OutputType};
use crate::prelude::*;
@ -31,40 +32,56 @@ pub(crate) fn codegen_global_asm_item(tcx: TyCtxt<'_>, global_asm: &mut String,
}
}
#[derive(Debug)]
pub(crate) struct GlobalAsmConfig {
asm_enabled: bool,
assembler: PathBuf,
linker: PathBuf,
output_filenames: Arc<OutputFilenames>,
}
impl GlobalAsmConfig {
pub(crate) fn new(tcx: TyCtxt<'_>) -> Self {
let asm_enabled = cfg!(feature = "inline_asm")
&& !tcx.sess.target.is_like_osx
&& !tcx.sess.target.is_like_windows;
GlobalAsmConfig {
asm_enabled,
assembler: crate::toolchain::get_toolchain_binary(tcx.sess, "as"),
linker: crate::toolchain::get_toolchain_binary(tcx.sess, "ld"),
output_filenames: tcx.output_filenames(()).clone(),
}
}
}
pub(crate) fn compile_global_asm(
tcx: TyCtxt<'_>,
config: &GlobalAsmConfig,
cgu_name: &str,
global_asm: &str,
) -> io::Result<()> {
) -> Result<(), String> {
if global_asm.is_empty() {
return Ok(());
}
if cfg!(not(feature = "inline_asm"))
|| tcx.sess.target.is_like_osx
|| tcx.sess.target.is_like_windows
{
if !config.asm_enabled {
if global_asm.contains("__rust_probestack") {
return Ok(());
}
// FIXME fix linker error on macOS
if cfg!(not(feature = "inline_asm")) {
return Err(io::Error::new(
io::ErrorKind::Unsupported,
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift",
));
return Err(
"asm! and global_asm! support is disabled while compiling rustc_codegen_cranelift"
.to_owned(),
);
} else {
return Err(io::Error::new(
io::ErrorKind::Unsupported,
"asm! and global_asm! are not yet supported on macOS and Windows",
));
return Err(
"asm! and global_asm! are not yet supported on macOS and Windows".to_owned()
);
}
}
let assembler = crate::toolchain::get_toolchain_binary(tcx.sess, "as");
let linker = crate::toolchain::get_toolchain_binary(tcx.sess, "ld");
// Remove all LLVM style comments
let global_asm = global_asm
.lines()
@ -72,11 +89,11 @@ pub(crate) fn compile_global_asm(
.collect::<Vec<_>>()
.join("\n");
let output_object_file = tcx.output_filenames(()).temp_path(OutputType::Object, Some(cgu_name));
let output_object_file = config.output_filenames.temp_path(OutputType::Object, Some(cgu_name));
// Assemble `global_asm`
let global_asm_object_file = add_file_stem_postfix(output_object_file.clone(), ".asm");
let mut child = Command::new(assembler)
let mut child = Command::new(&config.assembler)
.arg("-o")
.arg(&global_asm_object_file)
.stdin(Stdio::piped())
@ -85,16 +102,13 @@ pub(crate) fn compile_global_asm(
child.stdin.take().unwrap().write_all(global_asm.as_bytes()).unwrap();
let status = child.wait().expect("Failed to wait for `as`.");
if !status.success() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!("Failed to assemble `{}`", global_asm),
));
return Err(format!("Failed to assemble `{}`", global_asm));
}
// Link the global asm and main object file together
let main_object_file = add_file_stem_postfix(output_object_file.clone(), ".main");
std::fs::rename(&output_object_file, &main_object_file).unwrap();
let status = Command::new(linker)
let status = Command::new(&config.linker)
.arg("-r") // Create a new object file
.arg("-o")
.arg(output_object_file)
@ -103,13 +117,10 @@ pub(crate) fn compile_global_asm(
.status()
.unwrap();
if !status.success() {
return Err(io::Error::new(
io::ErrorKind::Other,
format!(
"Failed to link `{}` and `{}` together",
main_object_file.display(),
global_asm_object_file.display(),
),
return Err(format!(
"Failed to link `{}` and `{}` together",
main_object_file.display(),
global_asm_object_file.display(),
));
}