Skip to content

Commit

Permalink
Auto merge of #42932 - bjorn3:no_llvm_try2, r=eddyb
Browse files Browse the repository at this point in the history
Support compiling rustc without LLVM (try 2)

Now doesn't change rustc_driver.

Supersedes #42752
  • Loading branch information
bors committed Aug 11, 2017
2 parents 38bdbb7 + e539996 commit edd82ee
Show file tree
Hide file tree
Showing 15 changed files with 416 additions and 154 deletions.
19 changes: 19 additions & 0 deletions src/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ pub struct Config {
pub profiler: bool,

// llvm codegen options
pub llvm_enabled: bool,
pub llvm_assertions: bool,
pub llvm_optimize: bool,
pub llvm_release_debuginfo: bool,
Expand Down Expand Up @@ -192,6 +193,7 @@ struct Install {
#[derive(Deserialize, Default)]
#[serde(deny_unknown_fields, rename_all = "kebab-case")]
struct Llvm {
enabled: Option<bool>,
ccache: Option<StringOrBool>,
ninja: Option<bool>,
assertions: Option<bool>,
Expand Down Expand Up @@ -265,6 +267,7 @@ struct TomlTarget {
impl Config {
pub fn parse(build: &str, file: Option<PathBuf>) -> Config {
let mut config = Config::default();
config.llvm_enabled = true;
config.llvm_optimize = true;
config.use_jemalloc = true;
config.backtrace = true;
Expand Down Expand Up @@ -345,6 +348,7 @@ impl Config {
Some(StringOrBool::Bool(false)) | None => {}
}
set(&mut config.ninja, llvm.ninja);
set(&mut config.llvm_enabled, llvm.enabled);
set(&mut config.llvm_assertions, llvm.assertions);
set(&mut config.llvm_optimize, llvm.optimize);
set(&mut config.llvm_release_debuginfo, llvm.release_debuginfo);
Expand Down
4 changes: 4 additions & 0 deletions src/bootstrap/config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,10 @@
# =============================================================================
[llvm]

# Indicates whether rustc will support compilation with LLVM
# note: rustc does not compile without LLVM at the moment
#enabled = true

# Indicates whether the LLVM build is a Release or Debug build
#optimize = true

Expand Down
3 changes: 3 additions & 0 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -429,6 +429,9 @@ impl Build {
if self.config.use_jemalloc {
features.push_str(" jemalloc");
}
if self.config.llvm_enabled {
features.push_str(" llvm");
}
features
}

Expand Down
6 changes: 6 additions & 0 deletions src/bootstrap/native.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ impl Step for Llvm {
fn run(self, builder: &Builder) {
let build = builder.build;
let target = self.target;

// If we're not compiling for LLVM bail out here.
if !build.config.llvm_enabled {
return;
}

// If we're using a custom LLVM bail out here, but we can only use a
// custom LLVM for the build triple.
if let Some(config) = build.config.target_config.get(&target) {
Expand Down
9 changes: 8 additions & 1 deletion src/librustc_driver/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ crate-type = ["dylib"]
arena = { path = "../libarena" }
graphviz = { path = "../libgraphviz" }
log = { version = "0.3", features = ["release_max_level_info"] }
owning_ref = "0.3.3"
env_logger = { version = "0.4", default-features = false }
rustc = { path = "../librustc" }
rustc_allocator = { path = "../librustc_allocator" }
Expand All @@ -29,9 +30,15 @@ rustc_plugin = { path = "../librustc_plugin" }
rustc_privacy = { path = "../librustc_privacy" }
rustc_resolve = { path = "../librustc_resolve" }
rustc_save_analysis = { path = "../librustc_save_analysis" }
rustc_trans = { path = "../librustc_trans" }
rustc_trans = { path = "../librustc_trans", optional = true }
rustc_trans_utils = { path = "../librustc_trans_utils" }
rustc_typeck = { path = "../librustc_typeck" }
serialize = { path = "../libserialize" }
syntax = { path = "../libsyntax" }
syntax_ext = { path = "../libsyntax_ext" }
syntax_pos = { path = "../libsyntax_pos" }

ar = "0.3.0"

[features]
llvm = ["rustc_trans"]
100 changes: 73 additions & 27 deletions src/librustc_driver/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@ use rustc::session::CompileIncomplete;
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};
use rustc::middle::{self, stability, reachable};
#[cfg(feature="llvm")]
use rustc::middle::dependency_format;
use rustc::middle::privacy::AccessLevels;
use rustc::mir::transform::{MIR_CONST, MIR_VALIDATED, MIR_OPTIMIZED, Passes};
use rustc::ty::{self, TyCtxt, Resolutions, GlobalArenas};
Expand All @@ -31,7 +33,9 @@ use rustc_incremental::{self, IncrementalHashesMap};
use rustc_resolve::{MakeGlobMap, Resolver};
use rustc_metadata::creader::CrateLoader;
use rustc_metadata::cstore::{self, CStore};
#[cfg(feature="llvm")]
use rustc_trans::back::{link, write};
#[cfg(feature="llvm")]
use rustc_trans as trans;
use rustc_typeck as typeck;
use rustc_privacy;
Expand Down Expand Up @@ -69,6 +73,11 @@ pub fn compile_input(sess: &Session,
output: &Option<PathBuf>,
addl_plugins: Option<Vec<String>>,
control: &CompileController) -> CompileResult {
#[cfg(feature="llvm")]
use rustc_trans::back::write::OngoingCrateTranslation;
#[cfg(not(feature="llvm"))]
type OngoingCrateTranslation = ();

macro_rules! controller_entry_point {
($point: ident, $tsess: expr, $make_state: expr, $phase_result: expr) => {{
let state = &mut $make_state;
Expand All @@ -88,7 +97,7 @@ pub fn compile_input(sess: &Session,
// We need nested scopes here, because the intermediate results can keep
// large chunks of memory alive and we want to free them as soon as
// possible to keep the peak memory usage low
let (outputs, trans) = {
let (outputs, trans): (OutputFilenames, OngoingCrateTranslation) = {
let krate = match phase_1_parse_input(control, sess, input) {
Ok(krate) => krate,
Err(mut parse_error) => {
Expand All @@ -113,7 +122,8 @@ pub fn compile_input(sess: &Session,
};

let outputs = build_output_filenames(input, outdir, output, &krate.attrs, sess);
let crate_name = link::find_crate_name(Some(sess), &krate.attrs, input);
let crate_name =
::rustc_trans_utils::link::find_crate_name(Some(sess), &krate.attrs, input);
let ExpansionResult { expanded_crate, defs, analysis, resolutions, mut hir_forest } = {
phase_2_configure_and_expand(
sess, &cstore, krate, registry, &crate_name, addl_plugins, control.make_glob_map,
Expand Down Expand Up @@ -206,6 +216,8 @@ pub fn compile_input(sess: &Session,
println!("Pre-trans");
tcx.print_debug_stats();
}

#[cfg(feature="llvm")]
let trans = phase_4_translate_to_llvm(tcx, analysis, incremental_hashes_map,
&outputs);

Expand All @@ -221,38 +233,59 @@ pub fn compile_input(sess: &Session,
}
}

#[cfg(not(feature="llvm"))]
{
let _ = incremental_hashes_map;
sess.err(&format!("LLVM is not supported by this rustc"));
sess.abort_if_errors();
unreachable!();
}

#[cfg(feature="llvm")]
Ok((outputs, trans))
})??
};

if sess.opts.debugging_opts.print_type_sizes {
sess.code_stats.borrow().print_type_sizes();
#[cfg(not(feature="llvm"))]
{
let _ = outputs;
let _ = trans;
unreachable!();
}

let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);
#[cfg(feature="llvm")]
{
if sess.opts.debugging_opts.print_type_sizes {
sess.code_stats.borrow().print_type_sizes();
}

controller_entry_point!(after_llvm,
sess,
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
phase5_result);
phase5_result?;
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, trans);

phase_6_link_output(sess, &trans, &outputs);
controller_entry_point!(after_llvm,
sess,
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
phase5_result);
phase5_result?;

// Now that we won't touch anything in the incremental compilation directory
// any more, we can finalize it (which involves renaming it)
rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash);
phase_6_link_output(sess, &trans, &outputs);

if sess.opts.debugging_opts.perf_stats {
sess.print_perf_stats();
}
// Now that we won't touch anything in the incremental compilation directory
// any more, we can finalize it (which involves renaming it)
rustc_incremental::finalize_session_directory(sess, trans.link.crate_hash);

controller_entry_point!(compilation_done,
sess,
CompileState::state_when_compilation_done(input, sess, outdir, output),
Ok(()));
if sess.opts.debugging_opts.perf_stats {
sess.print_perf_stats();
}

controller_entry_point!(
compilation_done,
sess,
CompileState::state_when_compilation_done(input, sess, outdir, output),
Ok(())
);

Ok(())
Ok(())
}
}

fn keep_hygiene_data(sess: &Session) -> bool {
Expand Down Expand Up @@ -360,6 +393,7 @@ pub struct CompileState<'a, 'tcx: 'a> {
pub resolutions: Option<&'a Resolutions>,
pub analysis: Option<&'a ty::CrateAnalysis>,
pub tcx: Option<TyCtxt<'a, 'tcx, 'tcx>>,
#[cfg(feature="llvm")]
pub trans: Option<&'a trans::CrateTranslation>,
}

Expand All @@ -386,6 +420,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
resolutions: None,
analysis: None,
tcx: None,
#[cfg(feature="llvm")]
trans: None,
}
}
Expand Down Expand Up @@ -474,7 +509,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
}
}


#[cfg(feature="llvm")]
fn state_after_llvm(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
Expand All @@ -488,6 +523,7 @@ impl<'a, 'tcx> CompileState<'a, 'tcx> {
}
}

#[cfg(feature="llvm")]
fn state_when_compilation_done(input: &'a Input,
session: &'tcx Session,
out_dir: &'a Option<PathBuf>,
Expand Down Expand Up @@ -906,6 +942,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
mir::provide(&mut local_providers);
reachable::provide(&mut local_providers);
rustc_privacy::provide(&mut local_providers);
#[cfg(feature="llvm")]
trans::provide(&mut local_providers);
typeck::provide(&mut local_providers);
ty::provide(&mut local_providers);
Expand All @@ -918,6 +955,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,

let mut extern_providers = ty::maps::Providers::default();
cstore::provide(&mut extern_providers);
#[cfg(feature="llvm")]
trans::provide(&mut extern_providers);
ty::provide_extern(&mut extern_providers);
traits::provide_extern(&mut extern_providers);
Expand Down Expand Up @@ -1064,6 +1102,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,

/// Run the translation phase to LLVM, after which the AST and analysis can
/// be discarded.
#[cfg(feature="llvm")]
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
analysis: ty::CrateAnalysis,
incremental_hashes_map: IncrementalHashesMap,
Expand All @@ -1085,6 +1124,7 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,

/// Run LLVM itself, producing a bitcode file, assembly file or object file
/// as a side effect.
#[cfg(feature="llvm")]
pub fn phase_5_run_llvm_passes(sess: &Session,
trans: write::OngoingCrateTranslation)
-> (CompileResult, trans::CrateTranslation) {
Expand All @@ -1103,6 +1143,7 @@ pub fn phase_5_run_llvm_passes(sess: &Session,

/// Run the linker on any artifacts that resulted from the LLVM run.
/// This should produce either a finished executable or library.
#[cfg(feature="llvm")]
pub fn phase_6_link_output(sess: &Session,
trans: &trans::CrateTranslation,
outputs: &OutputFilenames) {
Expand All @@ -1124,7 +1165,12 @@ fn write_out_deps(sess: &Session, outputs: &OutputFilenames, crate_name: &str) {
match *output_type {
OutputType::Exe => {
for output in sess.crate_types.borrow().iter() {
let p = link::filename_for_input(sess, *output, crate_name, outputs);
let p = ::rustc_trans_utils::link::filename_for_input(
sess,
*output,
crate_name,
outputs
);
out_filenames.push(p);
}
}
Expand Down Expand Up @@ -1234,15 +1280,15 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
if base.is_empty() {
base.extend(attr_types);
if base.is_empty() {
base.push(link::default_output_for_target(session));
base.push(::rustc_trans_utils::link::default_output_for_target(session));
}
base.sort();
base.dedup();
}

base.into_iter()
.filter(|crate_type| {
let res = !link::invalid_output_for_target(session, *crate_type);
let res = !::rustc_trans_utils::link::invalid_output_for_target(session, *crate_type);

if !res {
session.warn(&format!("dropping unsupported crate type `{}` for target `{}`",
Expand Down
Loading

0 comments on commit edd82ee

Please sign in to comment.