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();
}