[llvm] [NFC][ADT] add NumDigitsBase10 to MathExtra and update some current users (PR #165479)

via llvm-commits llvm-commits at lists.llvm.org
Tue Oct 28 14:06:56 PDT 2025


https://github.com/Ralender created https://github.com/llvm/llvm-project/pull/165479

None

>From ea6babde14c703843b7a19ca1e8af75c9f623c89 Mon Sep 17 00:00:00 2001
From: tyker <tyker1 at outlook.com>
Date: Thu, 19 Jun 2025 23:01:33 +0200
Subject: [PATCH] [NFC][ADT] implement NumDigitsBase10 in MathExtras.h and
 update some users of log10

---
 .../llvm/DebugInfo/PDB/Native/FormatUtil.h    | 43 -------------------
 .../llvm/DebugInfo/PDB/Native/InputFile.h     |  9 ++--
 llvm/include/llvm/Support/MathExtras.h        |  3 ++
 llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp    |  2 +-
 llvm/lib/Support/MathExtras.cpp               | 35 +++++++++++++++
 llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp  |  2 +-
 llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp   | 21 ++++-----
 llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp |  6 +--
 .../llvm-remarkutil/RemarkInstructionMix.cpp  |  2 +-
 llvm/unittests/Support/MathExtrasTest.cpp     | 15 +++++++
 llvm/utils/FileCheck/FileCheck.cpp            |  2 +-
 11 files changed, 76 insertions(+), 64 deletions(-)

diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h b/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h
index 76a019ddf8f34..a76b5c0d44791 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/FormatUtil.h
@@ -62,49 +62,6 @@ LLVM_ABI std::string formatChunkKind(codeview::DebugSubsectionKind Kind,
 LLVM_ABI std::string formatSymbolKind(codeview::SymbolKind K);
 LLVM_ABI std::string formatTypeLeafKind(codeview::TypeLeafKind K);
 
-/// Returns the number of digits in the given integer.
-inline int NumDigits(uint64_t N) {
-  if (N < 10ULL)
-    return 1;
-  if (N < 100ULL)
-    return 2;
-  if (N < 1000ULL)
-    return 3;
-  if (N < 10000ULL)
-    return 4;
-  if (N < 100000ULL)
-    return 5;
-  if (N < 1000000ULL)
-    return 6;
-  if (N < 10000000ULL)
-    return 7;
-  if (N < 100000000ULL)
-    return 8;
-  if (N < 1000000000ULL)
-    return 9;
-  if (N < 10000000000ULL)
-    return 10;
-  if (N < 100000000000ULL)
-    return 11;
-  if (N < 1000000000000ULL)
-    return 12;
-  if (N < 10000000000000ULL)
-    return 13;
-  if (N < 100000000000000ULL)
-    return 14;
-  if (N < 1000000000000000ULL)
-    return 15;
-  if (N < 10000000000000000ULL)
-    return 16;
-  if (N < 100000000000000000ULL)
-    return 17;
-  if (N < 1000000000000000000ULL)
-    return 18;
-  if (N < 10000000000000000000ULL)
-    return 19;
-  return 20;
-}
-
 namespace detail {
 template <typename T>
 struct EndianAdapter final
diff --git a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
index 71df1d59c2177..1f2c7e43002fa 100644
--- a/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
+++ b/llvm/include/llvm/DebugInfo/PDB/Native/InputFile.h
@@ -183,7 +183,8 @@ Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
   if (Filters.DumpModi) {
     uint32_t Modi = *Filters.DumpModi;
     SymbolGroup SG(&Input, Modi);
-    return iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(Modi)),
+    return iterateOneModule(Input,
+                            withLabelWidth(HeaderScope, NumDigitsBase10(Modi)),
                             SG, Modi, Callback);
   }
 
@@ -191,9 +192,9 @@ Error iterateSymbolGroups(InputFile &Input, const PrintScope &HeaderScope,
 
   for (const auto &SG : Input.symbol_groups()) {
     if (shouldDumpSymbolGroup(I, SG, Filters))
-      if (auto Err =
-              iterateOneModule(Input, withLabelWidth(HeaderScope, NumDigits(I)),
-                               SG, I, Callback))
+      if (auto Err = iterateOneModule(
+              Input, withLabelWidth(HeaderScope, NumDigitsBase10(I)), SG, I,
+              Callback))
         return Err;
 
     ++I;
diff --git a/llvm/include/llvm/Support/MathExtras.h b/llvm/include/llvm/Support/MathExtras.h
index 9bbb8a2a30541..2288c74494c32 100644
--- a/llvm/include/llvm/Support/MathExtras.h
+++ b/llvm/include/llvm/Support/MathExtras.h
@@ -786,6 +786,9 @@ using stack_float_t = volatile float;
 using stack_float_t = float;
 #endif
 
+/// Returns the number of digits in the given integer.
+int NumDigitsBase10(uint64_t X);
+
 } // namespace llvm
 
 #endif
diff --git a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
index 989fde9749b18..957c0c4c8f9a9 100644
--- a/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
+++ b/llvm/lib/DebugInfo/Symbolize/DIPrinter.cpp
@@ -84,7 +84,7 @@ class SourceCode {
   void format(raw_ostream &OS) {
     if (!PrunedSource)
       return;
-    size_t MaxLineNumberWidth = std::ceil(std::log10(LastLine));
+    size_t MaxLineNumberWidth = NumDigitsBase10(LastLine);
     int64_t L = FirstLine;
     for (size_t Pos = 0; Pos < PrunedSource->size(); ++L) {
       size_t PosEnd = PrunedSource->find('\n', Pos);
diff --git a/llvm/lib/Support/MathExtras.cpp b/llvm/lib/Support/MathExtras.cpp
index ad44b1a21676c..4424cdd935fef 100644
--- a/llvm/lib/Support/MathExtras.cpp
+++ b/llvm/lib/Support/MathExtras.cpp
@@ -28,4 +28,39 @@ namespace llvm {
   const float huge_valf = HUGE_VALF;
 #endif
 
+  /// Returns the number of digits in the given integer.
+  int NumDigitsBase10(uint64_t X) {
+    static constexpr struct ConstexprData {
+      uint8_t AtLeast[65] = {};
+      uint64_t Boundaries[20] = {};
+      static constexpr int NumDigitsConstexpr(uint64_t N) {
+        int res = 1;
+        while (N >= 10) {
+          res++;
+          N /= 10;
+        }
+        return res;
+      }
+      constexpr ConstexprData() {
+        uint64_t Val = ~0ull;
+        for (uint64_t i = 0; i <= 64; i++) {
+          uint64_t Digits = NumDigitsConstexpr(Val) - 1;
+          AtLeast[i] = Digits;
+          Val >>= 1;
+        }
+        // Special case because X=0 should return 1 and not 0
+        Boundaries[0] = 0;
+        Val = 10;
+        for (uint64_t i = 1; i < 20; i++) {
+          Boundaries[i] = Val;
+          Val *= 10;
+        }
+      }
+    } Data;
+
+    uint64_t Base2 = X ? countl_zero(X) : 64;
+    uint64_t Digits = Data.AtLeast[Base2];
+    return Digits + (X >= Data.Boundaries[Digits]);
+  }
+
 } // namespace llvm
diff --git a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp
index 4c851e14a12dd..3adc6593ac884 100644
--- a/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/BytesOutputStyle.cpp
@@ -370,7 +370,7 @@ static void iterateModules(PDBFile &File, LinePrinter &P, uint32_t IndentLevel,
                      Callback);
   } else {
     uint32_t Count = Modules.getModuleCount();
-    uint32_t Digits = NumDigits(Count);
+    uint32_t Digits = NumDigitsBase10(Count);
     for (uint32_t I = 0; I < Count; ++I) {
       iterateOneModule(File, P, Modules, I, Digits, IndentLevel, Callback);
     }
diff --git a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
index b2362ecb75703..5ddc0db8a34c6 100644
--- a/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
+++ b/llvm/tools/llvm-pdbutil/DumpOutputStyle.cpp
@@ -363,16 +363,16 @@ Error DumpOutputStyle::dumpStreamSummary() {
   for (uint32_t StreamIdx = 0; StreamIdx < StreamCount; ++StreamIdx) {
     P.formatLine(
         "Stream {0} ({1} bytes): [{2}]",
-        fmt_align(StreamIdx, AlignStyle::Right, NumDigits(StreamCount)),
+        fmt_align(StreamIdx, AlignStyle::Right, NumDigitsBase10(StreamCount)),
         fmt_align(getPdb().getStreamByteSize(StreamIdx), AlignStyle::Right,
-                  NumDigits(MaxStreamSize)),
+                  NumDigitsBase10(MaxStreamSize)),
         StreamPurposes[StreamIdx].getLongName());
 
     if (opts::dump::DumpStreamBlocks) {
       auto Blocks = getPdb().getStreamBlockList(StreamIdx);
       std::vector<uint32_t> BV(Blocks.begin(), Blocks.end());
       P.formatLine("       {0}  Blocks: [{1}]",
-                   fmt_repeat(' ', NumDigits(StreamCount)),
+                   fmt_repeat(' ', NumDigitsBase10(StreamCount)),
                    make_range(BV.begin(), BV.end()));
     }
   }
@@ -572,7 +572,7 @@ Error DumpOutputStyle::dumpSymbolStats() {
             if (StreamIdx == kInvalidStreamIndex) {
               P.formatLine(
                   "Mod {0} (debug info not present): [{1}]",
-                  fmt_align(Modi, AlignStyle::Right, NumDigits(ModCount)),
+                  fmt_align(Modi, AlignStyle::Right, NumDigitsBase10(ModCount)),
                   Desc.getModuleName());
               return Error::success();
             }
@@ -749,11 +749,11 @@ Error DumpOutputStyle::dumpUdtStats() {
   // separators.
   StringRef CountHeader("Count");
   StringRef SizeHeader("Size");
-  size_t CD = NumDigits(UdtStats.Totals.Count);
+  size_t CD = NumDigitsBase10(UdtStats.Totals.Count);
   CD += (CD - 1) / 3;
   CD = std::max(CD, CountHeader.size());
 
-  size_t SD = NumDigits(UdtStats.Totals.Size);
+  size_t SD = NumDigitsBase10(UdtStats.Totals.Size);
   SD += (SD - 1) / 3;
   SD = std::max(SD, SizeHeader.size());
 
@@ -1071,7 +1071,7 @@ Error DumpOutputStyle::dumpStringTableFromPdb() {
       P.formatLine("Empty");
     else {
       auto MaxID = llvm::max_element(IS->name_ids());
-      uint32_t Digits = NumDigits(*MaxID);
+      uint32_t Digits = NumDigitsBase10(*MaxID);
 
       P.formatLine("{0} | {1}", fmt_align("ID", AlignStyle::Right, Digits),
                    "String");
@@ -1205,7 +1205,8 @@ dumpFullTypeStream(LinePrinter &Printer, LazyRandomTypeCollection &Types,
                    TpiStream *Stream, bool Bytes, bool Extras) {
 
   Printer.formatLine("Showing {0:N} records", NumTypeRecords);
-  uint32_t Width = NumDigits(TypeIndex::FirstNonSimpleIndex + NumTypeRecords);
+  uint32_t Width =
+      NumDigitsBase10(TypeIndex::FirstNonSimpleIndex + NumTypeRecords);
 
   MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types, RefTracker,
                            NumHashBuckets, HashValues, Stream);
@@ -1221,8 +1222,8 @@ static void dumpPartialTypeStream(LinePrinter &Printer,
                                   TypeReferenceTracker *RefTracker,
                                   TpiStream &Stream, ArrayRef<TypeIndex> TiList,
                                   bool Bytes, bool Extras, bool Deps) {
-  uint32_t Width =
-      NumDigits(TypeIndex::FirstNonSimpleIndex + Stream.getNumTypeRecords());
+  uint32_t Width = NumDigitsBase10(TypeIndex::FirstNonSimpleIndex +
+                                   Stream.getNumTypeRecords());
 
   MinimalTypeDumpVisitor V(Printer, Width + 2, Bytes, Extras, Types, RefTracker,
                            Stream.getNumHashBuckets(), Stream.getHashValues(),
diff --git a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
index db3a752d58165..5f0f95b3775e6 100644
--- a/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
+++ b/llvm/tools/llvm-pdbutil/MinimalTypeDumper.cpp
@@ -309,7 +309,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
     return Error::success();
 
   auto Max = llvm::max_element(Indices);
-  uint32_t W = NumDigits(Max->getIndex()) + 2;
+  uint32_t W = NumDigitsBase10(Max->getIndex()) + 2;
 
   for (auto I : Indices)
     P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
@@ -324,7 +324,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
     return Error::success();
 
   auto Max = llvm::max_element(Indices);
-  uint32_t W = NumDigits(Max->getIndex()) + 2;
+  uint32_t W = NumDigitsBase10(Max->getIndex()) + 2;
 
   for (auto I : Indices)
     P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
@@ -494,7 +494,7 @@ Error MinimalTypeDumpVisitor::visitKnownRecord(CVType &CVR,
     return Error::success();
 
   auto Max = llvm::max_element(Indices);
-  uint32_t W = NumDigits(Max->getIndex()) + 2;
+  uint32_t W = NumDigitsBase10(Max->getIndex()) + 2;
 
   for (auto I : Indices)
     P.formatLine("{0}: `{1}`", fmt_align(I, AlignStyle::Right, W),
diff --git a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
index 7c8ac474c0fdb..62310440ef4fb 100644
--- a/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
+++ b/llvm/tools/llvm-remarkutil/RemarkInstructionMix.cpp
@@ -111,7 +111,7 @@ static Error tryInstructionMix() {
         Mix.begin(), Mix.end(), 1, [](unsigned MaxValue, const MixEntry &Elt) {
           return std::max(MaxValue, Elt.second);
         });
-    unsigned ValueWidth = std::log10(MaxValue) + 1;
+    unsigned ValueWidth = NumDigitsBase10(MaxValue);
     FOS << "Instruction";
     FOS.PadToColumn(MaxMnemonic + 1) << "Count\n";
     FOS << "-----------";
diff --git a/llvm/unittests/Support/MathExtrasTest.cpp b/llvm/unittests/Support/MathExtrasTest.cpp
index 5cb85fc55da92..27e8b26e8801d 100644
--- a/llvm/unittests/Support/MathExtrasTest.cpp
+++ b/llvm/unittests/Support/MathExtrasTest.cpp
@@ -692,4 +692,19 @@ TYPED_TEST(OverflowTest, MulResultZero) {
   EXPECT_FALSE(MulOverflow<TypeParam>(0, -5, Result));
   EXPECT_EQ(Result, TypeParam(0));
 }
+
+TEST(MathExtras, NumDigitsBase10) {
+  EXPECT_EQ(NumDigitsBase10(0), 1);
+  EXPECT_EQ(NumDigitsBase10(1), 1);
+
+  uint64_t Val = 10;
+  for (int i = 2; i <= 20; i++) {
+    EXPECT_EQ(NumDigitsBase10(Val - 1), i - 1);
+    EXPECT_EQ(NumDigitsBase10(Val), i);
+    Val *= 10;
+  }
+
+  EXPECT_EQ(NumDigitsBase10(std::numeric_limits<uint64_t>::max()), 20);
+}
+
 } // namespace
diff --git a/llvm/utils/FileCheck/FileCheck.cpp b/llvm/utils/FileCheck/FileCheck.cpp
index 305c28b4c7257..1a31d25ab5669 100644
--- a/llvm/utils/FileCheck/FileCheck.cpp
+++ b/llvm/utils/FileCheck/FileCheck.cpp
@@ -595,7 +595,7 @@ static void DumpAnnotatedInput(raw_ostream &OS, const FileCheckRequest &Req,
   unsigned LineCount = InputFileText.count('\n');
   if (InputFileEnd[-1] != '\n')
     ++LineCount;
-  unsigned LineNoWidth = std::log10(LineCount) + 1;
+  unsigned LineNoWidth = NumDigitsBase10(LineCount);
   // +3 below adds spaces (1) to the left of the (right-aligned) line numbers
   // on input lines and (2) to the right of the (left-aligned) labels on
   // annotation lines so that input lines and annotation lines are more



More information about the llvm-commits mailing list