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

View File

@ -43,11 +43,22 @@ pub trait CodegenBackend {
/// # Panics
///
/// Panics when the passed `Box<dyn Any>` was not returned by `codegen_backend`.
fn join_codegen_and_link(
fn join_codegen(
&self,
ongoing_codegen: Box<dyn Any>,
sess: &Session,
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,
) -> Result<(), ErrorReported>;
}

View File

@ -310,19 +310,22 @@ pub struct Linker {
impl Linker {
pub fn link(self) -> Result<()> {
let r = self
.codegen_backend
.join_codegen_and_link(
self.ongoing_codegen,
&self.sess,
&self.dep_graph,
&self.prepare_outputs,
)
.map_err(|_| ErrorReported);
let codegen_results =
self.codegen_backend.join_codegen(self.ongoing_codegen, &self.sess, &self.dep_graph)?;
let prof = self.sess.prof.clone();
let dep_graph = self.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)
}
fn join_codegen_and_link(
fn join_codegen(
&self,
ongoing_codegen: Box<dyn Any>,
sess: &Session,
_sess: &Session,
_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,
) -> Result<(), ErrorReported> {
use std::io::Write;
use rustc::session::config::CrateType;
use rustc_codegen_utils::link::out_filename;
let crate_name = ongoing_codegen.downcast::<Symbol>()
.expect("in join_codegen_and_link: ongoing_codegen is not a Symbol");
let crate_name = codegen_results.downcast::<Symbol>()
.expect("in link: codegen_results is not a Symbol");
for &crate_type in sess.opts.crate_types.iter() {
if crate_type != CrateType::Rlib {
sess.fatal(&format!("Crate type is {:?}", crate_type));