Rollup merge of #152481 - bjorn3:backends_reduce_duplication, r=fmease
Use cg_ssa's produce_final_output_artifacts in cg_clif
This commit is contained in:
commit
596faf0f26
4 changed files with 25 additions and 210 deletions
|
|
@ -2,29 +2,26 @@
|
|||
//! standalone executable.
|
||||
|
||||
use std::env;
|
||||
use std::fs::{self, File};
|
||||
use std::fs::File;
|
||||
use std::io::BufWriter;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::path::PathBuf;
|
||||
use std::sync::Arc;
|
||||
use std::thread::JoinHandle;
|
||||
|
||||
use cranelift_object::{ObjectBuilder, ObjectModule};
|
||||
use rustc_codegen_ssa::assert_module_sources::CguReuse;
|
||||
use rustc_codegen_ssa::back::link::ensure_removed;
|
||||
use rustc_codegen_ssa::back::write::{CompiledModules, produce_final_output_artifacts};
|
||||
use rustc_codegen_ssa::base::determine_cgu_reuse;
|
||||
use rustc_codegen_ssa::{
|
||||
CodegenResults, CompiledModule, CrateInfo, ModuleKind, errors as ssa_errors,
|
||||
};
|
||||
use rustc_codegen_ssa::{CodegenResults, CompiledModule, CrateInfo, ModuleKind};
|
||||
use rustc_data_structures::profiling::SelfProfilerRef;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_data_structures::sync::{IntoDynSyncSend, par_map};
|
||||
use rustc_hir::attrs::Linkage as RLinkage;
|
||||
use rustc_metadata::fs::copy_to_stdout;
|
||||
use rustc_middle::dep_graph::{WorkProduct, WorkProductId};
|
||||
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
|
||||
use rustc_middle::mir::mono::{CodegenUnit, MonoItem, MonoItemData, Visibility};
|
||||
use rustc_session::Session;
|
||||
use rustc_session::config::{OutFileName, OutputFilenames, OutputType};
|
||||
use rustc_session::config::{OutputFilenames, OutputType};
|
||||
|
||||
use crate::base::CodegenedFunction;
|
||||
use crate::concurrency_limiter::{ConcurrencyLimiter, ConcurrencyLimiterToken};
|
||||
|
|
@ -125,203 +122,22 @@ impl OngoingCodegen {
|
|||
|
||||
sess.dcx().abort_if_errors();
|
||||
|
||||
let codegen_results = CodegenResults {
|
||||
modules,
|
||||
allocator_module: self.allocator_module,
|
||||
crate_info: self.crate_info,
|
||||
};
|
||||
let compiled_modules = CompiledModules { modules, allocator_module: self.allocator_module };
|
||||
|
||||
produce_final_output_artifacts(sess, &codegen_results, outputs);
|
||||
produce_final_output_artifacts(sess, &compiled_modules, outputs);
|
||||
|
||||
(codegen_results, work_products)
|
||||
(
|
||||
CodegenResults {
|
||||
crate_info: self.crate_info,
|
||||
|
||||
modules: compiled_modules.modules,
|
||||
allocator_module: compiled_modules.allocator_module,
|
||||
},
|
||||
work_products,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
// Adapted from https://github.com/rust-lang/rust/blob/73476d49904751f8d90ce904e16dfbc278083d2c/compiler/rustc_codegen_ssa/src/back/write.rs#L547C1-L706C2
|
||||
fn produce_final_output_artifacts(
|
||||
sess: &Session,
|
||||
codegen_results: &CodegenResults,
|
||||
crate_output: &OutputFilenames,
|
||||
) {
|
||||
let user_wants_bitcode = false;
|
||||
let mut user_wants_objects = false;
|
||||
|
||||
// Produce final compile outputs.
|
||||
let copy_gracefully = |from: &Path, to: &OutFileName| match to {
|
||||
OutFileName::Stdout => {
|
||||
if let Err(e) = copy_to_stdout(from) {
|
||||
sess.dcx().emit_err(ssa_errors::CopyPath::new(from, to.as_path(), e));
|
||||
}
|
||||
}
|
||||
OutFileName::Real(path) => {
|
||||
if let Err(e) = fs::copy(from, path) {
|
||||
sess.dcx().emit_err(ssa_errors::CopyPath::new(from, path, e));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
let copy_if_one_unit = |output_type: OutputType, keep_numbered: bool| {
|
||||
if codegen_results.modules.len() == 1 {
|
||||
// 1) Only one codegen unit. In this case it's no difficulty
|
||||
// to copy `foo.0.x` to `foo.x`.
|
||||
let path = crate_output.temp_path_for_cgu(
|
||||
output_type,
|
||||
&codegen_results.modules[0].name,
|
||||
sess.invocation_temp.as_deref(),
|
||||
);
|
||||
let output = crate_output.path(output_type);
|
||||
if !output_type.is_text_output() && output.is_tty() {
|
||||
sess.dcx()
|
||||
.emit_err(ssa_errors::BinaryOutputToTty { shorthand: output_type.shorthand() });
|
||||
} else {
|
||||
copy_gracefully(&path, &output);
|
||||
}
|
||||
if !sess.opts.cg.save_temps && !keep_numbered {
|
||||
// The user just wants `foo.x`, not `foo.#module-name#.x`.
|
||||
ensure_removed(sess.dcx(), &path);
|
||||
}
|
||||
} else {
|
||||
if crate_output.outputs.contains_explicit_name(&output_type) {
|
||||
// 2) Multiple codegen units, with `--emit foo=some_name`. We have
|
||||
// no good solution for this case, so warn the user.
|
||||
sess.dcx()
|
||||
.emit_warn(ssa_errors::IgnoringEmitPath { extension: output_type.extension() });
|
||||
} else if crate_output.single_output_file.is_some() {
|
||||
// 3) Multiple codegen units, with `-o some_name`. We have
|
||||
// no good solution for this case, so warn the user.
|
||||
sess.dcx()
|
||||
.emit_warn(ssa_errors::IgnoringOutput { extension: output_type.extension() });
|
||||
} else {
|
||||
// 4) Multiple codegen units, but no explicit name. We
|
||||
// just leave the `foo.0.x` files in place.
|
||||
// (We don't have to do any work in this case.)
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Flag to indicate whether the user explicitly requested bitcode.
|
||||
// Otherwise, we produced it only as a temporary output, and will need
|
||||
// to get rid of it.
|
||||
for output_type in crate_output.outputs.keys() {
|
||||
match *output_type {
|
||||
OutputType::Bitcode | OutputType::ThinLinkBitcode => {
|
||||
// Cranelift doesn't have bitcode
|
||||
// user_wants_bitcode = true;
|
||||
// // Copy to .bc, but always keep the .0.bc. There is a later
|
||||
// // check to figure out if we should delete .0.bc files, or keep
|
||||
// // them for making an rlib.
|
||||
// copy_if_one_unit(OutputType::Bitcode, true);
|
||||
}
|
||||
OutputType::LlvmAssembly => {
|
||||
// Cranelift IR text already emitted during codegen
|
||||
// copy_if_one_unit(OutputType::LlvmAssembly, false);
|
||||
}
|
||||
OutputType::Assembly => {
|
||||
// Currently no support for emitting raw assembly files
|
||||
// copy_if_one_unit(OutputType::Assembly, false);
|
||||
}
|
||||
OutputType::Object => {
|
||||
user_wants_objects = true;
|
||||
copy_if_one_unit(OutputType::Object, true);
|
||||
}
|
||||
OutputType::Mir | OutputType::Metadata | OutputType::Exe | OutputType::DepInfo => {}
|
||||
}
|
||||
}
|
||||
|
||||
// Clean up unwanted temporary files.
|
||||
|
||||
// We create the following files by default:
|
||||
// - #crate#.#module-name#.bc
|
||||
// - #crate#.#module-name#.o
|
||||
// - #crate#.crate.metadata.bc
|
||||
// - #crate#.crate.metadata.o
|
||||
// - #crate#.o (linked from crate.##.o)
|
||||
// - #crate#.bc (copied from crate.##.bc)
|
||||
// We may create additional files if requested by the user (through
|
||||
// `-C save-temps` or `--emit=` flags).
|
||||
|
||||
if !sess.opts.cg.save_temps {
|
||||
// Remove the temporary .#module-name#.o objects. If the user didn't
|
||||
// explicitly request bitcode (with --emit=bc), and the bitcode is not
|
||||
// needed for building an rlib, then we must remove .#module-name#.bc as
|
||||
// well.
|
||||
|
||||
// Specific rules for keeping .#module-name#.bc:
|
||||
// - If the user requested bitcode (`user_wants_bitcode`), and
|
||||
// codegen_units > 1, then keep it.
|
||||
// - If the user requested bitcode but codegen_units == 1, then we
|
||||
// can toss .#module-name#.bc because we copied it to .bc earlier.
|
||||
// - If we're not building an rlib and the user didn't request
|
||||
// bitcode, then delete .#module-name#.bc.
|
||||
// If you change how this works, also update back::link::link_rlib,
|
||||
// where .#module-name#.bc files are (maybe) deleted after making an
|
||||
// rlib.
|
||||
let needs_crate_object = crate_output.outputs.contains_key(&OutputType::Exe);
|
||||
|
||||
let keep_numbered_bitcode = user_wants_bitcode && sess.codegen_units().as_usize() > 1;
|
||||
|
||||
let keep_numbered_objects =
|
||||
needs_crate_object || (user_wants_objects && sess.codegen_units().as_usize() > 1);
|
||||
|
||||
for module in codegen_results.modules.iter() {
|
||||
if let Some(ref path) = module.object {
|
||||
if !keep_numbered_objects {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref path) = module.dwarf_object {
|
||||
if !keep_numbered_objects {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref path) = module.bytecode {
|
||||
if !keep_numbered_bitcode {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !user_wants_bitcode {
|
||||
if let Some(ref allocator_module) = codegen_results.allocator_module {
|
||||
if let Some(ref path) = allocator_module.bytecode {
|
||||
ensure_removed(sess.dcx(), path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if sess.opts.json_artifact_notifications {
|
||||
if codegen_results.modules.len() == 1 {
|
||||
codegen_results.modules[0].for_each_output(|_path, ty| {
|
||||
if sess.opts.output_types.contains_key(&ty) {
|
||||
let descr = ty.shorthand();
|
||||
// for single cgu file is renamed to drop cgu specific suffix
|
||||
// so we regenerate it the same way
|
||||
let path = crate_output.path(ty);
|
||||
sess.dcx().emit_artifact_notification(path.as_path(), descr);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
for module in &codegen_results.modules {
|
||||
module.for_each_output(|path, ty| {
|
||||
if sess.opts.output_types.contains_key(&ty) {
|
||||
let descr = ty.shorthand();
|
||||
sess.dcx().emit_artifact_notification(path, descr);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// We leave the following files around by default:
|
||||
// - #crate#.o
|
||||
// - #crate#.crate.metadata.o
|
||||
// - #crate#.bc
|
||||
// These are used in linking steps and will be cleaned up afterward.
|
||||
}
|
||||
|
||||
fn make_module(sess: &Session, name: String) -> UnwindModule<ObjectModule> {
|
||||
let isa = crate::build_isa(sess, false);
|
||||
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@ extern crate rustc_hir;
|
|||
extern crate rustc_incremental;
|
||||
extern crate rustc_index;
|
||||
extern crate rustc_log;
|
||||
extern crate rustc_metadata;
|
||||
extern crate rustc_session;
|
||||
extern crate rustc_span;
|
||||
extern crate rustc_symbol_mangling;
|
||||
|
|
|
|||
|
|
@ -397,9 +397,9 @@ fn generate_thin_lto_work<B: ExtraBackendMethods>(
|
|||
.collect()
|
||||
}
|
||||
|
||||
struct CompiledModules {
|
||||
modules: Vec<CompiledModule>,
|
||||
allocator_module: Option<CompiledModule>,
|
||||
pub struct CompiledModules {
|
||||
pub modules: Vec<CompiledModule>,
|
||||
pub allocator_module: Option<CompiledModule>,
|
||||
}
|
||||
|
||||
enum MaybeLtoModules<B: WriteBackendMethods> {
|
||||
|
|
@ -532,7 +532,7 @@ fn copy_all_cgu_workproducts_to_incr_comp_cache_dir(
|
|||
work_products
|
||||
}
|
||||
|
||||
fn produce_final_output_artifacts(
|
||||
pub fn produce_final_output_artifacts(
|
||||
sess: &Session,
|
||||
compiled_modules: &CompiledModules,
|
||||
crate_output: &OutputFilenames,
|
||||
|
|
|
|||
|
|
@ -130,14 +130,14 @@ pub(crate) struct CopyPathBuf {
|
|||
// Reports Paths using `Debug` implementation rather than Path's `Display` implementation.
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("could not copy {$from} to {$to}: {$error}")]
|
||||
pub struct CopyPath<'a> {
|
||||
pub(crate) struct CopyPath<'a> {
|
||||
from: DebugArgPath<'a>,
|
||||
to: DebugArgPath<'a>,
|
||||
error: Error,
|
||||
}
|
||||
|
||||
impl<'a> CopyPath<'a> {
|
||||
pub fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> {
|
||||
pub(crate) fn new(from: &'a Path, to: &'a Path, error: Error) -> CopyPath<'a> {
|
||||
CopyPath { from: DebugArgPath(from), to: DebugArgPath(to), error }
|
||||
}
|
||||
}
|
||||
|
|
@ -154,19 +154,19 @@ impl IntoDiagArg for DebugArgPath<'_> {
|
|||
#[diag(
|
||||
"option `-o` or `--emit` is used to write binary output type `{$shorthand}` to stdout, but stdout is a tty"
|
||||
)]
|
||||
pub struct BinaryOutputToTty {
|
||||
pub(crate) struct BinaryOutputToTty {
|
||||
pub shorthand: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("ignoring emit path because multiple .{$extension} files were produced")]
|
||||
pub struct IgnoringEmitPath {
|
||||
pub(crate) struct IgnoringEmitPath {
|
||||
pub extension: &'static str,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag("ignoring -o because multiple .{$extension} files were produced")]
|
||||
pub struct IgnoringOutput {
|
||||
pub(crate) struct IgnoringOutput {
|
||||
pub extension: &'static str,
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue