Skip to content

Commit 44c1843

Browse files
committed
Add TransCrate trait
1 parent 89af6d5 commit 44c1843

File tree

9 files changed

+337
-50
lines changed

9 files changed

+337
-50
lines changed

src/Cargo.lock

Lines changed: 12 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/librustc_driver/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ rustc_resolve = { path = "../librustc_resolve" }
3333
rustc_save_analysis = { path = "../librustc_save_analysis" }
3434
rustc_trans = { path = "../librustc_trans", optional = true }
3535
rustc_trans_utils = { path = "../librustc_trans_utils" }
36+
rustc_trans_traits = { path = "../librustc_trans_traits" }
3637
rustc_typeck = { path = "../librustc_typeck" }
3738
serialize = { path = "../libserialize" }
3839
syntax = { path = "../libsyntax" }

src/librustc_driver/driver.rs

Lines changed: 19 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,16 @@ use rustc_incremental;
3434
use rustc_resolve::{MakeGlobMap, Resolver};
3535
use rustc_metadata::creader::CrateLoader;
3636
use rustc_metadata::cstore::{self, CStore};
37-
use rustc_trans::back::write;
3837
use rustc_trans as trans;
38+
use rustc_trans_traits::TransCrate;
3939
use rustc_typeck as typeck;
4040
use rustc_privacy;
4141
use rustc_plugin::registry::Registry;
4242
use rustc_plugin as plugin;
4343
use rustc_passes::{ast_validation, no_asm, loops, consts, static_recursion, hir_stats};
4444
use rustc_const_eval::{self, check_match};
4545
use super::Compilation;
46+
use ::DefaultTransCrate;
4647

4748
use serialize::json;
4849

