From b02e5cce169212bd4efe5857bc719d6ed47a53fc Mon Sep 17 00:00:00 2001 From: Denis Merigoux Date: Mon, 1 Oct 2018 10:32:09 +0200 Subject: Moved Backend interface into rustc_codegen_utils --- src/librustc_codegen_utils/common.rs | 22 ++++++ src/librustc_codegen_utils/interfaces/backend.rs | 80 +++++++++++++++++++++ src/librustc_codegen_utils/interfaces/mod.rs | 18 +++++ src/librustc_codegen_utils/lib.rs | 88 +++++++++++++++++++----- 4 files changed, 192 insertions(+), 16 deletions(-) create mode 100644 src/librustc_codegen_utils/interfaces/backend.rs create mode 100644 src/librustc_codegen_utils/interfaces/mod.rs (limited to 'src/librustc_codegen_utils') diff --git a/src/librustc_codegen_utils/common.rs b/src/librustc_codegen_utils/common.rs index c274fa4345a..3f4389913ae 100644 --- a/src/librustc_codegen_utils/common.rs +++ b/src/librustc_codegen_utils/common.rs @@ -113,3 +113,25 @@ pub enum TypeKind { X86_MMX, Token, } + +// FIXME(mw): Anything that is produced via DepGraph::with_task() must implement +// the HashStable trait. Normally DepGraph::with_task() calls are +// hidden behind queries, but CGU creation is a special case in two +// ways: (1) it's not a query and (2) CGU are output nodes, so their +// Fingerprints are not actually needed. It remains to be clarified +// how exactly this case will be handled in the red/green system but +// for now we content ourselves with providing a no-op HashStable +// implementation for CGUs. +mod temp_stable_hash_impls { + use rustc_data_structures::stable_hasher::{StableHasherResult, StableHasher, + HashStable}; + use ModuleCodegen; + + impl HashStable for ModuleCodegen { + fn hash_stable(&self, + _: &mut HCX, + _: &mut StableHasher) { + // do nothing + } + } +} diff --git a/src/librustc_codegen_utils/interfaces/backend.rs b/src/librustc_codegen_utils/interfaces/backend.rs new file mode 100644 index 00000000000..3cdb1c6a0dd --- /dev/null +++ b/src/librustc_codegen_utils/interfaces/backend.rs @@ -0,0 +1,80 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use rustc::ty::layout::{HasTyCtxt, LayoutOf, TyLayout}; +use rustc::ty::Ty; + +use super::CodegenObject; +use rustc::middle::allocator::AllocatorKind; +use rustc::middle::cstore::EncodedMetadata; +use rustc::mir::mono::Stats; +use rustc::session::Session; +use rustc::ty::TyCtxt; +use rustc::util::time_graph::TimeGraph; +use std::any::Any; +use std::sync::mpsc::Receiver; +use syntax_pos::symbol::InternedString; +use ModuleCodegen; + +pub trait BackendTypes { + type Value: CodegenObject; + type BasicBlock: Copy; + type Type: CodegenObject; + type Context; + type Funclet; + + type DIScope: Copy; +} + +pub trait Backend<'tcx>: + BackendTypes + HasTyCtxt<'tcx> + LayoutOf, TyLayout = TyLayout<'tcx>> +{ +} + +impl<'tcx, T> Backend<'tcx> for T where + Self: BackendTypes + HasTyCtxt<'tcx> + LayoutOf, TyLayout = TyLayout<'tcx>> +{} + +pub trait BackendMethods { + type Module; + type OngoingCodegen; + + fn new_metadata(&self, sess: &Session, mod_name: &str) -> Self::Module; + fn write_metadata<'b, 'gcx>( + &self, + tcx: TyCtxt<'b, 'gcx, 'gcx>, + metadata: &Self::Module, + ) -> EncodedMetadata; + fn codegen_allocator(&self, tcx: TyCtxt, mods: &Self::Module, kind: AllocatorKind); + + fn start_async_codegen( + &self, + tcx: TyCtxt, + time_graph: Option, + metadata: EncodedMetadata, + coordinator_receive: Receiver>, + total_cgus: usize, + ) -> Self::OngoingCodegen; + fn submit_pre_codegened_module_to_llvm( + &self, + codegen: &Self::OngoingCodegen, + tcx: TyCtxt, + module: ModuleCodegen, + ); + fn codegen_aborted(codegen: Self::OngoingCodegen); + fn codegen_finished(&self, codegen: &Self::OngoingCodegen, tcx: TyCtxt); + fn check_for_errors(&self, codegen: &Self::OngoingCodegen, sess: &Session); + fn wait_for_signal_to_codegen_item(&self, codegen: &Self::OngoingCodegen); + fn compile_codegen_unit<'a, 'tcx: 'a>( + &self, + tcx: TyCtxt<'a, 'tcx, 'tcx>, + cgu_name: InternedString, + ) -> Stats; +} diff --git a/src/librustc_codegen_utils/interfaces/mod.rs b/src/librustc_codegen_utils/interfaces/mod.rs new file mode 100644 index 00000000000..f958dbabe68 --- /dev/null +++ b/src/librustc_codegen_utils/interfaces/mod.rs @@ -0,0 +1,18 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +mod backend; + +pub use self::backend::{Backend, BackendMethods, BackendTypes}; + +use std::fmt; + +pub trait CodegenObject: Copy + PartialEq + fmt::Debug {} +impl CodegenObject for T {} diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index 2141a763d16..4fb182e4f05 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -21,6 +21,7 @@ #![feature(custom_attribute)] #![feature(nll)] #![allow(unused_attributes)] +#![allow(dead_code)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] @@ -46,8 +47,11 @@ use std::path::PathBuf; use rustc::session::Session; use rustc::ty::TyCtxt; +use rustc::dep_graph::WorkProduct; +use rustc::session::config::{OutputFilenames, OutputType}; pub mod command; +pub mod interfaces; pub mod link; pub mod linker; pub mod codegen_backend; @@ -56,27 +60,53 @@ pub mod symbol_names; pub mod symbol_names_test; pub mod common; -/// check for the #[rustc_error] annotation, which forces an -/// error in codegen. This is used to write compile-fail tests -/// that actually test that compilation succeeds without -/// reporting an error. -pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { - if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() { - let main_def_id = tcx.hir.local_def_id(id); +pub struct ModuleCodegen { + /// The name of the module. When the crate may be saved between + /// compilations, incremental compilation requires that name be + /// unique amongst **all** crates. Therefore, it should contain + /// something unique to this crate (e.g., a module path) as well + /// as the crate name and disambiguator. + /// We currently generate these names via CodegenUnit::build_cgu_name(). + pub name: String, + pub module_llvm: M, + pub kind: ModuleKind, +} - if tcx.has_attr(main_def_id, "rustc_error") { - tcx.sess.span_fatal(span, "compilation successful"); +pub const RLIB_BYTECODE_EXTENSION: &str = "bc.z"; + +impl ModuleCodegen { + pub fn into_compiled_module(self, + emit_obj: bool, + emit_bc: bool, + emit_bc_compressed: bool, + outputs: &OutputFilenames) -> CompiledModule { + let object = if emit_obj { + Some(outputs.temp_path(OutputType::Object, Some(&self.name))) + } else { + None + }; + let bytecode = if emit_bc { + Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name))) + } else { + None + }; + let bytecode_compressed = if emit_bc_compressed { + Some(outputs.temp_path(OutputType::Bitcode, Some(&self.name)) + .with_extension(RLIB_BYTECODE_EXTENSION)) + } else { + None + }; + + CompiledModule { + name: self.name.clone(), + kind: self.kind, + object, + bytecode, + bytecode_compressed, } } } -#[derive(Copy, Clone, Debug, PartialEq)] -pub enum ModuleKind { - Regular, - Metadata, - Allocator, -} - #[derive(Debug)] pub struct CompiledModule { pub name: String, @@ -86,6 +116,32 @@ pub struct CompiledModule { pub bytecode_compressed: Option, } +pub struct CachedModuleCodegen { + pub name: String, + pub source: WorkProduct, +} + +#[derive(Copy, Clone, Debug, PartialEq)] +pub enum ModuleKind { + Regular, + Metadata, + Allocator, +} + +/// check for the #[rustc_error] annotation, which forces an +/// error in codegen. This is used to write compile-fail tests +/// that actually test that compilation succeeds without +/// reporting an error. +pub fn check_for_rustc_errors_attr(tcx: TyCtxt) { + if let Some((id, span, _)) = *tcx.sess.entry_fn.borrow() { + let main_def_id = tcx.hir.local_def_id(id); + + if tcx.has_attr(main_def_id, "rustc_error") { + tcx.sess.span_fatal(span, "compilation successful"); + } + } +} + pub fn find_library(name: &str, search_paths: &[PathBuf], sess: &Session) -> PathBuf { // On Windows, static libraries sometimes show up as libfoo.a and other -- cgit 1.4.1-3-g733a5