Implement support for predecessor iterators on basic blocks, use them to print
out predecessor information in the asmprinter.

PiperOrigin-RevId: 206343174
diff --git a/lib/IR/AsmPrinter.cpp b/lib/IR/AsmPrinter.cpp
index 26cb1fc..28149fc 100644
--- a/lib/IR/AsmPrinter.cpp
+++ b/lib/IR/AsmPrinter.cpp
@@ -716,7 +716,30 @@
     });
     os << ')';
   }
-  os << ":\n";
+  os << ':';
+
+  // Print out some context information about the predecessors of this block.
+  if (!block->getFunction()) {
+    os << "\t// block is not in a function!";
+  } else if (block->hasNoPredecessors()) {
+    // Don't print "no predecessors" for the entry block.
+    if (block != &block->getFunction()->front())
+      os << "\t// no predecessors";
+  } else if (auto *pred = block->getSinglePredecessor()) {
+    os << "\t// pred: bb" << getBBID(pred);
+  } else {
+    // We want to print the predecessors in increasing numeric order, not in
+    // whatever order the use-list is in, so gather and sort them.
+    SmallVector<unsigned, 4> predIDs;
+    for (auto *pred : block->getPredecessors())
+      predIDs.push_back(getBBID(pred));
+    llvm::array_pod_sort(predIDs.begin(), predIDs.end());
+
+    os << "\t// " << predIDs.size() << " preds: ";
+
+    interleaveComma(predIDs, [&](unsigned predID) { os << "bb" << predID; });
+  }
+  os << '\n';
 
   for (auto &inst : block->getOperations()) {
     os << "  ";
diff --git a/lib/IR/BasicBlock.cpp b/lib/IR/BasicBlock.cpp
index 7cb6440..11201d5 100644
--- a/lib/IR/BasicBlock.cpp
+++ b/lib/IR/BasicBlock.cpp
@@ -71,6 +71,26 @@
     inst->block = this;
 }
 
+/// Return true if this block has no predecessors.
+bool BasicBlock::hasNoPredecessors() const {
+  return pred_begin() == pred_end();
+}
+
+/// If this basic block has exactly one predecessor, return it.  Otherwise,
+/// return null.
+///
+/// Note that multiple edges from a single block (e.g. if you have a cond
+/// branch with the same block as the true/false destinations) is not
+/// considered to be a single predecessor.
+BasicBlock *BasicBlock::getSinglePredecessor() {
+  auto it = pred_begin();
+  if (it == pred_end())
+    return nullptr;
+  auto *firstPred = *it;
+  ++it;
+  return it == pred_end() ? firstPred : nullptr;
+}
+
 //===----------------------------------------------------------------------===//
 // ilist_traits for BasicBlock
 //===----------------------------------------------------------------------===//