Implement the groundwork for predecessor/successor iterators on basic blocks.

Give BasicBlock a use/def list, making references to them in TerminatorInst's
into a type that maintains the list.

PiperOrigin-RevId: 206166388
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index a1cdcb3..7afaf68 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -22,7 +22,7 @@
 /// Replace all uses of 'this' value with the new value, updating anything in
 /// the IR that uses 'this' to use the other value instead.  When this returns
 /// there are zero uses of 'this'.
-void SSAValue::replaceAllUsesWith(SSAValue *newValue) {
+void IRObjectWithUseList::replaceAllUsesWith(IRObjectWithUseList *newValue) {
   assert(this != newValue && "cannot RAUW a value with itself");
   while (!use_empty()) {
     use_begin()->set(newValue);
@@ -105,6 +105,10 @@
 void Instruction::dropAllReferences() {
   for (auto &op : getInstOperands())
     op.drop();
+
+  if (auto *term = dyn_cast<TerminatorInst>(this))
+    for (auto &dest : term->getDestinations())
+      dest.drop();
 }
 
 //===----------------------------------------------------------------------===//
@@ -209,7 +213,7 @@
 }
 
 //===----------------------------------------------------------------------===//
-// Terminators
+// TerminatorInst
 //===----------------------------------------------------------------------===//
 
 /// Remove this terminator from its BasicBlock and delete it.
@@ -219,6 +223,25 @@
   destroy();
 }
 
+/// Return the list of destination entries that this terminator branches to.
+MutableArrayRef<BBDestination> TerminatorInst::getDestinations() {
+  switch (getKind()) {
+  case Kind::Operation:
+    assert(0 && "not a terminator");
+  case Kind::Branch:
+    return cast<BranchInst>(this)->getDestinations();
+  case Kind::CondBranch:
+    return cast<CondBranchInst>(this)->getDestinations();
+  case Kind::Return:
+    // Return has no basic block successors.
+    return {};
+  }
+}
+
+//===----------------------------------------------------------------------===//
+// ReturnInst
+//===----------------------------------------------------------------------===//
+
 /// Create a new OperationInst with the specific fields.
 ReturnInst *ReturnInst::create(ArrayRef<CFGValue *> operands) {
   auto byteSize = totalSizeToAlloc<InstOperand>(operands.size());
@@ -245,6 +268,15 @@
     operand.~InstOperand();
 }
 
+//===----------------------------------------------------------------------===//
+// BranchInst
+//===----------------------------------------------------------------------===//
+
+BranchInst::BranchInst(BasicBlock *dest)
+    : TerminatorInst(Kind::Branch), dest(this, dest) {}
+
+void BranchInst::setDest(BasicBlock *block) { dest.set(block); }
+
 /// Add one value to the operand list.
 void BranchInst::addOperand(CFGValue *value) {
   operands.emplace_back(InstOperand(this, value));
@@ -257,6 +289,18 @@
     addOperand(value);
 }
 
+//===----------------------------------------------------------------------===//
+// CondBranchInst
+//===----------------------------------------------------------------------===//
+
+CondBranchInst::CondBranchInst(CFGValue *condition, BasicBlock *trueDest,
+                               BasicBlock *falseDest)
+    : TerminatorInst(Kind::CondBranch),
+      condition(condition), dests{{this}, {this}}, numTrueOperands(0) {
+  dests[falseIndex].set(falseDest);
+  dests[trueIndex].set(trueDest);
+}
+
 /// Add one value to the true operand list.
 void CondBranchInst::addTrueOperand(CFGValue *value) {
   assert(getNumFalseOperands() == 0 &&