forked from OSchip/llvm-project
[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
This commit is contained in:
parent
7be3285248
commit
407b1e65a4
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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, " ");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue