Skip to content
Draft
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
26 changes: 7 additions & 19 deletions compiler/rustc_ast_lowering/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ use rustc_attr_parsing::{AttributeParser, OmitDoc, Recovery, ShouldEmit};
use rustc_data_structures::fingerprint::Fingerprint;
use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::sorted_map::SortedMap;
use rustc_data_structures::stable_hasher::{StableHash, StableHasher};
use rustc_data_structures::steal::Steal;
use rustc_data_structures::tagged_ptr::TaggedRef;
use rustc_errors::{DiagArgFromDisplay, DiagCtxtHandle};
Expand Down Expand Up @@ -506,25 +505,15 @@ fn index_crate<'a, 'b>(

/// Compute the hash for the HIR of the full crate.
/// This hash will then be part of the crate_hash which is stored in the metadata.
fn compute_hir_hash(
tcx: TyCtxt<'_>,
owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>,
) -> Fingerprint {
let mut hir_body_nodes: Vec<_> = owners
fn compute_hir_hash(owners: &IndexSlice<LocalDefId, hir::MaybeOwner<'_>>) -> Fingerprint {
owners
.iter_enumerated()
.filter_map(|(def_id, info)| {
.filter_map(|(_, info)| {
let info = info.as_owner()?;
let def_path_hash = tcx.hir_def_path_hash(def_id);
Some((def_path_hash, info))
Some(info.fingerprint())
})
.collect();
hir_body_nodes.sort_unstable_by_key(|bn| bn.0);

tcx.with_stable_hashing_context(|mut hcx| {
let mut stable_hasher = StableHasher::new();
hir_body_nodes.stable_hash(&mut hcx, &mut stable_hasher);
stable_hasher.finish()
})
.reduce(Fingerprint::combine_commutative)
.expect("HIR hash requested without any content")
}

pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
Expand Down Expand Up @@ -561,8 +550,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> mid_hir::Crate<'_> {
}

// Don't hash unless necessary, because it's expensive.
let opt_hir_hash =
if tcx.needs_hir_hash() { Some(compute_hir_hash(tcx, &owners)) } else { None };
let opt_hir_hash = if tcx.needs_hir_hash() { Some(compute_hir_hash(&owners)) } else { None };

let delayed_resolver = Steal::new((resolver, krate));
mid_hir::Crate::new(owners, delayed_ids, delayed_resolver, opt_hir_hash)
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_driver_impl/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -324,10 +324,6 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))

tcx.ensure_ok().analysis(());

if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
dump_feature_usage_metrics(tcx, metrics_dir);
}

if callbacks.after_analysis(compiler, tcx) == Compilation::Stop {
return early_exit();
}
Expand All @@ -340,6 +336,10 @@ pub fn run_compiler(at_args: &[String], callbacks: &mut (dyn Callbacks + Send))

let linker = Linker::codegen_and_build_linker(tcx, &*compiler.codegen_backend);

if let Some(metrics_dir) = &sess.opts.unstable_opts.metrics_dir {
dump_feature_usage_metrics(tcx, metrics_dir);
}

tcx.report_unused_features();

Some(linker)
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_hir/src/hir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1645,6 +1645,19 @@ impl<'tcx> OwnerInfo<'tcx> {
pub fn node(&self) -> OwnerNode<'tcx> {
self.nodes.node()
}

// A fingerprint that identifies the contents of the OwnerInfo.
// It only depends on `nodes` and `attrs` because `parenting` and `trait_map` are
// deterministically calculated from `nodes` and `attrs`.
#[inline]
pub fn fingerprint(&self) -> Fingerprint {
let body = self
.nodes
.opt_hash_including_bodies
.expect("HIR hash requested without needs_hir_hash");
let attrs = self.attrs.opt_hash.expect("HIR hash requested without needs_hir_hash");
body.combine(attrs)
}
}

