Skip to content

Commit edcd7fd

Browse files
committed
Move macro-stats code to a stats module.
1 parent a9b6bd7 commit edcd7fd

File tree

4 files changed

+197
-171
lines changed

4 files changed

+197
-171
lines changed

compiler/rustc_expand/src/base.rs

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,22 +1167,6 @@ pub struct ExpansionData {
11671167
pub is_trailing_mac: bool,
11681168
}
11691169

1170-
#[derive(Default)]
1171-
pub struct MacroStat {
1172-
/// Number of uses of the macro.
1173-
pub uses: usize,
1174-
1175-
/// Net increase in number of lines of code (when pretty-printed), i.e.
1176-
/// `lines(output) - lines(invocation)`. Can be negative because a macro
1177-
/// output may be smaller than the invocation.
1178-
pub lines: isize,
1179-
1180-
/// Net increase in number of lines of code (when pretty-printed), i.e.
1181-
/// `bytes(output) - bytes(invocation)`. Can be negative because a macro
1182-
/// output may be smaller than the invocation.
1183-
pub bytes: isize,
1184-
}
1185-
11861170
/// One of these is made during expansion and incrementally updated as we go;
11871171
/// when a macro expansion occurs, the resulting nodes have the `backtrace()
11881172
/// -> expn_data` of their expansion context stored into their span.
@@ -1207,7 +1191,7 @@ pub struct ExtCtxt<'a> {
12071191
/// not to expand it again.
12081192
pub(super) expanded_inert_attrs: MarkedAttrs,
12091193
/// `-Zmacro-stats` data.
1210-
pub macro_stats: FxHashMap<(Symbol, MacroKind), MacroStat>,
1194+
pub macro_stats: FxHashMap<(Symbol, MacroKind), crate::stats::MacroStat>, // njn: quals
12111195
}
12121196

