From 48b312f04a89c72cf6db2cbb08bbc7fe6fce9bdb Mon Sep 17 00:00:00 2001 From: bjorn3 <17426603+bjorn3@users.noreply.github.com> Date: Fri, 12 Aug 2022 09:55:59 +0000 Subject: [PATCH] Don't take TyCtxt as argument for compile_global_asm This allows it to be executed on a background thread. --- src/driver/aot.rs | 21 ++++++++++--- src/global_asm.rs | 77 +++++++++++++++++++++++++++-------------------- 2 files changed, 61 insertions(+), 37 deletions(-) diff --git a/src/driver/aot.rs b/src/driver/aot.rs index 0816ebc4599..0ca634affb4 100644 --- a/src/driver/aot.rs +++ b/src/driver/aot.rs @@ -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, + 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), ) diff --git a/src/global_asm.rs b/src/global_asm.rs index 5cd7abfdfb5..14288e99242 100644 --- a/src/global_asm.rs +++ b/src/global_asm.rs @@ -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, +} + +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::>() .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(), )); }