Skip to content

Commit df5a57c

Browse files
committed
Generalized base:codegen_crate
1 parent 4460972 commit df5a57c

File tree

6 files changed

+155
-57
lines changed

6 files changed

+155
-57
lines changed

src/librustc_codegen_llvm/back/lto.rs

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@ use back::write::{ModuleConfig, with_llvm_pmb, CodegenContext};
1414
use back::write::{self, DiagnosticHandlers, pre_lto_bitcode_filename};
1515
use errors::{FatalError, Handler};
1616
use llvm::archive_ro::ArchiveRO;
17-
use llvm::{True, False};
18-
use llvm;
17+
use llvm::{self, True, False};
1918
use memmap;
2019
use rustc::dep_graph::WorkProduct;
2120
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
@@ -49,7 +48,7 @@ pub fn crate_type_allows_lto(crate_type: config::CrateType) -> bool {
4948

5049
pub(crate) enum LtoModuleCodegen {
5150
Fat {
52-
module: Option<ModuleCodegen>,
51+
module: Option<ModuleCodegen<ModuleLlvm>>,
5352
_serialized_bitcode: Vec<SerializedModule>,
5453
},
5554

@@ -73,7 +72,7 @@ impl LtoModuleCodegen {
7372
pub(crate) unsafe fn optimize(&mut self,
7473
cgcx: &CodegenContext,
7574
timeline: &mut Timeline)
76-
-> Result<ModuleCodegen, FatalError>
75+
-> Result<ModuleCodegen<ModuleLlvm>, FatalError>
7776
{
7877
match *self {
7978
LtoModuleCodegen::Fat { ref mut module, .. } => {
@@ -108,7 +107,7 @@ impl LtoModuleCodegen {
108107
/// the need optimization and another for modules that can simply be copied over
109108
/// from the incr. comp. cache.
110109
pub(crate) fn run(cgcx: &CodegenContext,
111-
modules: Vec<ModuleCodegen>,
110+
modules: Vec<ModuleCodegen<ModuleLlvm>>,
112111
cached_modules: Vec<(SerializedModule, WorkProduct)>,
113112
timeline: &mut Timeline)
114113
-> Result<(Vec<LtoModuleCodegen>, Vec<WorkProduct>), FatalError>
@@ -232,7 +231,7 @@ pub(crate) fn run(cgcx: &CodegenContext,
232231

233232
fn fat_lto(cgcx: &CodegenContext,
234233
diag_handler: &Handler,
235-
mut modules: Vec<ModuleCodegen>,
234+
mut modules: Vec<ModuleCodegen<ModuleLlvm>>,
236235
mut serialized_modules: Vec<(SerializedModule, CString)>,
237236
symbol_white_list: &[*const libc::c_char],
238237
timeline: &mut Timeline)
@@ -388,7 +387,7 @@ impl Drop for Linker<'a> {
388387
/// they all go out of scope.
389388
fn thin_lto(cgcx: &CodegenContext,
390389
diag_handler: &Handler,
391-
modules: Vec<ModuleCodegen>,
390+
modules: Vec<ModuleCodegen<ModuleLlvm>>,
392391
serialized_modules: Vec<(SerializedModule, CString)>,
393392
cached_modules: Vec<(SerializedModule, WorkProduct)>,
394393
symbol_white_list: &[*const libc::c_char],
@@ -736,7 +735,7 @@ impl ThinModule {
736735
}
737736

738737
unsafe fn optimize(&mut self, cgcx: &CodegenContext, timeline: &mut Timeline)
739-
-> Result<ModuleCodegen, FatalError>
738+
-> Result<ModuleCodegen<ModuleLlvm>, FatalError>
740739
{
741740
let diag_handler = cgcx.create_diag_handler();
742741
let tm = (cgcx.tm_factory)().map_err(|e| {

src/librustc_codegen_llvm/back/write.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use rustc::util::nodemap::FxHashMap;
2929
use time_graph::{self, TimeGraph, Timeline};
3030
use llvm::{self, DiagnosticInfo, PassManager, SMDiagnostic};
3131
use llvm_util;
32-
use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, // ModuleLlvm,
32+
use {CodegenResults, ModuleCodegen, CompiledModule, ModuleKind, ModuleLlvm,
3333
CachedModuleCodegen};
3434
use CrateInfo;
3535
use rustc::hir::def_id::{CrateNum, LOCAL_CRATE};
@@ -404,7 +404,7 @@ impl CodegenContext {
404404
}
405405
}
406406

407-
pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen, name: &str) {
407+
pub(crate) fn save_temp_bitcode(&self, module: &ModuleCodegen<ModuleLlvm>, name: &str) {
408408
if !self.save_temps {
409409
return
410410
}
@@ -511,7 +511,7 @@ unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void
511511
// Unsafe due to LLVM calls.
512512
unsafe fn optimize(cgcx: &CodegenContext,
513513
diag_handler: &Handler,
514-
module: &ModuleCodegen,
514+
module: &ModuleCodegen<ModuleLlvm>,
515515
config: &ModuleConfig,
516516
timeline: &mut Timeline)
517517
-> Result<(), FatalError>
@@ -644,7 +644,7 @@ unsafe fn optimize(cgcx: &CodegenContext,
644644
}
645645

646646
fn generate_lto_work(cgcx: &CodegenContext,
647-
modules: Vec<ModuleCodegen>,
647+
modules: Vec<ModuleCodegen<ModuleLlvm>>,
648648
import_only_modules: Vec<(SerializedModule, WorkProduct)>)
649649
-> Vec<(WorkItem, u64)>
650650
{
@@ -673,7 +673,7 @@ fn generate_lto_work(cgcx: &CodegenContext,
673673

674674
unsafe fn codegen(cgcx: &CodegenContext,
675675
diag_handler: &Handler,
676-
module: ModuleCodegen,
676+
module: ModuleCodegen<ModuleLlvm>,
677677
config: &ModuleConfig,
678678
timeline: &mut Timeline)
679679
-> Result<CompiledModule, FatalError>
@@ -1288,7 +1288,7 @@ pub(crate) fn dump_incremental_data(_codegen_results: &CodegenResults) {
12881288

12891289
enum WorkItem {
12901290
/// Optimize a newly codegened, totally unoptimized module.
1291-
Optimize(ModuleCodegen),
1291+
Optimize(ModuleCodegen<ModuleLlvm>),
12921292
/// Copy the post-LTO artifacts from the incremental cache to the output
12931293
/// directory.
12941294
CopyPostLtoArtifacts(CachedModuleCodegen),
@@ -1316,7 +1316,7 @@ impl WorkItem {
13161316

13171317
enum WorkItemResult {
13181318
Compiled(CompiledModule),
1319-
NeedsLTO(ModuleCodegen),
1319+
NeedsLTO(ModuleCodegen<ModuleLlvm>),
13201320
}
13211321

13221322
fn execute_work_item(cgcx: &CodegenContext,
@@ -1340,7 +1340,7 @@ fn execute_work_item(cgcx: &CodegenContext,
13401340
}
13411341

13421342
fn execute_optimize_work_item(cgcx: &CodegenContext,
1343-
module: ModuleCodegen,
1343+
module: ModuleCodegen<ModuleLlvm>,
13441344
module_config: &ModuleConfig,
13451345
timeline: &mut Timeline)
13461346
-> Result<WorkItemResult, FatalError>
@@ -1491,7 +1491,7 @@ fn execute_lto_work_item(cgcx: &CodegenContext,
14911491
enum Message {
14921492
Token(io::Result<Acquired>),
14931493
NeedsLTO {
1494-
result: ModuleCodegen,
1494+
result: ModuleCodegen<ModuleLlvm>,
14951495
worker_id: usize,
14961496
},
14971497
Done {
@@ -2431,7 +2431,7 @@ impl OngoingCodegen {
24312431

24322432
pub(crate) fn submit_pre_codegened_module_to_llvm(&self,
24332433
tcx: TyCtxt,
2434-
module: ModuleCodegen) {
2434+
module: ModuleCodegen<ModuleLlvm>) {
24352435
self.wait_for_signal_to_codegen_item();
24362436
self.check_for_errors(tcx.sess);
24372437

@@ -2465,7 +2465,7 @@ impl OngoingCodegen {
24652465
}
24662466

24672467
pub(crate) fn submit_codegened_module_to_llvm(tcx: TyCtxt,
2468-
module: ModuleCodegen,
2468+
module: ModuleCodegen<ModuleLlvm>,
24692469
cost: u64) {
24702470
let llvm_work_item = WorkItem::Optimize(module);
24712471
drop(tcx.tx_to_llvm_workers.lock().send(Box::new(Message::CodegenDone {

src/librustc_codegen_llvm/base.rs

Lines changed: 31 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ use super::ModuleKind;
2929
use super::CachedModuleCodegen;
3030

3131
use abi;
32-
use back::write::{self, OngoingCodegen};
32+
use back::write;
3333
use llvm;
3434
use metadata;
3535
use rustc::dep_graph::cgu_reuse_tracker::CguReuse;
@@ -48,7 +48,6 @@ use rustc::util::profiling::ProfileCategory;
4848
use rustc::session::config::{self, DebugInfo, EntryFnType, Lto};
4949
use rustc::session::Session;
5050
use rustc_incremental;
51-
use allocator;
5251
use mir::place::PlaceRef;
5352
use builder::{Builder, MemFlags};
5453
use callee;
@@ -591,9 +590,10 @@ fn maybe_create_entry_wrapper<'a, 'll: 'a, 'tcx: 'll, Bx: BuilderMethods<'a, 'll
591590
}
592591
}
593592

594-
fn write_metadata<'a, 'gcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>,
595-
llvm_module: &ModuleLlvm)
596-
-> EncodedMetadata {
593+
pub(crate) fn write_metadata<'a, 'gcx>(
594+
tcx: TyCtxt<'a, 'gcx, 'gcx>,
595+
llvm_module: &ModuleLlvm
596+
) -> EncodedMetadata {
597597
use std::io::Write;
598598
use flate2::Compression;
599599
use flate2::write::DeflateEncoder;
@@ -720,21 +720,23 @@ fn determine_cgu_reuse<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
720720
}
721721
}
722722

723-
pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
724-
rx: mpsc::Receiver<Box<dyn Any + Send>>)
725-
-> OngoingCodegen
726-
{
723+
pub fn codegen_crate<'a, 'tcx, B : BackendMethods>(
724+
backend: B,
725+
tcx: TyCtxt<'a, 'tcx, 'tcx>,
726+
rx: mpsc::Receiver<Box<dyn Any + Send>>
727+
) -> B::OngoingCodegen {
728+
727729
check_for_rustc_errors_attr(tcx);
728730

729731
if let Some(true) = tcx.sess.opts.debugging_opts.thinlto {
730-
if unsafe { !llvm::LLVMRustThinLTOAvailable() } {
732+
if backend.thin_lto_available() {
731733
tcx.sess.fatal("this compiler's LLVM does not support ThinLTO");
732734
}
733735
}
734736

735737
if (tcx.sess.opts.debugging_opts.pgo_gen.is_some() ||
736738
!tcx.sess.opts.debugging_opts.pgo_use.is_empty()) &&
737-
unsafe { !llvm::LLVMRustPGOAvailable() }
739+
backend.pgo_available()
738740
{
739741
tcx.sess.fatal("this compiler's LLVM does not support PGO");
740742
}
@@ -748,9 +750,9 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
748750
&["crate"],
749751
Some("metadata")).as_str()
750752
.to_string();
751-
let metadata_llvm_module = ModuleLlvm::new(tcx.sess, &metadata_cgu_name);
753+
let metadata_llvm_module = backend.new_metadata(tcx.sess, &metadata_cgu_name);
752754
let metadata = time(tcx.sess, "write metadata", || {
753-
write_metadata(tcx, &metadata_llvm_module)
755+
backend.write_metadata(tcx, &metadata_llvm_module)
754756
});
755757
tcx.sess.profiler(|p| p.end_activity(ProfileCategory::Codegen));
756758

@@ -769,19 +771,19 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
769771
// Skip crate items and just output metadata in -Z no-codegen mode.
770772
if tcx.sess.opts.debugging_opts.no_codegen ||
771773
!tcx.sess.opts.output_types.should_codegen() {
772-
let ongoing_codegen = write::start_async_codegen(
774+
let ongoing_codegen = backend.start_async_codegen(
773775
tcx,
774776
time_graph.clone(),
775777
metadata,
776778
rx,
777779
1);
778780

779-
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_module);
780-
ongoing_codegen.codegen_finished(tcx);
781+
backend.submit_pre_codegened_module_to_llvm(&ongoing_codegen, tcx, metadata_module);
782+
backend.codegen_finished(&ongoing_codegen, tcx);
781783

782784
assert_and_save_dep_graph(tcx);
783785

784-
ongoing_codegen.check_for_errors(tcx.sess);
786+
backend.check_for_errors(&ongoing_codegen, tcx.sess);
785787

786788
return ongoing_codegen;
787789
}
@@ -802,7 +804,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
802804
}
803805
}
804806

805-
let ongoing_codegen = write::start_async_codegen(
807+
let ongoing_codegen = backend.start_async_codegen(
806808
tcx,
807809
time_graph.clone(),
808810
metadata,
@@ -830,11 +832,9 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
830832
&["crate"],
831833
Some("allocator")).as_str()
832834
.to_string();
833-
let modules = ModuleLlvm::new(tcx.sess, &llmod_id);
835+
let modules = backend.new_metadata(tcx.sess, &llmod_id);
834836
time(tcx.sess, "write allocator module", || {
835-
unsafe {
836-
allocator::codegen(tcx, &modules, kind)
837-
}
837+
backend.codegen_allocator(tcx, &modules, kind)
838838
});
839839

840840
Some(ModuleCodegen {
@@ -847,10 +847,10 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
847847
};
848848

849849
if let Some(allocator_module) = allocator_module {
850-
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, allocator_module);
850+
backend.submit_pre_codegened_module_to_llvm(&ongoing_codegen, tcx, allocator_module);
851851
}
852852

853-
ongoing_codegen.submit_pre_codegened_module_to_llvm(tcx, metadata_module);
853+
backend.submit_pre_codegened_module_to_llvm(&ongoing_codegen, tcx, metadata_module);
854854

855855
// We sort the codegen units by size. This way we can schedule work for LLVM
856856
// a bit more efficiently.
@@ -864,8 +864,8 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
864864
let mut all_stats = Stats::default();
865865

866866
for cgu in codegen_units.into_iter() {
867-
ongoing_codegen.wait_for_signal_to_codegen_item();
868-
ongoing_codegen.check_for_errors(tcx.sess);
867+
backend.wait_for_signal_to_codegen_item(&ongoing_codegen);
868+
backend.check_for_errors(&ongoing_codegen, tcx.sess);
869869

870870
let cgu_reuse = determine_cgu_reuse(tcx, &cgu);
871871
tcx.sess.cgu_reuse_tracker.set_actual_reuse(&cgu.name().as_str(), cgu_reuse);
@@ -900,7 +900,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
900900
};
901901
}
902902

903-
ongoing_codegen.codegen_finished(tcx);
903+
backend.codegen_finished(&ongoing_codegen, tcx);
904904

905905
// Since the main thread is sometimes blocked during codegen, we keep track
906906
// -Ztime-passes output manually.
@@ -934,7 +934,7 @@ pub fn codegen_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
934934
}
935935
}
936936

937-
ongoing_codegen.check_for_errors(tcx.sess);
937+
backend.check_for_errors(&ongoing_codegen, tcx.sess);
938938

939939
assert_and_save_dep_graph(tcx);
940940
ongoing_codegen
@@ -1192,7 +1192,7 @@ fn compile_codegen_unit<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
11921192
fn module_codegen<'a, 'tcx>(
11931193
tcx: TyCtxt<'a, 'tcx, 'tcx>,
11941194
cgu_name: InternedString)
1195-
-> (Stats, ModuleCodegen)
1195+
-> (Stats, ModuleCodegen<ModuleLlvm>)
11961196
{
11971197
let cgu = tcx.codegen_unit(cgu_name);
11981198

@@ -1343,9 +1343,9 @@ pub fn visibility_to_llvm(linkage: Visibility) -> llvm::Visibility {
13431343
mod temp_stable_hash_impls {
13441344
use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher,
13451345
HashStable};
1346-
use ModuleCodegen;
1346+
use {ModuleCodegen, ModuleLlvm};
13471347

1348-
impl<HCX> HashStable<HCX> for ModuleCodegen {
1348+
impl<HCX> HashStable<HCX> for ModuleCodegen<ModuleLlvm> {
13491349
fn hash_stable<W: StableHasherResult>(&self,
13501350
_: &mut HCX,
13511351
_: &mut StableHasher<W>) {

src/librustc_codegen_llvm/interfaces/backend.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,51 @@
99
// except according to those terms.
1010

1111
use super::CodegenObject;
12+
use ModuleCodegen;
13+
use rustc::session::Session;
14+
use rustc::middle::cstore::EncodedMetadata;
15+
use rustc::middle::allocator::AllocatorKind;
16+
use rustc::ty::TyCtxt;
17+
use time_graph::TimeGraph;
18+
use std::sync::mpsc::Receiver;
19+
use std::any::Any;
1220

1321
pub trait Backend<'ll> {
1422
type Value : 'll + CodegenObject;
1523
type BasicBlock : Copy;
1624
type Type : CodegenObject;
1725
type Context;
1826
}
27+
28+
pub trait BackendMethods {
29+
type Metadata;
30+
type OngoingCodegen;
31+
32+
fn thin_lto_available(&self) -> bool;
33+
fn pgo_available(&self) -> bool;
34+
fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Metadata;
35+
fn write_metadata<'a, 'gcx>(
36+
&self,
37+
tcx: TyCtxt<'a, 'gcx, 'gcx>,
38+
metadata: &Self::Metadata
39+
) -> EncodedMetadata;
40+
fn codegen_allocator(&self, tcx: TyCtxt, mods: &Self::Metadata, kind: AllocatorKind);
41+
42+
fn start_async_codegen(
43+
&self,
44+
tcx: TyCtxt,
45+
time_graph: Option<TimeGraph>,
46+
metadata: EncodedMetadata,
47+
coordinator_receive: Receiver<Box<dyn Any + Send>>,
48+
total_cgus: usize
49+
) -> Self::OngoingCodegen;
50+
fn submit_pre_codegened_module_to_llvm(
51+
&self,
52+
codegen: &Self::OngoingCodegen,
53+
tcx: TyCtxt,
54+
module: ModuleCodegen<Self::Metadata>
55+
);
56+
fn codegen_finished(&self, codegen: &Self::OngoingCodegen, tcx: TyCtxt);
57+
fn check_for_errors(&self, codegen: &Self::OngoingCodegen, sess: &Session);
58+
fn wait_for_signal_to_codegen_item(&self, codegen: &Self::OngoingCodegen);
59+
}

0 commit comments

Comments
 (0)