about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNicholas Nethercote <n.nethercote@gmail.com>2025-06-24 08:42:14 +1000
committerNicholas Nethercote <n.nethercote@gmail.com>2025-06-24 08:42:14 +1000
commitc3200c3bb54b94bafb0731adeffd2128f1d6cdd3 (patch)
tree34fd315206a051d71e8a718e43c6afee0a89cc20
parent111e9bc64bbdce14122e3676978f2ceefa5bff1a (diff)
downloadrust-c3200c3bb54b94bafb0731adeffd2128f1d6cdd3.tar.gz
rust-c3200c3bb54b94bafb0731adeffd2128f1d6cdd3.zip
Tweak `-Zmacro-stats` measurement.
It currently reports net size, i.e. size(output) - size(input). After
some use I think this is sub-optimal, and it's better to just report
size(output). Because for derive macros the input size is always 1, and
for attribute macros it's almost always 1.
-rw-r--r--compiler/rustc_expand/src/stats.rs28
-rw-r--r--compiler/rustc_interface/src/passes.rs4
-rw-r--r--src/doc/unstable-book/src/compiler-flags/macro-stats.md6
-rw-r--r--tests/ui/stats/macro-stats.stderr40
4 files changed, 35 insertions, 43 deletions
diff --git a/compiler/rustc_expand/src/stats.rs b/compiler/rustc_expand/src/stats.rs
index 6b2ad30dffd..b4c4eac028f 100644
--- a/compiler/rustc_expand/src/stats.rs
+++ b/compiler/rustc_expand/src/stats.rs
@@ -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 {
@@ -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.
@@ -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\
         "
         );
@@ -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;
 }
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 201b7e2b940..bba56281edd 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -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),
         );
     }
diff --git a/src/doc/unstable-book/src/compiler-flags/macro-stats.md b/src/doc/unstable-book/src/compiler-flags/macro-stats.md
index b2622cff057..f3fa69058a7 100644
--- a/src/doc/unstable-book/src/compiler-flags/macro-stats.md
+++ b/src/doc/unstable-book/src/compiler-flags/macro-stats.md
@@ -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
diff --git a/tests/ui/stats/macro-stats.stderr b/tests/ui/stats/macro-stats.stderr
index f87e34622b9..00c6b55c6a2 100644
--- a/tests/ui/stats/macro-stats.stderr
+++ b/tests/ui/stats/macro-stats.stderr
@@ -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 ===================================================================================