async-llvm(1): Run LLVM already in trans_crate().

This commit is contained in:
Michael Woerister 2017-07-21 15:14:21 +02:00
parent 2a6828e7f1
commit c4adeceb37
4 changed files with 129 additions and 72 deletions

View File

@ -15,8 +15,7 @@ use rustc_data_structures::stable_hasher::StableHasher;
use rustc_mir as mir;
use rustc::session::{Session, CompileResult};
use rustc::session::CompileIncomplete;
use rustc::session::config::{self, Input, OutputFilenames, OutputType,
OutputTypes};
use rustc::session::config::{self, Input, OutputFilenames, OutputType};
use rustc::session::search_paths::PathKind;
use rustc::lint;
use rustc::middle::{self, dependency_format, stability, reachable};
@ -26,7 +25,6 @@ use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
use rustc::traits;
use rustc::util::common::{ErrorReported, time};
use rustc::util::nodemap::NodeSet;
use rustc::util::fs::rename_or_copy_remove;
use rustc_allocator as allocator;
use rustc_borrowck as borrowck;
use rustc_incremental::{self, IncrementalHashesMap};
@ -231,7 +229,7 @@ pub fn compile_input(sess: &Session,
sess.code_stats.borrow().print_type_sizes();
}
let phase5_result = phase_5_run_llvm_passes(sess, &trans, &outputs);
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans, &outputs);
controller_entry_point!(after_llvm,
sess,
@ -1057,7 +1055,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
analysis: ty::CrateAnalysis,
incremental_hashes_map: &IncrementalHashesMap,
output_filenames: &OutputFilenames)
-> trans::CrateTranslation {
-> trans::OngoingCrateTranslation {
let time_passes = tcx.sess.time_passes();
time(time_passes,
@ -1069,61 +1067,26 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
"translation",
move || trans::trans_crate(tcx, analysis, &incremental_hashes_map, output_filenames));
time(time_passes,
"assert dep graph",
|| rustc_incremental::assert_dep_graph(tcx));
time(time_passes,
"serialize dep graph",
|| rustc_incremental::save_dep_graph(tcx,
&incremental_hashes_map,
&translation.metadata.hashes,
translation.link.crate_hash));
translation
}
/// Run LLVM itself, producing a bitcode file, assembly file or object file
/// as a side effect.
pub fn phase_5_run_llvm_passes(sess: &Session,
trans: &trans::CrateTranslation,
outputs: &OutputFilenames) -> CompileResult {
if sess.opts.cg.no_integrated_as ||
(sess.target.target.options.no_integrated_as &&
(outputs.outputs.contains_key(&OutputType::Object) ||
outputs.outputs.contains_key(&OutputType::Exe)))
{
let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
time(sess.time_passes(),
"LLVM passes",
|| write::run_passes(sess, trans, &output_types, outputs));
trans: trans::OngoingCrateTranslation,
outputs: &OutputFilenames)
-> (CompileResult, trans::CrateTranslation) {
let trans = trans.join(sess, outputs);
write::run_assembler(sess, outputs);
// HACK the linker expects the object file to be named foo.0.o but
// `run_assembler` produces an object named just foo.o. Rename it if we
// are going to build an executable
if sess.opts.output_types.contains_key(&OutputType::Exe) {
let f = outputs.path(OutputType::Object);
rename_or_copy_remove(&f,
f.with_file_name(format!("{}.0.o",
f.file_stem().unwrap().to_string_lossy()))).unwrap();
}
// Remove assembly source, unless --save-temps was specified
if !sess.opts.cg.save_temps {
fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap();
}
} else {
time(sess.time_passes(),
"LLVM passes",
|| write::run_passes(sess, trans, &sess.opts.output_types, outputs));
if sess.opts.debugging_opts.incremental_info {
write::dump_incremental_data(&trans);
}
time(sess.time_passes(),
"serialize work products",
move || rustc_incremental::save_work_products(sess));
sess.compile_status()
(sess.compile_status(), trans)
}
/// Run the linker on any artifacts that resulted from the LLVM run.

View File

@ -18,7 +18,7 @@ use rustc::session::Session;
use llvm;
use llvm::{ModuleRef, TargetMachineRef, PassManagerRef, DiagnosticInfoRef};
use llvm::SMDiagnosticRef;
use {CrateTranslation, ModuleLlvm, ModuleSource, ModuleTranslation};
use {CrateTranslation, OngoingCrateTranslation, ModuleLlvm, ModuleSource, ModuleTranslation};
use rustc::hir::def_id::CrateNum;
use rustc::util::common::{time, time_depth, set_time_depth, path2cstr};
use rustc::util::fs::link_or_copy;
@ -255,7 +255,7 @@ impl ModuleConfig {
}
}
fn set_flags(&mut self, sess: &Session, trans: &CrateTranslation) {
fn set_flags(&mut self, sess: &Session, trans: &OngoingCrateTranslation) {
self.no_verify = sess.no_verify();
self.no_prepopulate_passes = sess.opts.cg.no_prepopulate_passes;
self.no_builtins = trans.no_builtins;
@ -614,7 +614,7 @@ pub fn cleanup_llvm(trans: &CrateTranslation) {
}
pub fn run_passes(sess: &Session,
trans: &CrateTranslation,
trans: &OngoingCrateTranslation,
output_types: &OutputTypes,
crate_output: &OutputFilenames) {
// It's possible that we have `codegen_units > 1` but only one item in
@ -748,10 +748,6 @@ pub fn run_passes(sess: &Session,
work_items.push(work);
}
if sess.opts.debugging_opts.incremental_info {
dump_incremental_data(&trans);
}
let client = sess.jobserver_from_env.clone().unwrap_or_else(|| {
// Pick a "reasonable maximum" if we don't otherwise have a jobserver in
// our environment, capping out at 32 so we don't take everything down
@ -938,7 +934,7 @@ pub fn run_passes(sess: &Session,
}
}
fn dump_incremental_data(trans: &CrateTranslation) {
pub fn dump_incremental_data(trans: &CrateTranslation) {
let mut reuse = 0;
for mtrans in trans.modules.iter() {
match mtrans.source {

View File

@ -23,7 +23,7 @@
//! but one TypeRef corresponds to many `Ty`s; for instance, tup(int, int,
//! int) and rec(x=int, y=int, z=int) will have the same TypeRef.
use super::CrateTranslation;
use super::OngoingCrateTranslation;
use super::ModuleLlvm;
use super::ModuleSource;
use super::ModuleTranslation;
@ -43,9 +43,9 @@ use rustc::dep_graph::AssertDepGraphSafe;
use rustc::middle::cstore::LinkMeta;
use rustc::hir::map as hir_map;
use rustc::util::common::time;
use rustc::session::config::{self, NoDebugInfo, OutputFilenames};
use rustc::session::config::{self, NoDebugInfo, OutputFilenames, OutputType, OutputTypes};
use rustc::session::Session;
use rustc_incremental::IncrementalHashesMap;
use rustc_incremental::{self, IncrementalHashesMap};
use abi;
use allocator;
use mir::lvalue::LvalueRef;
@ -922,7 +922,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
analysis: ty::CrateAnalysis,
incremental_hashes_map: &IncrementalHashesMap,
output_filenames: &OutputFilenames)
-> CrateTranslation {
-> OngoingCrateTranslation {
// Be careful with this krate: obviously it gives access to the
// entire contents of the krate. So if you push any subtasks of
// `TransCrate`, you need to be careful to register "reads" of the
@ -961,17 +961,18 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
!tcx.sess.opts.output_types.should_trans() {
let empty_exported_symbols = ExportedSymbols::empty();
let linker_info = LinkerInfo::new(&shared_ccx, &empty_exported_symbols);
return CrateTranslation {
return OngoingCrateTranslation {
crate_name: tcx.crate_name(LOCAL_CRATE),
modules: vec![],
metadata_module: metadata_module,
allocator_module: None,
link: link_meta,
metadata: metadata,
exported_symbols: empty_exported_symbols,
exported_symbols: Arc::new(empty_exported_symbols),
no_builtins: no_builtins,
linker_info: linker_info,
windows_subsystem: None,
no_integrated_as: false,
};
}
@ -1210,19 +1211,52 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
subsystem.to_string()
});
CrateTranslation {
let outputs = output_filenames;
let no_integrated_as = sess.opts.cg.no_integrated_as ||
(sess.target.target.options.no_integrated_as &&
(outputs.outputs.contains_key(&OutputType::Object) ||
outputs.outputs.contains_key(&OutputType::Exe)));
let crate_translation = OngoingCrateTranslation {
crate_name: tcx.crate_name(LOCAL_CRATE),
modules: modules,
metadata_module: metadata_module,
allocator_module: allocator_module,
link: link_meta,
metadata: metadata,
exported_symbols: Arc::try_unwrap(exported_symbols)
.expect("There's still a reference to exported_symbols?"),
no_builtins: no_builtins,
linker_info: linker_info,
windows_subsystem: windows_subsystem,
}
exported_symbols,
no_builtins,
linker_info,
windows_subsystem,
no_integrated_as,
modules,
metadata_module,
allocator_module,
};
time(sess.time_passes(),
"assert dep graph",
|| rustc_incremental::assert_dep_graph(tcx));
time(sess.time_passes(),
"serialize dep graph",
|| rustc_incremental::save_dep_graph(tcx,
incremental_hashes_map,
&crate_translation.metadata.hashes,
crate_translation.link.crate_hash));
// ---
if no_integrated_as {
let output_types = OutputTypes::new(&[(OutputType::Assembly, None)]);
time(sess.time_passes(),
"LLVM passes",
|| ::back::write::run_passes(sess, &crate_translation, &output_types, outputs))
} else {
time(sess.time_passes(),
"LLVM passes",
|| ::back::write::run_passes(sess, &crate_translation, &sess.opts.output_types, outputs))
};
crate_translation
}
#[inline(never)] // give this a place in the profiler

View File

@ -35,7 +35,12 @@
#![feature(conservative_impl_trait)]
use rustc::dep_graph::WorkProduct;
use rustc::session::Session;
use rustc::session::config::{OutputType, OutputFilenames};
use rustc::util::fs::rename_or_copy_remove;
use syntax_pos::symbol::Symbol;
use std::fs;
use std::sync::Arc;
extern crate flate2;
extern crate crossbeam;
@ -167,10 +172,69 @@ pub struct CrateTranslation {
pub allocator_module: Option<ModuleTranslation>,
pub link: rustc::middle::cstore::LinkMeta,
pub metadata: rustc::middle::cstore::EncodedMetadata,
pub exported_symbols: back::symbol_export::ExportedSymbols,
pub exported_symbols: Arc<back::symbol_export::ExportedSymbols>,
pub no_builtins: bool,
pub windows_subsystem: Option<String>,
pub linker_info: back::linker::LinkerInfo
}
pub struct OngoingCrateTranslation {
pub crate_name: Symbol,
pub link: rustc::middle::cstore::LinkMeta,
pub metadata: rustc::middle::cstore::EncodedMetadata,
pub exported_symbols: Arc<back::symbol_export::ExportedSymbols>,
pub no_builtins: bool,
pub windows_subsystem: Option<String>,
pub linker_info: back::linker::LinkerInfo,
pub no_integrated_as: bool,
// These will be replaced by a Future.
pub modules: Vec<ModuleTranslation>,
pub metadata_module: ModuleTranslation,
pub allocator_module: Option<ModuleTranslation>,
}
impl OngoingCrateTranslation {
pub fn join(self,
sess: &Session,
outputs: &OutputFilenames)
-> CrateTranslation {
let trans = CrateTranslation {
crate_name: self.crate_name,
link: self.link,
metadata: self.metadata,
exported_symbols: self.exported_symbols,
no_builtins: self.no_builtins,
windows_subsystem: self.windows_subsystem,
linker_info: self.linker_info,
modules: self.modules,
metadata_module: self.metadata_module,
allocator_module: self.allocator_module,
};
if self.no_integrated_as {
back::write::run_assembler(sess, outputs);
// HACK the linker expects the object file to be named foo.0.o but
// `run_assembler` produces an object named just foo.o. Rename it if we
// are going to build an executable
if sess.opts.output_types.contains_key(&OutputType::Exe) {
let f = outputs.path(OutputType::Object);
rename_or_copy_remove(&f,
f.with_file_name(format!("{}.0.o",
f.file_stem().unwrap().to_string_lossy()))).unwrap();
}
// Remove assembly source, unless --save-temps was specified
if !sess.opts.cg.save_temps {
fs::remove_file(&outputs.temp_path(OutputType::Assembly, None)).unwrap();
}
}
trans
}
}
__build_diagnostic_array! { librustc_trans, DIAGNOSTICS }