Split join_codegen_and_link() into two steps

`join_codegen_and_link()` is split to `join_codegen()` and `link()`.
This commit is contained in:
Victor Ding 2020-01-29 00:16:14 +11:00
parent b181835a6b
commit ae51d2ba32
4 changed files with 55 additions and 28 deletions

View File

@ -29,7 +29,7 @@ use rustc::dep_graph::WorkProduct;
use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule}; use rustc_codegen_ssa::back::lto::{LtoModuleCodegen, SerializedModule, ThinModule};
use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig}; use rustc_codegen_ssa::back::write::{CodegenContext, FatLTOInput, ModuleConfig};
use rustc_codegen_ssa::traits::*; use rustc_codegen_ssa::traits::*;
use rustc_codegen_ssa::CompiledModule; use rustc_codegen_ssa::{CodegenResults, CompiledModule};
use rustc_errors::{FatalError, Handler}; use rustc_errors::{FatalError, Handler};
use std::any::Any; use std::any::Any;
use std::ffi::CStr; use std::ffi::CStr;
@ -39,7 +39,7 @@ use syntax::expand::allocator::AllocatorKind;
use rustc::dep_graph::DepGraph; use rustc::dep_graph::DepGraph;
use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn}; use rustc::middle::cstore::{EncodedMetadata, MetadataLoaderDyn};
use rustc::session::config::{OptLevel, OutputFilenames, OutputType, PrintRequest}; use rustc::session::config::{OptLevel, OutputFilenames, PrintRequest};
use rustc::session::Session; use rustc::session::Session;
use rustc::ty::{self, TyCtxt}; use rustc::ty::{self, TyCtxt};
use rustc::util::common::ErrorReported; use rustc::util::common::ErrorReported;
@ -270,13 +270,12 @@ impl CodegenBackend for LlvmCodegenBackend {
) )
} }
fn join_codegen_and_link( fn join_codegen(
&self, &self,
ongoing_codegen: Box<dyn Any>, ongoing_codegen: Box<dyn Any>,
sess: &Session, sess: &Session,
dep_graph: &DepGraph, dep_graph: &DepGraph,
outputs: &OutputFilenames, ) -> Result<Box<dyn Any>, ErrorReported> {
) -> Result<(), ErrorReported> {
let (codegen_results, work_products) = ongoing_codegen let (codegen_results, work_products) = ongoing_codegen
.downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<LlvmCodegenBackend>>() .downcast::<rustc_codegen_ssa::back::write::OngoingCodegen<LlvmCodegenBackend>>()
.expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box<Any>") .expect("Expected LlvmCodegenBackend's OngoingCodegen, found Box<Any>")
@ -291,14 +290,18 @@ impl CodegenBackend for LlvmCodegenBackend {
sess.compile_status()?; sess.compile_status()?;
if !sess Ok(Box::new(codegen_results))
.opts }
.output_types
.keys() fn link(
.any(|&i| i == OutputType::Exe || i == OutputType::Metadata) &self,
{ sess: &Session,
return Ok(()); codegen_results: Box<dyn Any>,
} outputs: &OutputFilenames,
) -> Result<(), ErrorReported> {
let codegen_results = codegen_results
.downcast::<CodegenResults>()
.expect("Expected CodegenResults, found Box<Any>");
if sess.opts.debugging_opts.no_link { if sess.opts.debugging_opts.no_link {
// FIXME: use a binary format to encode the `.rlink` file // FIXME: use a binary format to encode the `.rlink` file

View File

@ -43,11 +43,22 @@ pub trait CodegenBackend {
/// # Panics /// # Panics
/// ///
/// Panics when the passed `Box<dyn Any>` was not returned by `codegen_backend`. /// Panics when the passed `Box<dyn Any>` was not returned by `codegen_backend`.
fn join_codegen_and_link( fn join_codegen(
&self, &self,
ongoing_codegen: Box<dyn Any>, ongoing_codegen: Box<dyn Any>,
sess: &Session, sess: &Session,
dep_graph: &DepGraph, dep_graph: &DepGraph,
) -> Result<Box<dyn Any>, ErrorReported>;
/// This is called on the returned `Box<dyn Any>` from `join_codegen`
///
/// # Panics
///
/// Panics when the passed `Box<dyn Any>` was not returned by `join_codegen`.
fn link(
&self,
sess: &Session,
codegen_results: Box<dyn Any>,
outputs: &OutputFilenames, outputs: &OutputFilenames,
) -> Result<(), ErrorReported>; ) -> Result<(), ErrorReported>;
} }

View File

@ -310,19 +310,22 @@ pub struct Linker {
impl Linker { impl Linker {
pub fn link(self) -> Result<()> { pub fn link(self) -> Result<()> {
let r = self let codegen_results =
.codegen_backend self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess, &self.dep_graph)?;
.join_codegen_and_link(
self.ongoing_codegen,
&self.sess,
&self.dep_graph,
&self.prepare_outputs,
)
.map_err(|_| ErrorReported);
let prof = self.sess.prof.clone(); let prof = self.sess.prof.clone();
let dep_graph = self.dep_graph; let dep_graph = self.dep_graph;
prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph)); prof.generic_activity("drop_dep_graph").run(move || drop(dep_graph));
r
if !self
.sess
.opts
.output_types
.keys()
.any(|&i| i == OutputType::Exe || i == OutputType::Metadata)
{
return Ok(());
}
self.codegen_backend.link(&self.sess, codegen_results, &self.prepare_outputs)
} }
} }

View File

@ -71,18 +71,28 @@ impl CodegenBackend for TheBackend {
Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol) Box::new(tcx.crate_name(LOCAL_CRATE) as Symbol)
} }
fn join_codegen_and_link( fn join_codegen(
&self, &self,
ongoing_codegen: Box<dyn Any>, ongoing_codegen: Box<dyn Any>,
sess: &Session, _sess: &Session,
_dep_graph: &DepGraph, _dep_graph: &DepGraph,
) -> Result<Box<dyn Any>, ErrorReported> {
let crate_name = ongoing_codegen.downcast::<Symbol>()
.expect("in join_codegen: ongoing_codegen is not a Symbol");
Ok(crate_name)
}
fn link(
&self,
sess: &Session,
codegen_results: Box<dyn Any>,
outputs: &OutputFilenames, outputs: &OutputFilenames,
) -> Result<(), ErrorReported> { ) -> Result<(), ErrorReported> {
use std::io::Write; use std::io::Write;
use rustc::session::config::CrateType; use rustc::session::config::CrateType;
use rustc_codegen_utils::link::out_filename; use rustc_codegen_utils::link::out_filename;
let crate_name = ongoing_codegen.downcast::<Symbol>() let crate_name = codegen_results.downcast::<Symbol>()
.expect("in join_codegen_and_link: ongoing_codegen is not a Symbol"); .expect("in link: codegen_results is not a Symbol");
for &crate_type in sess.opts.crate_types.iter() { for &crate_type in sess.opts.crate_types.iter() {
if crate_type != CrateType::Rlib { if crate_type != CrateType::Rlib {
sess.fatal(&format!("Crate type is {:?}", crate_type)); sess.fatal(&format!("Crate type is {:?}", crate_type));