Skip to content

Commit

Permalink
async-llvm(1): Run LLVM already in trans_crate().
Browse files Browse the repository at this point in the history
  • Loading branch information
michaelwoerister committed Jul 31, 2017
1 parent 2a6828e commit c4adece
Show file tree
Hide file tree
Showing 4 changed files with 129 additions and 72 deletions.
57 changes: 10 additions & 47 deletions src/librustc_driver/driver.rs
Expand Up @@ -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};
Expand All @@ -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};
Expand Down Expand Up @@ -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,
Expand Down Expand Up @@ -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,
Expand All @@ -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));

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();
}
trans: trans::OngoingCrateTranslation,
outputs: &OutputFilenames)
-> (CompileResult, trans::CrateTranslation) {
let trans = trans.join(sess, outputs);

// 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.
Expand Down
12 changes: 4 additions & 8 deletions src/librustc_trans/back/write.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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 {
Expand Down
66 changes: 50 additions & 16 deletions src/librustc_trans/base.rs
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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,
};
}

Expand Down Expand Up @@ -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
Expand Down
66 changes: 65 additions & 1 deletion src/librustc_trans/lib.rs
Expand Up @@ -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;
Expand Down Expand Up @@ -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 }

0 comments on commit c4adece

Please sign in to comment.