1
Fork 0

rustc_metadata: Store a flag telling whether an item may have doc links in its attributes

This should be cheap on rustc side, but it's significant optimization for rustdoc that won't need to decode and process attributes unnecessarily
This commit is contained in:
Vadim Petrochenkov 2022-04-16 23:49:37 +03:00
parent f5ca02c334
commit e2d3a4f631
9 changed files with 48 additions and 20 deletions

View file

@ -1744,6 +1744,10 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
adjustments: generator_data.adjustments,
})
}
fn get_may_have_doc_links(self, index: DefIndex) -> bool {
self.root.tables.may_have_doc_links.get(self, index).is_some()
}
}
impl CrateMetadata {

View file

@ -531,6 +531,10 @@ impl CStore {
) -> impl Iterator<Item = DefId> + '_ {
self.get_crate_data(cnum).get_all_incoherent_impls()
}
pub fn may_have_doc_links_untracked(&self, def_id: DefId) -> bool {
self.get_crate_data(def_id.krate).get_may_have_doc_links(def_id.index)
}
}
impl CrateStore for CStore {

View file

@ -977,6 +977,14 @@ fn should_encode_generics(def_kind: DefKind) -> bool {
}
impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
fn encode_attrs(&mut self, def_id: DefId) {
let attrs = self.tcx.get_attrs(def_id);
record!(self.tables.attributes[def_id] <- attrs);
if attrs.iter().any(|attr| attr.may_have_doc_links()) {
self.tables.may_have_doc_links.set(def_id.index, ());
}
}
fn encode_def_ids(&mut self) {
if self.is_proc_macro {
return;
@ -989,7 +997,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let Some(def_kind) = def_kind else { continue };
self.tables.opt_def_kind.set(def_id.index, def_kind);
record!(self.tables.def_span[def_id] <- tcx.def_span(def_id));
record!(self.tables.attributes[def_id] <- tcx.get_attrs(def_id));
self.encode_attrs(def_id);
record!(self.tables.expn_that_defined[def_id] <- self.tcx.expn_that_defined(def_id));
if should_encode_visibility(def_kind) {
record!(self.tables.visibility[def_id] <- self.tcx.visibility(def_id));
@ -1651,7 +1659,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
self.tables.opt_def_kind.set(LOCAL_CRATE.as_def_id().index, DefKind::Mod);
record!(self.tables.def_span[LOCAL_CRATE.as_def_id()] <- tcx.def_span(LOCAL_CRATE.as_def_id()));
record!(self.tables.attributes[LOCAL_CRATE.as_def_id()] <- tcx.get_attrs(LOCAL_CRATE.as_def_id()));
self.encode_attrs(LOCAL_CRATE.as_def_id());
record!(self.tables.visibility[LOCAL_CRATE.as_def_id()] <- tcx.visibility(LOCAL_CRATE.as_def_id()));
if let Some(stability) = stability {
record!(self.tables.lookup_stability[LOCAL_CRATE.as_def_id()] <- stability);
@ -1692,7 +1700,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
let def_id = id.to_def_id();
self.tables.opt_def_kind.set(def_id.index, DefKind::Macro(macro_kind));
record!(self.tables.kind[def_id] <- EntryKind::ProcMacro(macro_kind));
record!(self.tables.attributes[def_id] <- attrs);
self.encode_attrs(def_id);
record!(self.tables.def_keys[def_id] <- def_key);
record!(self.tables.def_ident_span[def_id] <- span);
record!(self.tables.def_span[def_id] <- span);

View file

@ -360,6 +360,7 @@ define_tables! {
def_path_hashes: Table<DefIndex, DefPathHash>,
proc_macro_quoted_spans: Table<usize, Lazy<Span>>,
generator_diagnostic_data: Table<DefIndex, Lazy<GeneratorDiagnosticData<'tcx>>>,
may_have_doc_links: Table<DefIndex, ()>,
}
#[derive(Copy, Clone, MetadataEncodable, MetadataDecodable)]

View file

@ -186,6 +186,20 @@ impl FixedSizeEncoding for Option<RawDefId> {
}
}
impl FixedSizeEncoding for Option<()> {
type ByteArray = [u8; 1];
#[inline]
fn from_bytes(b: &[u8; 1]) -> Self {
(b[0] != 0).then(|| ())
}
#[inline]
fn write_to_bytes(self, b: &mut [u8; 1]) {
b[0] = self.is_some() as u8
}
}
// NOTE(eddyb) there could be an impl for `usize`, which would enable a more
// generic `Lazy<T>` impl, but in the general case we might not need / want to
// fit every `usize` in `u32`.