12131197
impl<'a> ExtCtxt<'a> {

compiler/rustc_expand/src/expand.rs

Lines changed: 24 additions & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ use rustc_session::lint::BuiltinLintDiag;
2525
use rustc_session::lint::builtin::{UNUSED_ATTRIBUTES, UNUSED_DOC_COMMENTS};
2626
use rustc_session::parse::feature_err;
2727
use rustc_session::{Limit, Session};
28-
use rustc_span::hygiene::{MacroKind, SyntaxContext};
29-
use rustc_span::{ErrorGuaranteed, ExpnKind, FileName, Ident, LocalExpnId, Span, Symbol, kw, sym};
28+
use rustc_span::hygiene::SyntaxContext;
29+
use rustc_span::{ErrorGuaranteed, FileName, Ident, LocalExpnId, Span, sym};
3030
use smallvec::SmallVec;
3131

3232
use crate::base::*;
@@ -42,6 +42,7 @@ use crate::module::{
4242
DirOwnership, ParsedExternalMod, mod_dir_path, mod_file_path_from_attr, parse_external_mod,
4343
};
4444
use crate::placeholders::{PlaceholderExpander, placeholder};
45+
use crate::stats::*;
4546

4647
macro_rules! ast_fragments {
4748
(
@@ -160,7 +161,7 @@ macro_rules! ast_fragments {
160161
V::Result::output()
161162
}
162163

163-
fn to_string(&self) -> String {
164+
pub(crate) fn to_string(&self) -> String {
164165
match self {
165166
AstFragment::OptExpr(Some(expr)) => pprust::expr_to_string(expr),
166167
AstFragment::OptExpr(None) => unreachable!(),
@@ -185,21 +186,6 @@ macro_rules! ast_fragments {
185186
}
186187
}
187188

188-
fn elems_to_string<T>(elems: &SmallVec<[T; 1]>, f: impl Fn(&T) -> String) -> String {
189-
let mut s = String::new();
190-
for (i, elem) in elems.iter().enumerate() {
191-
if i > 0 {
192-
s.push('\n');
193-
}
194-
s.push_str(&f(elem));
195-
}
196-
s
197-
}
198-
199-
fn unreachable_to_string<T>(_: &T) -> String {
200-
unreachable!()
201-
}
202-
203189
ast_fragments! {
204190
Expr(P<ast::Expr>) {
205191
"expression";
@@ -330,7 +316,7 @@ impl AstFragmentKind {
330316
}
331317
}
332318

333-
fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(
319+
pub(crate) fn expect_from_annotatables<I: IntoIterator<Item = Annotatable>>(
334320
self,
335321
items: I,
336322
) -> AstFragment {
@@ -757,7 +743,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
757743
let fragment =
758744
self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span);
759745
if macro_stats {
760-
self.update_bang_macro_stats(fragment_kind, span, mac, &fragment);
746+
update_bang_macro_stats(
747+
self.cx,
748+
fragment_kind,
749+
span,
750+
mac,
751+
&fragment,
752+
);
761753
}
762754
fragment
763755
}
@@ -777,7 +769,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
777769
};
778770
if let Some(fragment) = fragment_kind.make_from(tok_result) {
779771
if macro_stats {
780-
self.update_bang_macro_stats(fragment_kind, span, mac, &fragment);
772+
update_bang_macro_stats(self.cx, fragment_kind, span, mac, &fragment);
781773
}
782774
fragment
783775
} else {
@@ -829,7 +821,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
829821
span,
830822
);
831823
if macro_stats {
832-
self.update_attr_macro_stats(
824+
update_attr_macro_stats(
825+
self.cx,
833826
fragment_kind,
834827
span,
835828
&attr_item.path,
@@ -867,7 +860,8 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
867860
} else {
868861
let fragment = fragment_kind.expect_from_annotatables(items);
869862
if macro_stats {
870-
self.update_attr_macro_stats(
863+
update_attr_macro_stats(
864+
self.cx,
871865
fragment_kind,
872866
span,
873867
&meta.path,
@@ -919,7 +913,13 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
919913
};
920914
let fragment = fragment_kind.expect_from_annotatables(items);
921915
if macro_stats {
922-
self.update_derive_macro_stats(fragment_kind, span, &meta.path, &fragment);
916+
update_derive_macro_stats(
917+
self.cx,
918+
fragment_kind,
919+
span,
920+
&meta.path,
921+
&fragment,
922+
);
923923
}
924924
fragment
925925
}
@@ -960,136 +960,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
960960
})
961961
}
962962

963-
fn update_bang_macro_stats(
964-
&mut self,
965-
fragment_kind: AstFragmentKind,
966-
span: Span,
967-
mac: P<ast::MacCall>,
968-
fragment: &AstFragment,
969-
) {
970-
// Does this path match any of the include macros, e.g. `include!`?
971-
// Ignore them. They would have large numbers but are entirely
972-
// unsurprising and uninteresting.
973-
let is_include_path = mac.path == sym::include
974-
|| mac.path == sym::include_bytes
975-
|| mac.path == sym::include_str
976-
|| mac.path == [sym::std, sym::include].as_slice() // std::include
977-
|| mac.path == [sym::std, sym::include_bytes].as_slice() // std::include_bytes
978-
|| mac.path == [sym::std, sym::include_str].as_slice(); // std::include_str
979-
if is_include_path {
980-
return;
981-
}
982-
983-
// The call itself (e.g. `println!("hi")`) is the input. Need to wrap
984-
// `mac` in something printable; `ast::Expr` is as good as anything
985-
// else.
986-
let expr = ast::Expr {
987-
id: ast::DUMMY_NODE_ID,
988-
kind: ExprKind::MacCall(mac),
989-
span: Default::default(),
990-
attrs: Default::default(),
991-
tokens: None,
992-
};
993-
let input = pprust::expr_to_string(&expr);
994-
995-
// Get `mac` back out of `expr`.
996-
let ast::Expr { kind: ExprKind::MacCall(mac), .. } = expr else { unreachable!() };
997-
998-
self.update_macro_stats(MacroKind::Bang, fragment_kind, span, &mac.path, &input, fragment);
999-
}
1000-
1001-
fn update_attr_macro_stats(
1002-
&mut self,
1003-
fragment_kind: AstFragmentKind,
1004-
span: Span,
1005-
path: &ast::Path,
1006-
attr: &ast::Attribute,
1007-
item: Annotatable,
1008-
fragment: &AstFragment,
1009-
) {
1010-
// Does this path match `#[derive(...)]` in any of its forms? If so,
1011-
// ignore it because the individual derives will go through the
1012-
// `Invocation::Derive` handling separately.
1013-
let is_derive_path = *path == sym::derive
1014-
// ::core::prelude::v1::derive
1015-
|| *path == [kw::PathRoot, sym::core, sym::prelude, sym::v1, sym::derive].as_slice();
1016-
if is_derive_path {
1017-
return;
1018-
}
1019-
1020-
// The attribute plus the item itself constitute the input, which we
1021-
// measure.
1022-
let input = format!(
1023-
"{}\n{}",
1024-
pprust::attribute_to_string(attr),
1025-
fragment_kind.expect_from_annotatables(iter::once(item)).to_string(),
1026-
);
1027-
self.update_macro_stats(MacroKind::Attr, fragment_kind, span, path, &input, fragment);
1028-
}
1029-
1030-
fn update_derive_macro_stats(
1031-
&mut self,
1032-
fragment_kind: AstFragmentKind,
1033-
span: Span,
1034-
path: &ast::Path,
1035-
fragment: &AstFragment,
1036-
) {
1037-
// Use something like `#[derive(Clone)]` for the measured input, even
1038-
// though it may have actually appeared in a multi-derive attribute
1039-
// like `#[derive(Clone, Copy, Debug)]`.
1040-
let input = format!("#[derive({})]", pprust::path_to_string(path));
1041-
self.update_macro_stats(MacroKind::Derive, fragment_kind, span, path, &input, fragment);
1042-
}
1043-
1044-
fn update_macro_stats(
1045-
&mut self,
1046-
macro_kind: MacroKind,
1047-
fragment_kind: AstFragmentKind,
1048-
span: Span,
1049-
path: &ast::Path,
1050-
input: &str,
1051-
fragment: &AstFragment,
1052-
) {
1053-
fn lines_and_bytes(s: &str) -> (usize, usize) {
1054-
(s.trim_end().split('\n').count(), s.len())
1055-
}
1056-
1057-
// Measure the size of the output by pretty-printing it and counting
1058-
// the lines and bytes.
1059-
let name = Symbol::intern(&pprust::path_to_string(path));
1060-
let output = fragment.to_string();
1061-
let (in_l, in_b) = lines_and_bytes(input);
1062-
let (out_l, out_b) = lines_and_bytes(&output);
1063-
1064-
// This code is useful for debugging `-Zmacro-stats`. For every
1065-
// invocation it prints the full input and output.
1066-
if false {
1067-
let name = ExpnKind::Macro(macro_kind, name).descr();
1068-
let crate_name = &self.cx.ecfg.crate_name;
1069-
let span = self
1070-
.cx
1071-
.sess
1072-
.source_map()
1073-
.span_to_string(span, rustc_span::FileNameDisplayPreference::Local);
1074-
eprint!(
1075-
"\
1076-
-------------------------------\n\
1077-
{name}: [{crate_name}] ({fragment_kind:?}) {span}\n\
1078-
-------------------------------\n\
1079-
{input}\n\
1080-
-- ({in_l} lines, {in_b} bytes) --> ({out_l} lines, {out_b} bytes) --\n\
1081-
{output}\n\
1082-
"
1083-
);
1084-
}
1085-
1086-
// The recorded size is the difference between the input and the output.
1087-
let entry = self.cx.macro_stats.entry((name, macro_kind)).or_insert(MacroStat::default());
1088-
entry.uses += 1;
1089-
entry.lines += out_l as isize - in_l as isize;
1090-
entry.bytes += out_b as isize - in_b as isize;
1091-
}
1092-
1093963
#[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable
1094964
fn gate_proc_macro_attr_item(&self, span: Span, item: &Annotatable) {
1095965
let kind = match item {

compiler/rustc_expand/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mod errors;
2020
mod mbe;
2121
mod placeholders;
2222
mod proc_macro_server;
23+
mod stats;
2324

2425
pub use mbe::macro_rules::compile_declarative_macro;
2526
pub mod base;

0 commit comments

Comments
 (0)