#[derive(Copy, Clone, Debug, StableHash)]
Expand Down
9 changes: 7 additions & 2 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -948,8 +948,13 @@ pub fn create_and_enter_global_ctxt<T, F: for<'tcx> FnOnce(TyCtxt<'tcx>) -> T>(
let definitions = FreezeLock::new(Definitions::new(stable_crate_id));

let stable_crate_ids = FreezeLock::new(StableCrateIdMap::default());
let untracked =
Untracked { cstore, source_span: AppendOnlyIndexVec::new(), definitions, stable_crate_ids };
let untracked = Untracked {
cstore,
source_span: AppendOnlyIndexVec::new(),
definitions,
stable_crate_ids,
local_crate_hash: OnceLock::new(),
};

// We're constructing the HIR here; we don't care what we will
// read, since we haven't even constructed the *input* to
Expand Down
1 change: 1 addition & 0 deletions compiler/rustc_metadata/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// tidy-alphabetical-start
#![allow(internal_features)]
#![feature(core_intrinsics)]
#![feature(error_iter)]
#![feature(file_buffered)]
#![feature(gen_blocks)]
Expand Down
77 changes: 57 additions & 20 deletions compiler/rustc_metadata/src/rmeta/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ use std::borrow::Borrow;
use std::collections::hash_map::Entry;
use std::fs::File;
use std::io::{Read, Seek, Write};
use std::ops::Deref;
use std::path::{Path, PathBuf};
use std::sync::Arc;

use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
use rustc_data_structures::memmap::{Mmap, MmapMut};
use rustc_data_structures::owned_slice::slice_owned;
use rustc_data_structures::stable_hasher::{StableHash, StableHasher};
use rustc_data_structures::sync::{par_for_each_in, par_join};
use rustc_data_structures::temp_dir::MaybeTempDir;
use rustc_data_structures::thousands::usize_with_underscores;
Expand All @@ -25,7 +28,7 @@ use rustc_middle::ty::AssocContainer;
use rustc_middle::ty::codec::TyEncoder;
use rustc_middle::ty::fast_reject::{self, TreatParams};
use rustc_middle::{bug, span_bug};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder, opaque};
use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
use rustc_session::config::mitigation_coverage::DeniedPartialMitigation;
use rustc_session::config::{CrateType, OptLevel, TargetModifier};
use rustc_span::hygiene::HygieneEncodeContext;
Expand All @@ -40,7 +43,7 @@ use crate::errors::{FailCreateFileEncoder, FailWriteFile};
use crate::rmeta::*;

pub(super) struct EncodeContext<'a, 'tcx> {
opaque: opaque::FileEncoder,
opaque: opaque::FileEncoder<'a>,
tcx: TyCtxt<'tcx>,
feat: &'tcx rustc_feature::Features,
tables: TableBuilders,
Expand Down Expand Up @@ -718,13 +721,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let denied_partial_mitigations = stat!("denied-partial-mitigations", || self
.encode_enabled_denied_partial_mitigations());

let hash = Svh::new(self.opaque.hash());
tcx.untracked().local_crate_hash.set(hash).expect("local_crate_hash set twice");

let root = stat!("final", || {
let attrs = tcx.hir_krate_attrs();
self.lazy(CrateRoot {
header: CrateHeader {
name: tcx.crate_name(LOCAL_CRATE),
triple: tcx.sess.opts.target_triple.clone(),
hash: tcx.crate_hash(LOCAL_CRATE),
hash,
is_proc_macro_crate: proc_macro_data.is_some(),
is_stub: false,
},
Expand Down Expand Up @@ -2428,22 +2434,6 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
// there's no need to do dep-graph tracking for any of it.
tcx.dep_graph.assert_ignored();

// Generate the metadata stub manually, as that is a small file compared to full metadata.
if let Some(ref_path) = ref_path {
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub");

with_encode_metadata_header(tcx, ref_path, |ecx| {
let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader {
name: tcx.crate_name(LOCAL_CRATE),
triple: tcx.sess.opts.target_triple.clone(),
hash: tcx.crate_hash(LOCAL_CRATE),
is_proc_macro_crate: false,
is_stub: true,
});
header.position.get()
})
}

let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata");

let dep_node = tcx.metadata_dep_node();
Expand All @@ -2462,6 +2452,31 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
Ok(_) => {}
Err(err) => tcx.dcx().emit_fatal(FailCreateFileEncoder { err }),
};

// Read the SVH from the old metadata header.
let file = std::fs::File::open(&source_file).unwrap();
let mmap = unsafe { Mmap::map(file) }.unwrap();
let owned = slice_owned(mmap, Deref::deref);
let blob = MetadataBlob::new(owned);
let header = blob.expect("file already created").get_header();
tcx.untracked().local_crate_hash.set(header.hash).expect("local_crate_hash set twice");

// Generate the metadata stub manually, as that is a small file compared to full metadata.
if let Some(ref_path) = ref_path {
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub");

with_encode_metadata_header(tcx, ref_path, |ecx| {
let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader {
name: tcx.crate_name(LOCAL_CRATE),
triple: tcx.sess.opts.target_triple.clone(),
hash: tcx.crate_hash(LOCAL_CRATE),
is_proc_macro_crate: false,
is_stub: true,
});
header.position.get()
})
}

return;
};

Expand Down Expand Up @@ -2503,14 +2518,36 @@ pub fn encode_metadata(tcx: TyCtxt<'_>, path: &Path, ref_path: Option<&Path>) {
},
None,
);

