async-llvm(1): Run LLVM already in trans_crate().
This commit is contained in:
parent
2a6828e7f1
commit
c4adeceb37
@ -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.
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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 }
|
||||
|
Loading…
x
Reference in New Issue
Block a user