Add support for multiple results to the printer/parser, add support
for forward references to the parser, add initial support for SSA
use-list iteration and RAUW.

PiperOrigin-RevId: 205484031
diff --git a/lib/IR/Instructions.cpp b/lib/IR/Instructions.cpp
index 57cedfe..b925cef 100644
--- a/lib/IR/Instructions.cpp
+++ b/lib/IR/Instructions.cpp
@@ -19,6 +19,23 @@
 #include "mlir/IR/BasicBlock.h"
 using namespace mlir;
 
+/// 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) {
+  assert(this != newValue && "cannot RAUW a value with itself");
+  while (!use_empty()) {
+    use_begin()->set(newValue);
+  }
+}
+
+/// Return the result number of this result.
+unsigned InstResult::getResultNumber() const {
+  // Results are always stored consecutively, so use pointer subtraction to
+  // figure out what number this is.
+  return this - &getOwner()->getInstResults()[0];
+}
+
 //===----------------------------------------------------------------------===//
 // Instruction
 //===----------------------------------------------------------------------===//
@@ -30,20 +47,25 @@
 }
 
 /// Destroy this instruction or one of its subclasses.
-void Instruction::destroy(Instruction *inst) {
-  switch (inst->getKind()) {
+void Instruction::destroy() {
+  switch (getKind()) {
   case Kind::Operation:
-    delete cast<OperationInst>(inst);
+    cast<OperationInst>(this)->destroy();
     break;
   case Kind::Branch:
-    delete cast<BranchInst>(inst);
+    delete cast<BranchInst>(this);
     break;
   case Kind::Return:
-    delete cast<ReturnInst>(inst);
+    delete cast<ReturnInst>(this);
     break;
   }
 }
 
+void OperationInst::destroy() {
+  this->~OperationInst();
+  free(this);
+}
+
 CFGFunction *Instruction::getFunction() const {
   return getBlock()->getFunction();
 }
@@ -60,7 +82,7 @@
                                      MLIRContext *context) {
   auto byteSize = totalSizeToAlloc<InstOperand, InstResult>(operands.size(),
                                                             resultTypes.size());
-  void *rawMem = ::operator new(byteSize);
+  void *rawMem = malloc(byteSize);
 
   // Initialize the OperationInst part of the instruction.
   auto inst = ::new (rawMem) OperationInst(
@@ -141,6 +163,14 @@
   getBlock()->getOperations().erase(this);
 }
 
+/// If this value is the result of an OperationInst, return the instruction
+/// that defines it.
+OperationInst *SSAValue::getDefiningInst() {
+  if (auto *result = dyn_cast<InstResult>(this))
+    return result->getOwner();
+  return nullptr;
+}
+
 //===----------------------------------------------------------------------===//
 // Terminators
 //===----------------------------------------------------------------------===//
@@ -149,7 +179,7 @@
 void TerminatorInst::eraseFromBlock() {
   assert(getBlock() && "Instruction has no parent");
   getBlock()->setTerminator(nullptr);
-  TerminatorInst::destroy(this);
+  destroy();
 }