// Generate the metadata stub manually, as that is a small file compared to full metadata.
if let Some(ref_path) = ref_path {
let _prof_timer = tcx.prof.verbose_generic_activity("generate_crate_metadata_stub");

with_encode_metadata_header(tcx, ref_path, |ecx| {
let header: LazyValue<CrateHeader> = ecx.lazy(CrateHeader {
name: tcx.crate_name(LOCAL_CRATE),
triple: tcx.sess.opts.target_triple.clone(),
hash: tcx.crate_hash(LOCAL_CRATE),
is_proc_macro_crate: false,
is_stub: true,
});
header.position.get()
})
}
}

fn with_encode_metadata_header(
tcx: TyCtxt<'_>,
path: &Path,
f: impl FnOnce(&mut EncodeContext<'_, '_>) -> usize,
) {
let mut encoder = opaque::FileEncoder::new(path)
let mut stable_hasher = StableHasher::new();
// Add dep_tracking_hash to ensure the SVH changes when any tracked flag changes.
tcx.with_stable_hashing_context(|mut hcx| {
tcx.sess.opts.dep_tracking_hash(true).stable_hash(&mut hcx, &mut stable_hasher);
});

let mut encoder = opaque::FileEncoder::new(path, &mut stable_hasher)
.unwrap_or_else(|err| tcx.dcx().emit_fatal(FailCreateFileEncoder { err }));
encoder.emit_raw_bytes(METADATA_HEADER);

Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_metadata/src/rmeta/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ use rustc_middle::mir::ConstValue;
use rustc_middle::ty::fast_reject::SimplifiedType;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::util::Providers;
use rustc_serialize::opaque::FileEncoder;
use rustc_session::config::mitigation_coverage::DeniedPartialMitigation;
use rustc_session::config::{SymbolManglingVersion, TargetModifier};
use rustc_session::cstore::{CrateDepKind, ForeignModule, LinkagePreference, NativeLib};
Expand All @@ -50,6 +49,7 @@ use crate::eii::EiiMapEncodedKeyValue;
mod decoder;
mod def_path_hash_map;
mod encoder;
mod opaque;
mod parameterized;
mod table;

Expand Down Expand Up @@ -364,7 +364,7 @@ macro_rules! define_tables {
}

impl TableBuilders {
fn encode(&self, buf: &mut FileEncoder) -> LazyTables {
fn encode(&self, buf: &mut opaque::FileEncoder<'_>) -> LazyTables {
LazyTables {
$($name1: self.$name1.encode(buf),)+
$($name2: self.$name2.encode(buf),)+
Expand Down
Loading
Loading