[llvm-branch-commits] [llvm] 407b1e6 - [StringExtras] Add a helper class for comma-separated lists

Kazu Hirata via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Sun Jan 10 14:36:58 PST 2021


Author: Kazu Hirata
Date: 2021-01-10T14:32:02-08:00
New Revision: 407b1e65a464081e28c325273b65e8eafdfad1d4

URL: https://github.com/llvm/llvm-project/commit/407b1e65a464081e28c325273b65e8eafdfad1d4
DIFF: https://github.com/llvm/llvm-project/commit/407b1e65a464081e28c325273b65e8eafdfad1d4.diff

LOG: [StringExtras] Add a helper class for comma-separated lists

This patch introduces a helper class SubsequentDelim to simplify loops
that generate a comma-separated lists.

For example, consider the following loop, taken from
llvm/lib/CodeGen/MachineBasicBlock.cpp:

    for (auto I = pred_begin(), E = pred_end(); I != E; ++I) {
      if (I != pred_begin())
        OS << ", ";
      OS << printMBBReference(**I);
    }

The new class allows us to rewrite the loop as:

    SubsequentDelim SD;
    for (auto I = pred_begin(), E = pred_end(); I != E; ++I)
      OS << SD << printMBBReference(**I);

where SD evaluates to the empty string for the first time and ", " for
subsequent iterations.

Unlike interleaveComma, defined in llvm/include/llvm/ADT/STLExtras.h,
SubsequentDelim can accommodate a wider variety of loops, including:

- those that conditionally skip certain items,
- those that need iterators to call getSuccProbability(I), and
- those that iterate over integer ranges.

As an example, this patch cleans up MachineBasicBlock::print.

Differential Revision: https://reviews.llvm.org/D94377

Added: 
    

Modified: 
    llvm/include/llvm/ADT/StringExtras.h
    llvm/lib/CodeGen/MachineBasicBlock.cpp
    llvm/unittests/ADT/StringExtrasTest.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/StringExtras.h b/llvm/include/llvm/ADT/StringExtras.h
index 77288f8514dc..1fea700efe0c 100644
--- a/llvm/include/llvm/ADT/StringExtras.h
+++ b/llvm/include/llvm/ADT/StringExtras.h
@@ -462,6 +462,30 @@ inline std::string join_items(Sep Separator, Args &&... Items) {
   return Result;
 }
 
+/// A helper class to return the specified delimiter string after the first
+/// invocation of operator StringRef().  Used to generate a comma-separated
+/// list from a loop like so:
+///
+/// \code
+///   SubsequentDelim SD;
+///   for (auto &I : C)
+///     OS << SD << I.getName();
+/// \end
+class SubsequentDelim {
+  bool First = true;
+  StringRef Delim;
+
+ public:
+  SubsequentDelim(StringRef Delim = ", ") : Delim(Delim) {}
+  operator StringRef() {
+    if (First) {
+      First = false;
+      return {};
+    }
+    return Delim;
+  }
+};
+
 } // end namespace llvm
 
 #endif // LLVM_ADT_STRINGEXTRAS_H

diff  --git a/llvm/lib/CodeGen/MachineBasicBlock.cpp b/llvm/lib/CodeGen/MachineBasicBlock.cpp
index 14a270f994b4..c7b404e075e1 100644
--- a/llvm/lib/CodeGen/MachineBasicBlock.cpp
+++ b/llvm/lib/CodeGen/MachineBasicBlock.cpp
@@ -353,11 +353,9 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
     if (Indexes) OS << '\t';
     // Don't indent(2), align with previous line attributes.
     OS << "; predecessors: ";
-    for (auto I = pred_begin(), E = pred_end(); I != E; ++I) {
-      if (I != pred_begin())
-        OS << ", ";
-      OS << printMBBReference(**I);
-    }
+    SubsequentDelim SD;
+    for (auto *Pred : predecessors())
+      OS << SD << printMBBReference(*Pred);
     OS << '\n';
     HasLineAttributes = true;
   }
@@ -366,10 +364,9 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
     if (Indexes) OS << '\t';
     // Print the successors
     OS.indent(2) << "successors: ";
+    SubsequentDelim SD;
     for (auto I = succ_begin(), E = succ_end(); I != E; ++I) {
-      if (I != succ_begin())
-        OS << ", ";
-      OS << printMBBReference(**I);
+      OS << SD << printMBBReference(**I);
       if (!Probs.empty())
         OS << '('
            << format("0x%08" PRIx32, getSuccProbability(I).getNumerator())
@@ -378,11 +375,10 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
     if (!Probs.empty() && IsStandalone) {
       // Print human readable probabilities as comments.
       OS << "; ";
+      SubsequentDelim SD;
       for (auto I = succ_begin(), E = succ_end(); I != E; ++I) {
         const BranchProbability &BP = getSuccProbability(I);
-        if (I != succ_begin())
-          OS << ", ";
-        OS << printMBBReference(**I) << '('
+        OS << SD << printMBBReference(**I) << '('
            << format("%.2f%%",
                      rint(((double)BP.getNumerator() / BP.getDenominator()) *
                           100.0 * 100.0) /
@@ -399,12 +395,9 @@ void MachineBasicBlock::print(raw_ostream &OS, ModuleSlotTracker &MST,
     if (Indexes) OS << '\t';
     OS.indent(2) << "liveins: ";
 
-    bool First = true;
+    SubsequentDelim SD;
     for (const auto &LI : liveins()) {
-      if (!First)
-        OS << ", ";
-      First = false;
-      OS << printReg(LI.PhysReg, TRI);
+      OS << SD << printReg(LI.PhysReg, TRI);
       if (!LI.LaneMask.all())
         OS << ":0x" << PrintLaneMask(LI.LaneMask);
     }

diff  --git a/llvm/unittests/ADT/StringExtrasTest.cpp b/llvm/unittests/ADT/StringExtrasTest.cpp
index b785bb51844b..97a5f946a216 100644
--- a/llvm/unittests/ADT/StringExtrasTest.cpp
+++ b/llvm/unittests/ADT/StringExtrasTest.cpp
@@ -215,3 +215,17 @@ TEST(StringExtras, IToStr) {
   EXPECT_EQ(std::to_string(MinInt64), itostr(MinInt64));
   EXPECT_EQ(std::to_string(MaxInt64), itostr(MaxInt64));
 }
+
+TEST(StringExtras, SubsequentDelim) {
+  SubsequentDelim SD;
+  StringRef S = SD;
+  EXPECT_EQ(S, "");
+  S = SD;
+  EXPECT_EQ(S, ", ");
+
+  SubsequentDelim SD2(" ");
+  S = SD2;
+  EXPECT_EQ(S, "");
+  S = SD2;
+  EXPECT_EQ(S, " ");
+}


        


More information about the llvm-branch-commits mailing list