Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[experiment] Add -Z no-link flag #67195

Merged
merged 1 commit into from
Jan 23, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3428,6 +3428,7 @@ dependencies = [
"rustc_session",
"rustc_span",
"rustc_target",
"serialize",
"smallvec 1.0.0",
"syntax",
]
Expand Down
5 changes: 3 additions & 2 deletions src/librustc/middle/cstore.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ pub use rustc_session::utils::NativeLibraryKind;

/// Where a crate came from on the local filesystem. One of these three options
/// must be non-None.
#[derive(PartialEq, Clone, Debug, HashStable)]
#[derive(PartialEq, Clone, Debug, HashStable, RustcEncodable, RustcDecodable)]
pub struct CrateSource {
pub dylib: Option<(PathBuf, PathKind)>,
pub rlib: Option<(PathBuf, PathKind)>,
Expand Down Expand Up @@ -75,7 +75,7 @@ impl DepKind {
}
}

#[derive(PartialEq, Clone, Debug)]
#[derive(PartialEq, Clone, Debug, RustcEncodable, RustcDecodable)]
pub enum LibSource {
Some(PathBuf),
MetadataOnly,
Expand Down Expand Up @@ -160,6 +160,7 @@ pub enum ExternCrateSource {
Path,
}

#[derive(RustcEncodable, RustcDecodable)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd prefer to save this in a binary file rather than escaped binary in a json string.

That said, I'm okay with doing this later, especially since this is an experimental feature.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Totally agreed, a binary file is definitely the proper way. I chose JSON in this PR purely because I don't want the file format details hold the feature, especially the proposed approach has not been reviewed yet.

pub struct EncodedMetadata {
pub raw_data: Vec<u8>,
}
Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/dependency_format.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub type DependencyList = Vec<Linkage>;
/// This is local to the tcx, and is generally relevant to one session.
pub type Dependencies = Vec<(config::CrateType, DependencyList)>;

#[derive(Copy, Clone, PartialEq, Debug, HashStable)]
#[derive(Copy, Clone, PartialEq, Debug, HashStable, RustcEncodable, RustcDecodable)]
pub enum Linkage {
NotLinked,
IncludedFromDylib,
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_llvm/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ rustc_incremental = { path = "../librustc_incremental" }
rustc_index = { path = "../librustc_index" }
rustc_llvm = { path = "../librustc_llvm" }
rustc_session = { path = "../librustc_session" }
rustc_serialize = { path = "../libserialize", package = "serialize" }
rustc_target = { path = "../librustc_target" }
smallvec = { version = "1.0", features = ["union", "may_dangle"] }
syntax = { path = "../libsyntax" }
Expand Down
14 changes: 14 additions & 0 deletions src/librustc_codegen_llvm/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ use rustc_codegen_ssa::CompiledModule;
use rustc_errors::{FatalError, Handler};
use std::any::Any;
use std::ffi::CStr;
use std::fs;
use std::sync::Arc;
use syntax::expand::allocator::AllocatorKind;

Expand All @@ -44,6 +45,7 @@ use rustc::ty::{self, TyCtxt};
use rustc::util::common::ErrorReported;
use rustc_codegen_ssa::ModuleCodegen;
use rustc_codegen_utils::codegen_backend::CodegenBackend;
use rustc_serialize::json;

mod back {
pub mod archive;
Expand Down Expand Up @@ -298,6 +300,18 @@ impl CodegenBackend for LlvmCodegenBackend {
return Ok(());
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that finalize_session_directory is never called in this case, which means that incremental compilation won't work.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should it have been called for Exe and Metadata output types, too?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current condition says return if neither exe, nor metadata is emitted.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just realized that codegen_backend.join_codegen_and_link needs to be called to actually emit all object files. Maybe split rename it to join_codegen and return CodegenResults from it, leaving the linker part to rustc_driver?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good suggestion. In fact, I think it is a good refactoring even without this -Z no-link change.

}

if sess.opts.debugging_opts.no_link {
// FIXME: use a binary format to encode the `.rlink` file
let rlink_data = json::encode(&codegen_results).map_err(|err| {
sess.fatal(&format!("failed to encode rlink: {}", err));
})?;
let rlink_file = outputs.with_extension("rlink");
fs::write(&rlink_file, rlink_data).map_err(|err| {
sess.fatal(&format!("failed to write file {}: {}", rlink_file.display(), err));
})?;
return Ok(());
}

// Run the linker on any artifacts that resulted from the LLVM run.
// This should produce either a finished executable or library.
sess.time("link_crate", || {
Expand Down
1 change: 1 addition & 0 deletions src/librustc_codegen_ssa/back/linker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ use rustc_target::spec::{LinkerFlavor, LldFlavor};

/// For all the linkers we support, and information they might
/// need out of the shared crate context before we get rid of it.
#[derive(RustcEncodable, RustcDecodable)]
pub struct LinkerInfo {
exports: FxHashMap<CrateType, Vec<String>>,
}
Expand Down
14 changes: 11 additions & 3 deletions src/librustc_codegen_ssa/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ impl<M> ModuleCodegen<M> {
}
}

#[derive(Debug)]
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct CompiledModule {
pub name: String,
pub kind: ModuleKind,
Expand All @@ -101,7 +101,7 @@ pub struct CachedModuleCodegen {
pub source: WorkProduct,
}

#[derive(Copy, Clone, Debug, PartialEq)]
#[derive(Copy, Clone, Debug, PartialEq, RustcEncodable, RustcDecodable)]
pub enum ModuleKind {
Regular,
Metadata,
Expand All @@ -117,7 +117,14 @@ bitflags::bitflags! {
}

/// Misc info we load from metadata to persist beyond the tcx.
#[derive(Debug)]
///
/// Note: though `CrateNum` is only meaningful within the same tcx, information within `CrateInfo`
0dvictor marked this conversation as resolved.
Show resolved Hide resolved
/// is self-contained. `CrateNum` can be viewed as a unique identifier within a `CrateInfo`, where
/// `used_crate_source` contains all `CrateSource` of the dependents, and maintains a mapping from
/// identifiers (`CrateNum`) to `CrateSource`. The other fields map `CrateNum` to the crate's own
/// additional properties, so that effectively we can retrieve each dependent crate's `CrateSource`
/// and the corresponding properties without referencing information outside of a `CrateInfo`.
#[derive(Debug, RustcEncodable, RustcDecodable)]
pub struct CrateInfo {
pub panic_runtime: Option<CrateNum>,
pub compiler_builtins: Option<CrateNum>,
Expand All @@ -135,6 +142,7 @@ pub struct CrateInfo {
pub dependency_formats: Lrc<Dependencies>,
}

#[derive(RustcEncodable, RustcDecodable)]
pub struct CodegenResults {
pub crate_name: Symbol,
pub modules: Vec<CompiledModule>,
Expand Down
34 changes: 29 additions & 5 deletions src/librustc_hir/def_id.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use rustc_data_structures::AtomicRef;
use rustc_index::vec::Idx;
use rustc_serialize::{Decoder, Encoder};
use std::fmt;
use std::u32;
use std::{u32, u64};

rustc_index::newtype_index! {
pub struct CrateId {
Expand Down Expand Up @@ -86,8 +87,18 @@ impl fmt::Display for CrateNum {
}
}

impl rustc_serialize::UseSpecializedEncodable for CrateNum {}
impl rustc_serialize::UseSpecializedDecodable for CrateNum {}
/// As a local identifier, a `CrateNum` is only meaningful within its context, e.g. within a tcx.
/// Therefore, make sure to include the context when encode a `CrateNum`.
impl rustc_serialize::UseSpecializedEncodable for CrateNum {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we decided to stick with this approach (#67516 (comment)), we may want to add a comment (here or on CrateNum) saying which conditions have to hold when using this.

fn default_encode<E: Encoder>(&self, e: &mut E) -> Result<(), E::Error> {
e.emit_u32(self.as_u32())
}
}
impl rustc_serialize::UseSpecializedDecodable for CrateNum {
fn default_decode<D: Decoder>(d: &mut D) -> Result<CrateNum, D::Error> {
Ok(CrateNum::from_u32(d.read_u32()?))
}
}

rustc_index::newtype_index! {
/// A DefIndex is an index into the hir-map for a crate, identifying a
Expand Down Expand Up @@ -135,8 +146,21 @@ impl DefId {
}
}

impl rustc_serialize::UseSpecializedEncodable for DefId {}
impl rustc_serialize::UseSpecializedDecodable for DefId {}
impl rustc_serialize::UseSpecializedEncodable for DefId {
fn default_encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
let krate = u64::from(self.krate.as_u32());
let index = u64::from(self.index.as_u32());
s.emit_u64((krate << 32) | index)
}
}
impl rustc_serialize::UseSpecializedDecodable for DefId {
fn default_decode<D: Decoder>(d: &mut D) -> Result<DefId, D::Error> {
let def_id = d.read_u64()?;
let krate = CrateNum::from_u32((def_id >> 32) as u32);
let index = DefIndex::from_u32((def_id & 0xffffffff) as u32);
Ok(DefId { krate, index })
}
}

pub fn default_def_id_debug(def_id: DefId, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("DefId").field("krate", &def_id.krate).field("index", &def_id.index).finish()
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,7 +619,7 @@ pub enum EntryFnType {

impl_stable_hash_via_hash!(EntryFnType);

#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug)]
#[derive(Copy, PartialEq, PartialOrd, Clone, Ord, Eq, Hash, Debug, RustcEncodable, RustcDecodable)]
pub enum CrateType {
Executable,
Dylib,
Expand Down
2 changes: 2 additions & 0 deletions src/librustc_session/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -950,4 +950,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
(such as entering an empty infinite loop) by inserting llvm.sideeffect"),
deduplicate_diagnostics: Option<bool> = (None, parse_opt_bool, [UNTRACKED],
"deduplicate identical diagnostics"),
no_link: bool = (false, parse_bool, [TRACKED],
"compile without linking"),
}
2 changes: 1 addition & 1 deletion src/librustc_session/search_paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub struct SearchPath {
pub files: Vec<PathBuf>,
}

#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq)]
#[derive(PartialEq, Clone, Copy, Debug, Hash, Eq, RustcEncodable, RustcDecodable)]
pub enum PathKind {
Native,
Crate,
Expand Down