Skip to content

Tweak -Zmacro-stats measurement. #142934

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

Merged
merged 1 commit into from
Jun 25, 2025
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
28 changes: 10 additions & 18 deletions compiler/rustc_expand/src/stats.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,11 @@ pub struct MacroStat {
/// Number of uses of the macro.
pub uses: usize,

/// Net increase in number of lines of code (when pretty-printed), i.e.
/// `lines(output) - lines(invocation)`. Can be negative because a macro
/// output may be smaller than the invocation.
pub lines: isize,

/// Net increase in number of lines of code (when pretty-printed), i.e.
/// `bytes(output) - bytes(invocation)`. Can be negative because a macro
/// output may be smaller than the invocation.
pub bytes: isize,
/// Number of lines of code (when pretty-printed).
pub lines: usize,

/// Number of bytes of code (when pretty-printed).
pub bytes: usize,
}

pub(crate) fn elems_to_string<T>(elems: &SmallVec<[T; 1]>, f: impl Fn(&T) -> String) -> String {
Expand Down Expand Up @@ -131,16 +127,12 @@ pub(crate) fn update_macro_stats(
input: &str,
fragment: &AstFragment,
) {
fn lines_and_bytes(s: &str) -> (usize, usize) {
(s.trim_end().split('\n').count(), s.len())
}

// Measure the size of the output by pretty-printing it and counting
// the lines and bytes.
let name = Symbol::intern(&pprust::path_to_string(path));
let output = fragment.to_string();
let (in_l, in_b) = lines_and_bytes(input);
let (out_l, out_b) = lines_and_bytes(&output);
let num_lines = output.trim_end().split('\n').count();
let num_bytes = output.len();

// This code is useful for debugging `-Zmacro-stats`. For every
// invocation it prints the full input and output.
Expand All @@ -157,7 +149,7 @@ pub(crate) fn update_macro_stats(
{name}: [{crate_name}] ({fragment_kind:?}) {span}\n\
-------------------------------\n\
{input}\n\
-- ({in_l} lines, {in_b} bytes) --> ({out_l} lines, {out_b} bytes) --\n\
-- {num_lines} lines, {num_bytes} bytes --\n\
{output}\n\
"
);
Expand All @@ -166,6 +158,6 @@ pub(crate) fn update_macro_stats(
// The recorded size is the difference between the input and the output.
let entry = ecx.macro_stats.entry((name, macro_kind)).or_insert(MacroStat::default());
entry.uses += 1;
entry.lines += out_l as isize - in_l as isize;
entry.bytes += out_b as isize - in_b as isize;
entry.lines += num_lines;
entry.bytes += num_bytes;
}
4 changes: 2 additions & 2 deletions compiler/rustc_interface/src/passes.rs
Original file line number Diff line number Diff line change
Expand Up @@ -354,9 +354,9 @@ fn print_macro_stats(ecx: &ExtCtxt<'_>) {
"{prefix} {:<name_w$}{:>uses_w$}{:>lines_w$}{:>avg_lines_w$}{:>bytes_w$}{:>avg_bytes_w$}",
name,
thousands::usize_with_underscores(uses),
thousands::isize_with_underscores(lines),
thousands::usize_with_underscores(lines),
thousands::f64p1_with_underscores(avg_lines),
thousands::isize_with_underscores(bytes),
thousands::usize_with_underscores(bytes),
thousands::f64p1_with_underscores(avg_bytes),
);
}
Expand Down
6 changes: 3 additions & 3 deletions src/doc/unstable-book/src/compiler-flags/macro-stats.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,12 @@ generated code is normally invisible to the programmer.

This flag helps identify such cases. When enabled, the compiler measures the
effect on code size of all used macros and prints a table summarizing that
effect. For each distinct macro, it counts how many times it is used, and the
net effect on code size (in terms of lines of code, and bytes of code). The
effect. For each distinct macro, it counts how many times it is used, and how
much code it produces when expanded (in lines of code, and bytes of code). The
code size evaluation uses the compiler's internal pretty-printing, and so will
be independent of the formatting in the original code.

Note that the net effect of a macro may be negative. E.g. the `cfg!` and
Note that the output size of a macro may be zero. E.g. the `cfg!` and
`#[test]` macros often strip out code.

If a macro is identified as causing a large increase in code size, it is worth
Expand Down
40 changes: 20 additions & 20 deletions tests/ui/stats/macro-stats.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,25 @@ macro-stats ====================================================================
macro-stats MACRO EXPANSION STATS: macro_stats
macro-stats Macro Name Uses Lines Avg Lines Bytes Avg Bytes
macro-stats -----------------------------------------------------------------------------------
macro-stats #[derive(Clone)] 8 56 7.0 1_660 207.5
macro-stats #[derive(PartialOrd)] 1 16 16.0 654 654.0
macro-stats #[derive(Hash)] 2 15 7.5 547 273.5
macro-stats #[derive(Ord)] 1 14 14.0 489 489.0
macro-stats q! 1 24 24.0 435 435.0
macro-stats #[derive(Default)] 2 14 7.0 367 183.5
macro-stats #[derive(Eq)] 1 10 10.0 312 312.0
macro-stats #[derive(Debug)] 1 7 7.0 261 261.0
macro-stats #[derive(PartialEq)] 1 8 8.0 247 247.0
macro-stats #[derive(Copy)] 1 1 1.0 46 46.0
macro-stats p! 1 2 2.0 28 28.0
macro-stats trait_impl_tys! 1 1 1.0 11 11.0
macro-stats foreign_item! 1 0 0.0 6 6.0
macro-stats impl_const! 1 0 0.0 4 4.0
macro-stats trait_tys! 1 1 1.0 3 3.0
macro-stats u32! 1 0 0.0 -3 -3.0
macro-stats none! 1 0 0.0 -3 -3.0
macro-stats n99! 2 0 0.0 -8 -4.0
macro-stats #[derive(Clone)] 8 64 8.0 1_788 223.5
macro-stats #[derive(PartialOrd)] 1 17 17.0 675 675.0
macro-stats #[derive(Hash)] 2 17 8.5 577 288.5
macro-stats q! 1 26 26.0 519 519.0
macro-stats #[derive(Ord)] 1 15 15.0 503 503.0
macro-stats #[derive(Default)] 2 16 8.0 403 201.5
macro-stats #[derive(Eq)] 1 11 11.0 325 325.0
macro-stats #[derive(Debug)] 1 8 8.0 277 277.0
macro-stats #[derive(PartialEq)] 1 9 9.0 267 267.0
macro-stats #[derive(Copy)] 1 2 2.0 61 61.0
macro-stats p! 1 3 3.0 32 32.0
macro-stats trait_impl_tys! 1 2 2.0 28 28.0
macro-stats foreign_item! 1 1 1.0 21 21.0
macro-stats this_is_a_really_really_long_macro_name!
macro-stats 1 0 0.0 -30 -30.0
macro-stats #[test] 1 -6 -6.0 -158 -158.0
macro-stats 1 1 1.0 18 18.0
macro-stats impl_const! 1 1 1.0 17 17.0
macro-stats trait_tys! 1 2 2.0 15 15.0
macro-stats n99! 2 2 1.0 4 2.0
macro-stats none! 1 1 1.0 4 4.0
macro-stats u32! 1 1 1.0 3 3.0
macro-stats #[test] 1 1 1.0 0 0.0
macro-stats ===================================================================================
Loading