@@ -76,7 +77,6 @@ pub fn compile_input(sess: &Session,
7677
output: &Option<PathBuf>,
7778
addl_plugins: Option<Vec<String>>,
7879
control: &CompileController) -> CompileResult {
79-
use rustc_trans::back::write::OngoingCrateTranslation;
8080
use rustc::session::config::CrateType;
8181

8282
macro_rules! controller_entry_point {
@@ -122,7 +122,7 @@ pub fn compile_input(sess: &Session,
122122
// We need nested scopes here, because the intermediate results can keep
123123
// large chunks of memory alive and we want to free them as soon as
124124
// possible to keep the peak memory usage low
125-
let (outputs, trans, dep_graph): (OutputFilenames, OngoingCrateTranslation, DepGraph) = {
125+
let (outputs, trans, dep_graph) = {
126126
let krate = match phase_1_parse_input(control, sess, input) {
127127
Ok(krate) => krate,
128128
Err(mut parse_error) => {
@@ -251,7 +251,7 @@ pub fn compile_input(sess: &Session,
251251
tcx.print_debug_stats();
252252
}
253253

254-
let trans = phase_4_translate_to_llvm(tcx, rx);
254+
let trans = phase_4_translate_to_llvm::<DefaultTransCrate>(tcx, rx);
255255

256256
if log_enabled!(::log::LogLevel::Info) {
257257
println!("Post-trans");
@@ -285,15 +285,15 @@ pub fn compile_input(sess: &Session,
285285
sess.code_stats.borrow().print_type_sizes();
286286
}
287287

288-
let (phase5_result, trans) = phase_5_run_llvm_passes(sess, &dep_graph, trans);
288+
let (phase5_result, trans) = phase_5_run_llvm_passes::<DefaultTransCrate>(sess, &dep_graph, trans);
289289

290290
controller_entry_point!(after_llvm,
291291
sess,
292292
CompileState::state_after_llvm(input, sess, outdir, output, &trans),
293293
phase5_result);
294294
phase5_result?;
295295

296-
phase_6_link_output(sess, &trans, &outputs);
296+
phase_6_link_output::<DefaultTransCrate>(sess, &trans, &outputs);
297297

298298
// Now that we won't touch anything in the incremental compilation directory
299299
// any more, we can finalize it (which involves renaming it)
@@ -972,7 +972,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
972972
mir::provide(&mut local_providers);
973973
reachable::provide(&mut local_providers);
974974
rustc_privacy::provide(&mut local_providers);
975-
trans::provide_local(&mut local_providers);
975+
DefaultTransCrate::provide_local(&mut local_providers);
976976
typeck::provide(&mut local_providers);
977977
ty::provide(&mut local_providers);
978978
traits::provide(&mut local_providers);
@@ -984,7 +984,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
984984

985985
let mut extern_providers = ty::maps::Providers::default();
986986
cstore::provide(&mut extern_providers);
987-
trans::provide_extern(&mut extern_providers);
987+
DefaultTransCrate::provide_extern(&mut extern_providers);
988988
ty::provide_extern(&mut extern_providers);
989989
traits::provide_extern(&mut extern_providers);
990990
// FIXME(eddyb) get rid of this once we replace const_eval with miri.
@@ -1130,9 +1130,9 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
11301130

11311131
/// Run the translation phase to LLVM, after which the AST and analysis can
11321132
/// be discarded.
1133-
pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
1133+
pub fn phase_4_translate_to_llvm<'a, 'tcx, T: TransCrate>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11341134
rx: mpsc::Receiver<Box<Any + Send>>)
1135-
-> write::OngoingCrateTranslation {
1135+
-> <T as TransCrate>::OngoingCrateTranslation {
11361136
let time_passes = tcx.sess.time_passes();
11371137

11381138
time(time_passes,
@@ -1141,9 +1141,8 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11411141

11421142
let translation =
11431143
time(time_passes, "translation", move || {
1144-
trans::trans_crate(tcx, rx)
1144+
T::trans_crate(tcx, rx)
11451145
});
1146-
11471146
if tcx.sess.profile_queries() {
11481147
profile::dump("profile_queries".to_string())
11491148
}
@@ -1153,15 +1152,14 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11531152

11541153
/// Run LLVM itself, producing a bitcode file, assembly file or object file
11551154
/// as a side effect.
1156-
#[cfg(feature="llvm")]
1157-
pub fn phase_5_run_llvm_passes(sess: &Session,
1155+
pub fn phase_5_run_llvm_passes<T: TransCrate>(sess: &Session,
11581156
dep_graph: &DepGraph,
1159-
trans: write::OngoingCrateTranslation)
1160-
-> (CompileResult, trans::CrateTranslation) {
1161-
let trans = trans.join(sess, dep_graph);
1157+
trans: <T as TransCrate>::OngoingCrateTranslation)
1158+
-> (CompileResult, <T as TransCrate>::TranslatedCrate) {
1159+
let trans = T::join_trans(trans, sess, dep_graph);
11621160

11631161
if sess.opts.debugging_opts.incremental_info {
1164-
write::dump_incremental_data(&trans);
1162+
T::dump_incremental_data(&trans);
11651163
}
11661164

11671165
time(sess.time_passes(),
@@ -1174,14 +1172,11 @@ pub fn phase_5_run_llvm_passes(sess: &Session,
11741172
/// Run the linker on any artifacts that resulted from the LLVM run.
11751173
/// This should produce either a finished executable or library.
11761174
#[cfg(feature="llvm")]
1177-
pub fn phase_6_link_output(sess: &Session,
1178-
trans: &trans::CrateTranslation,
1175+
pub fn phase_6_link_output<T: TransCrate>(sess: &Session,
1176+
trans: &<T as TransCrate>::TranslatedCrate,
11791177
outputs: &OutputFilenames) {
11801178
time(sess.time_passes(), "linking", || {
1181-
::rustc_trans::back::link::link_binary(sess,
1182-
trans,
1183-
outputs,
1184-
&trans.crate_name.as_str())
1179+
T::link_binary(sess, trans, outputs)
11851180
});
11861181
}
11871182

src/librustc_driver/lib.rs

Lines changed: 115 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@
2525
#![feature(rustc_diagnostic_macros)]
2626
#![feature(set_stdio)]
2727

28-
#[cfg(not(feature="llvm"))]
2928
extern crate ar;
30-
#[cfg(not(feature="llvm"))]
3129
extern crate flate2;
3230
extern crate arena;
3331
extern crate getopts;
@@ -54,6 +52,7 @@ extern crate rustc_save_analysis;
5452
#[cfg(feature="llvm")]
5553
extern crate rustc_trans;
5654
extern crate rustc_trans_utils;
55+
extern crate rustc_trans_traits;
5756
extern crate rustc_typeck;
5857
extern crate serialize;
5958
#[macro_use]
@@ -79,6 +78,7 @@ use rustc::middle::cstore::CrateStore;
7978
use rustc_metadata::locator;
8079
use rustc_metadata::cstore::CStore;
8180
use rustc::util::common::{time, ErrorReported};
81+
use rustc_trans_traits::TransCrate;
8282

8383
use serialize::json::ToJson;
8484

@@ -155,11 +155,10 @@ pub fn run<F>(run_compiler: F) -> isize
155155
}
156156

157157
#[cfg(not(feature="llvm"))]
158-
pub use no_llvm_metadata_loader::NoLLvmMetadataLoader as MetadataLoader;
158+
pub use trans_metadata_only::MetadataOnlyTransCrate as DefaultTransCrate;
159159
#[cfg(feature="llvm")]
160-
pub use rustc_trans::LlvmMetadataLoader as MetadataLoader;
160+
pub use rustc_trans::LlvmTransCrate as DefaultTransCrate;
161161

162-
#[cfg(not(feature="llvm"))]
163162
mod no_llvm_metadata_loader {
164163
extern crate owning_ref;
165164

@@ -172,9 +171,9 @@ mod no_llvm_metadata_loader {
172171
use ar::Archive;
173172
use self::owning_ref::{OwningRef, ErasedBoxRef};
174173

175-
pub struct NoLLvmMetadataLoader;
174+
pub struct NoLlvmMetadataLoader;
176175

177-
impl MetadataLoaderTrait for NoLLvmMetadataLoader {
176+
impl MetadataLoaderTrait for NoLlvmMetadataLoader {
178177
fn get_rlib_metadata(
179178
&self,
180179
_: &Target,
@@ -210,40 +209,131 @@ mod no_llvm_metadata_loader {
210209
}
211210
}
212211

213-
#[cfg(not(feature="llvm"))]
214-
mod rustc_trans {
215-
use syntax_pos::symbol::Symbol;
212+
mod trans_metadata_only {
213+
use std::io::prelude::*;
214+
use std::io::Cursor;
215+
use std::fs::File;
216+
217+
use ar::{Builder, Header};
218+
use flate2::Compression;
219+
use flate2::write::DeflateEncoder;
220+
221+
use syntax::symbol::Symbol;
222+
use rustc::hir::def_id::LOCAL_CRATE;
216223
use rustc::session::Session;
217-
use rustc::session::config::{PrintRequest, OutputFilenames};
224+
use rustc::session::config::{OutputFilenames, CrateType};
218225
use rustc::ty::{TyCtxt, CrateAnalysis};
219226
use rustc::ty::maps::Providers;
227+
use rustc::middle::cstore::{MetadataLoader, EncodedMetadata};
228+
use rustc::dep_graph::DepGraph;
220229
use rustc_incremental::IncrementalHashesMap;
230+
use rustc_trans_utils::find_exported_symbols;
231+
use rustc_trans_utils::link::{out_filename, build_link_meta};
232+
use rustc_trans_traits::TransCrate;
233+
234+
#[allow(dead_code)]
235+
pub struct MetadataOnlyTransCrate;
236+
pub struct OngoingCrateTranslation {
237+
metadata: EncodedMetadata,
238+
metadata_version: Vec<u8>,
239+
crate_name: Symbol,
240+
}
241+
pub struct TranslatedCrate(OngoingCrateTranslation);
242+
243+
impl MetadataOnlyTransCrate {
244+
#[allow(dead_code)]
245+
pub fn new(/*_sess: &Session*/) -> Self {
246+
MetadataOnlyTransCrate
247+
}
248+
}
249+
250+
impl TransCrate for MetadataOnlyTransCrate {
251+
type MetadataLoader = ::no_llvm_metadata_loader::NoLlvmMetadataLoader;
252+
type OngoingCrateTranslation = OngoingCrateTranslation;
253+
type TranslatedCrate = TranslatedCrate;
254+
255+
fn metadata_loader() -> Box<MetadataLoader> {
256+
box ::no_llvm_metadata_loader::NoLlvmMetadataLoader
257+
}
258+
259+
fn provide(_providers: &mut Providers) {}
260+
261+
fn trans_crate<'a, 'tcx>(
262+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
263+
analysis: CrateAnalysis,
264+
incr_hashes_map: IncrementalHashesMap,
265+
_output_filenames: &OutputFilenames
266+
) -> Self::OngoingCrateTranslation {
267+
let link_meta = build_link_meta(&incr_hashes_map);
268+
let exported_symbols = find_exported_symbols(tcx, &analysis.reachable);
269+
let (metadata, _hashes) = tcx.encode_metadata(&link_meta, &exported_symbols);
270+
271+
OngoingCrateTranslation {
272+
metadata: metadata,
273+
metadata_version: tcx.metadata_encoding_version().to_vec(),
274+
crate_name: tcx.crate_name(LOCAL_CRATE),
275+
}
276+
}
221277

222-
use self::back::write::OngoingCrateTranslation;
278+
fn join_trans(
279+
trans: Self::OngoingCrateTranslation,
280+
_sess: &Session,
281+
_dep_graph: &DepGraph,
282+
) -> Self::TranslatedCrate {
283+
TranslatedCrate(trans)
284+
}
285+
286+
fn link_binary(sess: &Session,
287+
trans: &Self::TranslatedCrate,
288+
outputs: &OutputFilenames) {
289+
for &crate_type in sess.opts.crate_types.iter() {
290+
if crate_type != CrateType::CrateTypeRlib &&
291+
crate_type != CrateType::CrateTypeDylib {
292+
continue;
293+
}
294+
let output_name =
295+
out_filename(sess, crate_type, &outputs, &trans.0.crate_name.as_str());
296+
let mut compressed = trans.0.metadata_version.clone();
297+
let metadata = if crate_type == CrateType::CrateTypeDylib {
298+
DeflateEncoder::new(&mut compressed, Compression::Fast)
299+
.write_all(&trans.0.metadata.raw_data).unwrap();
300+
&compressed
301+
} else {
302+
&trans.0.metadata.raw_data
303+
};
304+
let mut builder = Builder::new(File::create(&output_name).unwrap());
305+
let header = Header::new(
306+
"rust.metadata.bin".to_string(),
307+
metadata.len() as u64
308+
);
309+
builder
310+
.append(&header, Cursor::new(metadata))
311+
.unwrap();
312+
}
313+
}
314+
315+
fn dump_incremental_data(_trans: &Self::TranslatedCrate) {}
316+
}
317+
}
318+
319+
#[cfg(not(feature="llvm"))]
320+
mod rustc_trans {
321+
use syntax_pos::symbol::Symbol;
322+
use rustc::session::Session;
323+
use rustc::session::config::PrintRequest;
324+
pub use trans_metadata_only::MetadataOnlyTransCrate as LlvmTransCrate;
223325

224326
pub fn init(_sess: &Session) {}
225327
pub fn enable_llvm_debug() {}
226-
pub fn provide(_providers: &mut Providers) {}
227328
pub fn print_version() {}
228329
pub fn print_passes() {}
229330
pub fn print(_req: PrintRequest, _sess: &Session) {}
230331
pub fn target_features(_sess: &Session) -> Vec<Symbol> { vec![] }
231332

232-
pub fn trans_crate<'a, 'tcx>(
233-
_tcx: TyCtxt<'a, 'tcx, 'tcx>,
234-
_analysis: CrateAnalysis,
235-
_incr_hashes_map: IncrementalHashesMap,
236-
_output_filenames: &OutputFilenames
237-
) -> OngoingCrateTranslation {
238-
OngoingCrateTranslation(())
239-
}
240-
241333
pub struct CrateTranslation(());
242334

243335
pub mod back {
244336
pub mod write {
245-
pub struct OngoingCrateTranslation(pub (in ::rustc_trans) ());
246-
247337
pub const RELOC_MODEL_ARGS: [(&'static str, ()); 0] = [];
248338
pub const CODE_GEN_MODEL_ARGS: [(&'static str, ()); 0] = [];
249339
}
@@ -297,7 +387,7 @@ pub fn run_compiler<'a>(args: &[String],
297387
},
298388
};
299389

300-
let cstore = Rc::new(CStore::new(box ::MetadataLoader));
390+
let cstore = Rc::new(CStore::new(DefaultTransCrate::metadata_loader()));
301391

302392
let loader = file_loader.unwrap_or(box RealFileLoader);
303393
let codemap = Rc::new(CodeMap::with_file_loader(loader, sopts.file_path_mapping()));

0 commit comments

Comments
 (0)