diff --git a/mlir/include/mlir/IR/BasicBlock.h b/mlir/include/mlir/IR/BasicBlock.h index 73d0b7ffb6b8..7220be524df2 100644 --- a/mlir/include/mlir/IR/BasicBlock.h +++ b/mlir/include/mlir/IR/BasicBlock.h @@ -78,7 +78,7 @@ public: //===--------------------------------------------------------------------===// /// This is the list of operations in the block. - using OperationListType = llvm::iplist; + using OperationListType = llvm::iplist; OperationListType &getOperations() { return operations; } const OperationListType &getOperations() const { return operations; } @@ -98,16 +98,16 @@ public: const_reverse_iterator rend() const { return operations.rend(); } bool empty() const { return operations.empty(); } - void push_back(OperationInst *inst) { operations.push_back(inst); } - void push_front(OperationInst *inst) { operations.push_front(inst); } + void push_back(Instruction *inst) { operations.push_back(inst); } + void push_front(Instruction *inst) { operations.push_front(inst); } - OperationInst &back() { return operations.back(); } - const OperationInst &back() const { + Instruction &back() { return operations.back(); } + const Instruction &back() const { return const_cast(this)->back(); } - OperationInst &front() { return operations.front(); } - const OperationInst &front() const { + Instruction &front() { return operations.front(); } + const Instruction &front() const { return const_cast(this)->front(); } @@ -117,7 +117,7 @@ public: /// Get the terminator instruction of this block, or null if the block is /// malformed. - OperationInst *getTerminator() const; + Instruction *getTerminator() const; //===--------------------------------------------------------------------===// // Predecessors and successors. @@ -189,7 +189,7 @@ public: /// /// This function invalidates the specified iterator. BasicBlock *splitBasicBlock(iterator splitBefore); - BasicBlock *splitBasicBlock(OperationInst *splitBeforeInst) { + BasicBlock *splitBasicBlock(Instruction *splitBeforeInst) { return splitBasicBlock(iterator(splitBeforeInst)); } @@ -202,7 +202,7 @@ public: void printAsOperand(raw_ostream &os, bool printType = true); /// getSublistAccess() - Returns pointer to member of operation list - static OperationListType BasicBlock::*getSublistAccess(OperationInst*) { + static OperationListType BasicBlock::*getSublistAccess(Instruction *) { return &BasicBlock::operations; } diff --git a/mlir/include/mlir/IR/Builders.h b/mlir/include/mlir/IR/Builders.h index 9c8f916d0957..e2c31d44f209 100644 --- a/mlir/include/mlir/IR/Builders.h +++ b/mlir/include/mlir/IR/Builders.h @@ -169,7 +169,7 @@ public: setInsertionPoint(block, insertPoint); } - CFGFuncBuilder(OperationInst *insertBefore) + CFGFuncBuilder(Instruction *insertBefore) : CFGFuncBuilder(insertBefore->getBlock(), BasicBlock::iterator(insertBefore)) {} @@ -210,7 +210,7 @@ public: } /// Set the insertion point to the specified operation. - void setInsertionPoint(OperationInst *inst) { + void setInsertionPoint(Instruction *inst) { setInsertionPoint(inst->getBlock(), BasicBlock::iterator(inst)); } @@ -219,7 +219,7 @@ public: setInsertionPoint(block, block->end()); } - void insert(OperationInst *opInst) { + void insert(Instruction *opInst) { block->getOperations().insert(insertPoint, opInst); } @@ -230,7 +230,7 @@ public: BasicBlock *createBlock(BasicBlock *insertBefore = nullptr); /// Create an operation given the fields represented as an OperationState. - OperationInst *createOperation(const OperationState &state); + Instruction *createOperation(const OperationState &state); /// Create operation of specific op type at the current insertion point /// without verifying to see if it is valid. @@ -253,7 +253,7 @@ public: OpTy::build(this, &state, args...); auto *inst = createOperation(state); - // If the OperationInst we produce is valid, return it. + // If the Instruction we produce is valid, return it. if (!OpTy::verifyInvariants(inst)) { auto result = inst->dyn_cast(); assert(result && "Builder didn't return the right type"); @@ -266,7 +266,7 @@ public: return OpPointer(); } - OperationInst *cloneOperation(const OperationInst &srcOpInst) { + Instruction *cloneOperation(const Instruction &srcOpInst) { auto *op = srcOpInst.clone(); insert(op); return op; @@ -437,8 +437,8 @@ public: : Builder(mlFuncBuilder.getContext()), builder(mlFuncBuilder), kind(Function::Kind::MLFunc) {} FuncBuilder(Operation *op) : Builder(op->getContext()) { - if (isa(op)) { - builder = builderUnion(cast(op)); + if (auto *inst = dyn_cast(op)) { + builder = builderUnion(inst); kind = Function::Kind::CFGFunc; } else { builder = builderUnion(cast(op)); @@ -473,11 +473,11 @@ public: } /// Set the insertion point to the specified operation. This requires that the - /// input operation is a OperationInst when building a CFG function and a + /// input operation is a Instruction when building a CFG function and a /// OperationStmt when building a ML function. void setInsertionPoint(Operation *op) { if (kind == Function::Kind::CFGFunc) - builder.cfg.setInsertionPoint(cast(op)); + builder.cfg.setInsertionPoint(cast(op)); else builder.ml.setInsertionPoint(cast(op)); } @@ -487,7 +487,7 @@ private: union builderUnion { builderUnion(CFGFuncBuilder cfg) : cfg(cfg) {} builderUnion(MLFuncBuilder ml) : ml(ml) {} - builderUnion(OperationInst *op) : cfg(op) {} + builderUnion(Instruction *op) : cfg(op) {} builderUnion(OperationStmt *op) : ml(op) {} // Default initializer to allow deferring initialization of member. builderUnion() {} diff --git a/mlir/include/mlir/IR/CFGValue.h b/mlir/include/mlir/IR/CFGValue.h index 45b36c1bd054..d0140f3a3674 100644 --- a/mlir/include/mlir/IR/CFGValue.h +++ b/mlir/include/mlir/IR/CFGValue.h @@ -99,15 +99,15 @@ private: /// Instruction results are CFG Values. class InstResult : public CFGValue { public: - InstResult(Type type, OperationInst *owner) + InstResult(Type type, Instruction *owner) : CFGValue(CFGValueKind::InstResult, type), owner(owner) {} static bool classof(const SSAValue *value) { return value->getKind() == SSAValueKind::InstResult; } - OperationInst *getOwner() { return owner; } - const OperationInst *getOwner() const { return owner; } + Instruction *getOwner() { return owner; } + const Instruction *getOwner() const { return owner; } /// Return the number of this result. unsigned getResultNumber() const; @@ -116,7 +116,7 @@ private: /// The owner of this operand. /// TODO: can encode this more efficiently to avoid the space hit of this /// through bitpacking shenanigans. - OperationInst *const owner; + Instruction *const owner; }; } // namespace mlir diff --git a/mlir/include/mlir/IR/Instructions.h b/mlir/include/mlir/IR/Instructions.h index 53d3cca23b0b..a083e26d1906 100644 --- a/mlir/include/mlir/IR/Instructions.h +++ b/mlir/include/mlir/IR/Instructions.h @@ -32,24 +32,22 @@ namespace mlir { class BasicBlock; class CFGFunction; -class OperationInst; -class TerminatorInst; } // end namespace mlir //===----------------------------------------------------------------------===// -// ilist_traits for OperationInst +// ilist_traits for Instruction //===----------------------------------------------------------------------===// namespace llvm { -template <> struct ilist_traits<::mlir::OperationInst> { - using OperationInst = ::mlir::OperationInst; - using instr_iterator = simple_ilist::iterator; +template <> struct ilist_traits<::mlir::Instruction> { + using Instruction = ::mlir::Instruction; + using instr_iterator = simple_ilist::iterator; - static void deleteNode(OperationInst *inst); - void addNodeToList(OperationInst *inst); - void removeNodeFromList(OperationInst *inst); - void transferNodesFromList(ilist_traits &otherList, + static void deleteNode(Instruction *inst); + void addNodeToList(Instruction *inst); + void removeNodeFromList(Instruction *inst); + void transferNodesFromList(ilist_traits &otherList, instr_iterator first, instr_iterator last); private: @@ -63,44 +61,35 @@ namespace mlir { /// The operand of a Terminator contains a BasicBlock. using BasicBlockOperand = IROperandImpl; -/// Instruction is the root of the operation and terminator instructions in the -/// hierarchy. -class Instruction : public IROperandOwner { +// The trailing objects of an instruction are layed out as follows: +// - InstResult : The results of the instruction. +// - BasicBlockOperand : Use-list of successor blocks if this is a terminator. +// - unsigned : Count of operands held for each of the successors. +// +// Note: For Terminators, we rely on the assumption that all non successor +// operands are placed at the beginning of the operands list. +class Instruction final + : public Operation, + public IROperandOwner, + public llvm::ilist_node_with_parent, + private llvm::TrailingObjects { public: - enum class Kind { - Operation = (int)IROperandOwner::Kind::OperationInst, - }; - - Kind getKind() const { return (Kind)IROperandOwner::getKind(); } - - /// Return the BasicBlock containing this instruction. - const BasicBlock *getBlock() const { return block; } - BasicBlock *getBlock() { return block; } - - /// Return the CFGFunction containing this instruction. - CFGFunction *getFunction(); - const CFGFunction *getFunction() const { - return const_cast(this)->getFunction(); - } - - /// Destroy this instruction and its subclass data. - void destroy(); - - void print(raw_ostream &os) const; - void dump() const; + using IROperandOwner::getContext; + using IROperandOwner::getLoc; //===--------------------------------------------------------------------===// // Operands //===--------------------------------------------------------------------===// - unsigned getNumOperands() const; + unsigned getNumOperands() const { return operands.size(); } CFGValue *getOperand(unsigned idx) { return getInstOperand(idx).get(); } const CFGValue *getOperand(unsigned idx) const { return getInstOperand(idx).get(); } void setOperand(unsigned idx, CFGValue *value) { - return getInstOperand(idx).set(value); + getInstOperand(idx).set(value); } // Support non-const operand iteration. @@ -132,144 +121,10 @@ public: return {operand_begin(), operand_end()}; } - MutableArrayRef getInstOperands(); - ArrayRef getInstOperands() const { - return const_cast(this)->getInstOperands(); - } - - InstOperand &getInstOperand(unsigned idx) { return getInstOperands()[idx]; } - const InstOperand &getInstOperand(unsigned idx) const { - return getInstOperands()[idx]; - } - - /// This drops all operand uses from this instruction, which is an essential - /// step in breaking cyclic dependences between references when they are to - /// be deleted. - void dropAllReferences(); - - /// Emit an error about fatal conditions with this operation, reporting up to - /// any diagnostic handlers that may be listening. NOTE: This may terminate - /// the containing application, only use when the IR is in an inconsistent - /// state. - void emitError(const Twine &message) const; - - /// Emit a warning about this operation, reporting up to any diagnostic - /// handlers that may be listening. - void emitWarning(const Twine &message) const; - - /// Emit a note about this operation, reporting up to any diagnostic - /// handlers that may be listening. - void emitNote(const Twine &message) const; - - /// Methods for support type inquiry through isa, cast, and dyn_cast. - static bool classof(const IROperandOwner *ptr) { - return ptr->getKind() >= IROperandOwner::Kind::INST_FIRST; - } - -protected: - Instruction(Kind kind, Location location) - : IROperandOwner((IROperandOwner::Kind)kind, location) {} - - // Instructions are deleted through the destroy() member because this class - // does not have a virtual destructor. A vtable would bloat the size of - // every instruction by a word, is not necessary given the closed nature of - // instruction kinds. - ~Instruction(); - -private: - BasicBlock *block = nullptr; - - friend struct llvm::ilist_traits; - friend class BasicBlock; -}; - -inline raw_ostream &operator<<(raw_ostream &os, const Instruction &inst) { - inst.print(os); - return os; -} - -/// Operations are the main instruction kind in MLIR, which represent all of the -/// arithmetic and other basic computation. -// -// The trailing objects of an operation instruction are layed out as follows: -// - InstResult : The results of the instruction. -// - BasicBlockOperand : Use-list of successor blocks if this is a terminator. -// - unsigned : Count of operands held for each of the successors. -// -// Note: For Terminators, we rely on the assumption that all non successor -// operands are placed at the beginning of the operands list. -class OperationInst final - : public Operation, - public Instruction, - public llvm::ilist_node_with_parent, - private llvm::TrailingObjects { -public: - /// Create a new OperationInst with the specified fields. - static OperationInst * - create(Location location, OperationName name, ArrayRef operands, - ArrayRef resultTypes, ArrayRef attributes, - ArrayRef successors, MLIRContext *context); - - using Instruction::dump; - using Instruction::emitError; - using Instruction::emitNote; - using Instruction::emitWarning; - using Instruction::getContext; - using Instruction::getLoc; - using Instruction::print; - - OperationInst *clone() const; - - //===--------------------------------------------------------------------===// - // Operands - //===--------------------------------------------------------------------===// - - unsigned getNumOperands() const { return operands.size(); } - - CFGValue *getOperand(unsigned idx) { return getInstOperand(idx).get(); } - const CFGValue *getOperand(unsigned idx) const { - return getInstOperand(idx).get(); - } - void setOperand(unsigned idx, CFGValue *value) { - getInstOperand(idx).set(value); - } - - // Support non-const operand iteration. - using operand_iterator = OperandIterator; - - operand_iterator operand_begin() { return operand_iterator(this, 0); } - - operand_iterator operand_end() { - return operand_iterator(this, getNumOperands()); - } - - llvm::iterator_range getOperands() { - return {operand_begin(), operand_end()}; - } - - // Support const operand iteration. - using const_operand_iterator = - OperandIterator; - - const_operand_iterator operand_begin() const { - return const_operand_iterator(this, 0); - } - - const_operand_iterator operand_end() const { - return const_operand_iterator(this, getNumOperands()); - } - - llvm::iterator_range getOperands() const { - return {operand_begin(), operand_end()}; - } - MutableArrayRef getInstOperands() { return operands; } ArrayRef getInstOperands() const { return operands; } - // Accessors to InstOperand. Without these methods invoking getInstOperand() - // calls Instruction::getInstOperands() resulting in execution of - // an unnecessary switch statement. + // Accessors to InstOperand. InstOperand &getInstOperand(unsigned idx) { return getInstOperands()[idx]; } const InstOperand &getInstOperand(unsigned idx) const { return getInstOperands()[idx]; @@ -285,7 +140,7 @@ public: const CFGValue *getResult(unsigned idx) const { return &getInstResult(idx); } // Support non-const result iteration. - using result_iterator = ResultIterator; + using result_iterator = ResultIterator; result_iterator result_begin() { return result_iterator(this, 0); } result_iterator result_end() { return result_iterator(this, getNumResults()); @@ -296,7 +151,7 @@ public: // Support const operand iteration. using const_result_iterator = - ResultIterator; + ResultIterator; const_result_iterator result_begin() const { return const_result_iterator(this, 0); } @@ -332,7 +187,7 @@ public: return {getTrailingObjects(), numSuccs}; } ArrayRef getBasicBlockOperands() const { - return const_cast(this)->getBasicBlockOperands(); + return const_cast(this)->getBasicBlockOperands(); } MutableArrayRef getSuccessorInstOperands(unsigned index) { @@ -343,7 +198,7 @@ public: return {operandBegin, getNumSuccessorOperands(index)}; } ArrayRef getSuccessorInstOperands(unsigned index) const { - return const_cast(this)->getSuccessorInstOperands(index); + return const_cast(this)->getSuccessorInstOperands(index); } unsigned getNumSuccessors() const { return getBasicBlockOperands().size(); } @@ -358,7 +213,7 @@ public: return getBasicBlockOperands()[index].get(); } BasicBlock *getSuccessor(unsigned index) const { - return const_cast(this)->getSuccessor(index); + return const_cast(this)->getSuccessor(index); } void setSuccessor(BasicBlock *block, unsigned index) { assert(index < getNumSuccessors()); @@ -395,26 +250,66 @@ public: // Other //===--------------------------------------------------------------------===// + /// Create a new Instruction with the specified fields. + static Instruction * + create(Location location, OperationName name, ArrayRef operands, + ArrayRef resultTypes, ArrayRef attributes, + ArrayRef successors, MLIRContext *context); + + Instruction *clone() const; + + /// Return the BasicBlock containing this instruction. + const BasicBlock *getBlock() const { return block; } + BasicBlock *getBlock() { return block; } + + /// Return the CFGFunction containing this instruction. + CFGFunction *getFunction(); + const CFGFunction *getFunction() const { + return const_cast(this)->getFunction(); + } + + void print(raw_ostream &os) const; + void dump() const; + /// Unlink this instruction from its BasicBlock and delete it. void erase(); - /// Delete an instruction that is not linked into a block. + /// Destroy this instruction and its subclass data. void destroy(); - /// Unlink this operation instruction from its current basic block and insert + /// Unlink this instruction from its current basic block and insert /// it right before `existingInst` which may be in the same or another block /// of the same function. - void moveBefore(OperationInst *existingInst); + void moveBefore(Instruction *existingInst); - /// Unlink this operation instruction from its current basic block and insert + /// Unlink this instruction from its current basic block and insert /// it right before `iterator` in the specified basic block, which must be in /// the same function. void moveBefore(BasicBlock *block, - llvm::iplist::iterator iterator); + llvm::iplist::iterator iterator); + + /// This drops all operand uses from this instruction, which is an essential + /// step in breaking cyclic dependences between references when they are to + /// be deleted. + void dropAllReferences(); + + /// Emit an error about fatal conditions with this operation, reporting up to + /// any diagnostic handlers that may be listening. NOTE: This may terminate + /// the containing application, only use when the IR is in an inconsistent + /// state. + void emitError(const Twine &message) const; + + /// Emit a warning about this operation, reporting up to any diagnostic + /// handlers that may be listening. + void emitWarning(const Twine &message) const; + + /// Emit a note about this operation, reporting up to any diagnostic + /// handlers that may be listening. + void emitNote(const Twine &message) const; /// Methods for support type inquiry through isa, cast, and dyn_cast. static bool classof(const IROperandOwner *ptr) { - return ptr->getKind() == IROperandOwner::Kind::OperationInst; + return ptr->getKind() == IROperandOwner::Kind::Instruction; } static bool classof(const Operation *op) { return op->getOperationKind() == OperationKind::Instruction; @@ -423,14 +318,21 @@ public: private: const unsigned numResults, numSuccs; std::vector operands; + BasicBlock *block = nullptr; - OperationInst(Location location, OperationName name, unsigned numResults, - unsigned numSuccessors, ArrayRef attributes, - MLIRContext *context); - ~OperationInst(); + Instruction(Location location, OperationName name, unsigned numResults, + unsigned numSuccessors, ArrayRef attributes, + MLIRContext *context); + + // Instructions are deleted through the destroy() member because this class + // does not have a virtual destructor. + ~Instruction(); + + friend struct llvm::ilist_traits; + friend class BasicBlock; // This stuff is used by the TrailingObjects template. - friend llvm::TrailingObjects; size_t numTrailingObjects(OverloadToken) const { return numResults; @@ -441,6 +343,14 @@ private: size_t numTrailingObjects(OverloadToken) const { return numSuccs; } }; +inline raw_ostream &operator<<(raw_ostream &os, const Instruction &inst) { + inst.print(os); + return os; +} + +// TODO(riverriddle) Remove this when all uses have been renamed. +using OperationInst = Instruction; + } // end namespace mlir #endif // MLIR_IR_INSTRUCTIONS_H diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h index 433245a68d3f..1f4f5276dc9d 100644 --- a/mlir/include/mlir/IR/Operation.h +++ b/mlir/include/mlir/IR/Operation.h @@ -35,7 +35,7 @@ class Instruction; class Statement; /// Operations represent all of the arithmetic and other basic computation in -/// MLIR. This class is the common implementation details behind OperationInst +/// MLIR. This class is the common implementation details behind Instruction /// and OperationStmt. /// class Operation { @@ -196,7 +196,7 @@ public: } /// The dyn_cast methods perform a dynamic cast from an Operation (like - /// OperationInst and OperationStmt) to a typed Op like DimOp. This returns + /// Instruction and OperationStmt) to a typed Op like DimOp. This returns /// a null OpPointer on failure. template OpPointer dyn_cast() { if (isa()) { @@ -207,7 +207,7 @@ public: } /// The dyn_cast methods perform a dynamic cast from an Operation (like - /// OperationInst and OperationStmt) to a typed Op like DimOp. This returns + /// Instruction and OperationStmt) to a typed Op like DimOp. This returns /// a null ConstOpPointer on failure. template ConstOpPointer dyn_cast() const { if (isa()) { @@ -218,7 +218,7 @@ public: } /// The cast methods perform a cast from an Operation (like - /// OperationInst and OperationStmt) to a typed Op like DimOp. This aborts + /// Instruction and OperationStmt) to a typed Op like DimOp. This aborts /// if the parameter to the template isn't an instance of the template type /// argument. template OpPointer cast() { @@ -227,7 +227,7 @@ public: } /// The cast methods perform a cast from an Operation (like - /// OperationInst and OperationStmt) to a typed Op like DimOp. This aborts + /// Instruction and OperationStmt) to a typed Op like DimOp. This aborts /// if the parameter to the template isn't an instance of the template type /// argument. template ConstOpPointer cast() const { @@ -243,7 +243,7 @@ public: enum class OperationKind { Instruction, Statement }; // This is used to implement the dynamic casting logic, but you shouldn't - // call it directly. Use something like isa(someOp) instead. + // call it directly. Use something like isa(someOp) instead. OperationKind getOperationKind() const { return nameAndIsInstruction.getInt() ? OperationKind::Instruction : OperationKind::Statement; @@ -285,7 +285,6 @@ public: void dump() const; /// Methods for support type inquiry through isa, cast, and dyn_cast. - static bool classof(const Instruction *inst); static bool classof(const Statement *stmt); static bool classof(const IROperandOwner *ptr); @@ -299,7 +298,7 @@ private: void operator=(const Operation&) = delete; /// This holds the name of the operation, and a bool. The bool is true if - /// this operation is an OperationInst, false if it is a OperationStmt. + /// this operation is an Instruction, false if it is a OperationStmt. llvm::PointerIntPair nameAndIsInstruction; /// This holds general named attributes for the operation. diff --git a/mlir/include/mlir/IR/SSAValue.h b/mlir/include/mlir/IR/SSAValue.h index ab16c981eda0..29bc6f034c50 100644 --- a/mlir/include/mlir/IR/SSAValue.h +++ b/mlir/include/mlir/IR/SSAValue.h @@ -28,7 +28,7 @@ namespace mlir { class Function; -class OperationInst; +class Instruction; class OperationStmt; class Operation; @@ -67,10 +67,10 @@ public: return const_cast(this)->getFunction(); } - /// If this value is the result of an OperationInst, return the instruction + /// If this value is the result of an Instruction, return the instruction /// that defines it. - OperationInst *getDefiningInst(); - const OperationInst *getDefiningInst() const { + Instruction *getDefiningInst(); + const Instruction *getDefiningInst() const { return const_cast(this)->getDefiningInst(); } diff --git a/mlir/include/mlir/IR/UseDefLists.h b/mlir/include/mlir/IR/UseDefLists.h index f77b8a02bafa..bf7b34b49a83 100644 --- a/mlir/include/mlir/IR/UseDefLists.h +++ b/mlir/include/mlir/IR/UseDefLists.h @@ -79,11 +79,10 @@ public: OperationStmt, ForStmt, IfStmt, - OperationInst, + Instruction, /// These enums define ranges used for classof implementations. STMT_LAST = IfStmt, - INST_FIRST = OperationInst, }; Kind getKind() const { return locationAndKind.getInt(); } diff --git a/mlir/lib/Analysis/Dominance.cpp b/mlir/lib/Analysis/Dominance.cpp index 6b1a26305bf6..499d6351b33d 100644 --- a/mlir/lib/Analysis/Dominance.cpp +++ b/mlir/lib/Analysis/Dominance.cpp @@ -49,17 +49,15 @@ bool DominanceInfo::properlyDominates(const Instruction *a, return false; // If one is a terminator, then the other dominates it. - auto *aOp = cast(a); - if (aOp->isTerminator()) + if (a->isTerminator()) return false; - auto *bOp = cast(b); - if (bOp->isTerminator()) + if (b->isTerminator()) return true; // Otherwise, do a linear scan to determine whether B comes after A. - auto aIter = BasicBlock::const_iterator(aOp); - auto bIter = BasicBlock::const_iterator(bOp); + auto aIter = BasicBlock::const_iterator(a); + auto bIter = BasicBlock::const_iterator(b); auto fIter = aBlock->begin(); while (bIter != fIter) { --bIter; diff --git a/mlir/lib/IR/AsmPrinter.cpp b/mlir/lib/IR/AsmPrinter.cpp index 81902be6455a..67d33d9b9dfb 100644 --- a/mlir/lib/IR/AsmPrinter.cpp +++ b/mlir/lib/IR/AsmPrinter.cpp @@ -1168,7 +1168,6 @@ public: void print(const BasicBlock *block); void print(const Instruction *inst); - void print(const OperationInst *inst); void printSuccessorAndUseList(const Operation *term, unsigned index); @@ -1277,13 +1276,6 @@ void CFGFunctionPrinter::print(const Instruction *inst) { os << "<>\n"; return; } - switch (inst->getKind()) { - case Instruction::Kind::Operation: - return print(cast(inst)); - } -} - -void CFGFunctionPrinter::print(const OperationInst *inst) { printOperation(inst); } diff --git a/mlir/lib/IR/Instructions.cpp b/mlir/lib/IR/Instructions.cpp index e20c827e5e4a..059637b986a9 100644 --- a/mlir/lib/IR/Instructions.cpp +++ b/mlir/lib/IR/Instructions.cpp @@ -41,101 +41,21 @@ unsigned InstResult::getResultNumber() const { // Instruction //===----------------------------------------------------------------------===// -// Instructions are deleted through the destroy() member because we don't have -// a virtual destructor. -Instruction::~Instruction() { - assert(block == nullptr && "instruction destroyed but still in a block"); -} - -/// Destroy this instruction or one of its subclasses. -void Instruction::destroy() { - switch (getKind()) { - case Kind::Operation: - cast(this)->destroy(); - break; - } -} - -void OperationInst::destroy() { - this->~OperationInst(); - free(this); -} - -CFGFunction *Instruction::getFunction() { - auto *block = getBlock(); - return block ? block->getFunction() : nullptr; -} - -unsigned Instruction::getNumOperands() const { - switch (getKind()) { - case Kind::Operation: - return cast(this)->getNumOperands(); - } -} - -MutableArrayRef Instruction::getInstOperands() { - switch (getKind()) { - case Kind::Operation: - return cast(this)->getInstOperands(); - } -} - -/// This drops all operand uses from this instruction, which is an essential -/// step in breaking cyclic dependences between references when they are to -/// be deleted. -void Instruction::dropAllReferences() { - for (auto &op : getInstOperands()) - op.drop(); - - if (OperationInst *opInst = dyn_cast(this)) { - if (opInst->isTerminator()) - for (auto &dest : opInst->getBasicBlockOperands()) - dest.drop(); - } -} - -/// Emit a note about this instruction, reporting up to any diagnostic -/// handlers that may be listening. -void Instruction::emitNote(const Twine &message) const { - getContext()->emitDiagnostic(getLoc(), message, - MLIRContext::DiagnosticKind::Note); -} - -/// Emit a warning about this operation, reporting up to any diagnostic -/// handlers that may be listening. -void Instruction::emitWarning(const Twine &message) const { - getContext()->emitDiagnostic(getLoc(), message, - MLIRContext::DiagnosticKind::Warning); -} - -/// Emit an error about fatal conditions with this instruction, reporting up to -/// any diagnostic handlers that may be listening. NOTE: This may terminate -/// the containing application, only use when the IR is in an inconsistent -/// state. -void Instruction::emitError(const Twine &message) const { - getContext()->emitDiagnostic(getLoc(), message, - MLIRContext::DiagnosticKind::Error); -} - -//===----------------------------------------------------------------------===// -// OperationInst -//===----------------------------------------------------------------------===// - -/// Create a new OperationInst with the specified fields. -OperationInst *OperationInst::create(Location location, OperationName name, - ArrayRef operands, - ArrayRef resultTypes, - ArrayRef attributes, - ArrayRef successors, - MLIRContext *context) { +/// Create a new Instruction with the specified fields. +Instruction *Instruction::create(Location location, OperationName name, + ArrayRef operands, + ArrayRef resultTypes, + ArrayRef attributes, + ArrayRef successors, + MLIRContext *context) { unsigned numSuccessors = successors.size(); auto byteSize = totalSizeToAlloc( resultTypes.size(), numSuccessors, numSuccessors); void *rawMem = malloc(byteSize); - // Initialize the OperationInst part of the instruction. - auto inst = ::new (rawMem) OperationInst(location, name, resultTypes.size(), - numSuccessors, attributes, context); + // Initialize the Instruction part of the instruction. + auto inst = ::new (rawMem) Instruction(location, name, resultTypes.size(), + numSuccessors, attributes, context); // Initialize the results and operands. auto instResults = inst->getInstResults(); @@ -193,7 +113,7 @@ OperationInst *OperationInst::create(Location location, OperationName name, return inst; } -OperationInst *OperationInst::clone() const { +Instruction *Instruction::clone() const { SmallVector operands; SmallVector resultTypes; SmallVector successors; @@ -238,15 +158,17 @@ OperationInst *OperationInst::clone() const { successors, getContext()); } -OperationInst::OperationInst(Location location, OperationName name, - unsigned numResults, unsigned numSuccessors, - ArrayRef attributes, - MLIRContext *context) +Instruction::Instruction(Location location, OperationName name, + unsigned numResults, unsigned numSuccessors, + ArrayRef attributes, + MLIRContext *context) : Operation(/*isInstruction=*/true, name, attributes, context), - Instruction(Kind::Operation, location), numResults(numResults), - numSuccs(numSuccessors) {} + IROperandOwner(IROperandOwner::Kind::Instruction, location), + numResults(numResults), numSuccs(numSuccessors) {} + +Instruction::~Instruction() { + assert(block == nullptr && "instruction destroyed but still in a block"); -OperationInst::~OperationInst() { // Explicitly run the destructors for the results and successors. for (auto &result : getInstResults()) result.~InstResult(); @@ -256,7 +178,53 @@ OperationInst::~OperationInst() { successor.~BasicBlockOperand(); } -void OperationInst::addSuccessorOperand(unsigned index, CFGValue *value) { +/// Destroy this instruction. +void Instruction::destroy() { + this->~Instruction(); + free(this); +} + +CFGFunction *Instruction::getFunction() { + auto *block = getBlock(); + return block ? block->getFunction() : nullptr; +} + +/// This drops all operand uses from this instruction, which is an essential +/// step in breaking cyclic dependences between references when they are to +/// be deleted. +void Instruction::dropAllReferences() { + for (auto &op : getInstOperands()) + op.drop(); + + if (isTerminator()) + for (auto &dest : getBasicBlockOperands()) + dest.drop(); +} + +/// Emit a note about this instruction, reporting up to any diagnostic +/// handlers that may be listening. +void Instruction::emitNote(const Twine &message) const { + getContext()->emitDiagnostic(getLoc(), message, + MLIRContext::DiagnosticKind::Note); +} + +/// Emit a warning about this operation, reporting up to any diagnostic +/// handlers that may be listening. +void Instruction::emitWarning(const Twine &message) const { + getContext()->emitDiagnostic(getLoc(), message, + MLIRContext::DiagnosticKind::Warning); +} + +/// Emit an error about fatal conditions with this instruction, reporting up to +/// any diagnostic handlers that may be listening. NOTE: This may terminate +/// the containing application, only use when the IR is in an inconsistent +/// state. +void Instruction::emitError(const Twine &message) const { + getContext()->emitDiagnostic(getLoc(), message, + MLIRContext::DiagnosticKind::Error); +} + +void Instruction::addSuccessorOperand(unsigned index, CFGValue *value) { assert(isTerminator() && "Only terminators have successors."); assert(index < getNumSuccessors()); assert(std::accumulate(getTrailingObjects() + index + 1, @@ -267,47 +235,45 @@ void OperationInst::addSuccessorOperand(unsigned index, CFGValue *value) { ++getTrailingObjects()[index]; } -void OperationInst::addSuccessorOperands(unsigned index, - ArrayRef values) { +void Instruction::addSuccessorOperands(unsigned index, + ArrayRef values) { operands.reserve(operands.size() + values.size()); for (auto *value : values) addSuccessorOperand(index, value); } -void llvm::ilist_traits<::mlir::OperationInst>::deleteNode( - OperationInst *inst) { +void llvm::ilist_traits<::mlir::Instruction>::deleteNode(Instruction *inst) { inst->destroy(); } mlir::BasicBlock * -llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() { +llvm::ilist_traits<::mlir::Instruction>::getContainingBlock() { size_t Offset( size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr)))); - iplist *Anchor(static_cast *>(this)); + iplist *Anchor(static_cast *>(this)); return reinterpret_cast(reinterpret_cast(Anchor) - Offset); } /// This is a trait method invoked when an instruction is added to a block. We /// keep the block pointer up to date. -void llvm::ilist_traits<::mlir::OperationInst>::addNodeToList( - OperationInst *inst) { +void llvm::ilist_traits<::mlir::Instruction>::addNodeToList(Instruction *inst) { assert(!inst->getBlock() && "already in a basic block!"); inst->block = getContainingBlock(); } /// This is a trait method invoked when an instruction is removed from a block. /// We keep the block pointer up to date. -void llvm::ilist_traits<::mlir::OperationInst>::removeNodeFromList( - OperationInst *inst) { +void llvm::ilist_traits<::mlir::Instruction>::removeNodeFromList( + Instruction *inst) { assert(inst->block && "not already in a basic block!"); inst->block = nullptr; } /// This is a trait method invoked when an instruction is moved from one block /// to another. We keep the block pointer up to date. -void llvm::ilist_traits<::mlir::OperationInst>::transferNodesFromList( - ilist_traits &otherList, instr_iterator first, +void llvm::ilist_traits<::mlir::Instruction>::transferNodesFromList( + ilist_traits &otherList, instr_iterator first, instr_iterator last) { // If we are transferring instructions within the same basic block, the block // pointer doesn't need to be updated. @@ -321,7 +287,7 @@ void llvm::ilist_traits<::mlir::OperationInst>::transferNodesFromList( } /// Unlink this instruction from its BasicBlock and delete it. -void OperationInst::erase() { +void Instruction::erase() { assert(getBlock() && "Instruction has no parent"); getBlock()->getOperations().erase(this); } @@ -329,15 +295,15 @@ void OperationInst::erase() { /// Unlink this operation instruction from its current basic block and insert /// it right before `existingInst` which may be in the same or another block /// in the same function. -void OperationInst::moveBefore(OperationInst *existingInst) { +void Instruction::moveBefore(Instruction *existingInst) { assert(existingInst && "Cannot move before a null instruction"); return moveBefore(existingInst->getBlock(), existingInst->getIterator()); } /// Unlink this operation instruction from its current basic block and insert /// it right before `iterator` in the specified basic block. -void OperationInst::moveBefore(BasicBlock *block, - llvm::iplist::iterator iterator) { +void Instruction::moveBefore(BasicBlock *block, + llvm::iplist::iterator iterator) { block->getOperations().splice(iterator, getBlock()->getOperations(), getIterator()); } diff --git a/mlir/lib/IR/Operation.cpp b/mlir/lib/IR/Operation.cpp index cc64b152ebee..48617e65f207 100644 --- a/mlir/lib/IR/Operation.cpp +++ b/mlir/lib/IR/Operation.cpp @@ -74,7 +74,7 @@ Operation::~Operation() {} /// Return the context this operation is associated with. MLIRContext *Operation::getContext() const { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->getContext(); return llvm::cast(this)->getContext(); } @@ -82,35 +82,35 @@ MLIRContext *Operation::getContext() const { /// The source location the operation was defined or derived from. Note that /// it is possible for this pointer to be null. Location Operation::getLoc() const { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->getLoc(); return llvm::cast(this)->getLoc(); } /// Return the function this operation is defined in. Function *Operation::getOperationFunction() { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->getFunction(); return llvm::cast(this)->findFunction(); } /// Return the number of operands this operation has. unsigned Operation::getNumOperands() const { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->getNumOperands(); return llvm::cast(this)->getNumOperands(); } SSAValue *Operation::getOperand(unsigned idx) { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->getOperand(idx); return llvm::cast(this)->getOperand(idx); } void Operation::setOperand(unsigned idx, SSAValue *value) { - if (auto *inst = llvm::dyn_cast(this)) { + if (auto *inst = llvm::dyn_cast(this)) { inst->setOperand(idx, llvm::cast(value)); } else { auto *stmt = llvm::cast(this); @@ -120,7 +120,7 @@ void Operation::setOperand(unsigned idx, SSAValue *value) { /// Return the number of results this operation has. unsigned Operation::getNumResults() const { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->getNumResults(); return llvm::cast(this)->getNumResults(); @@ -128,7 +128,7 @@ unsigned Operation::getNumResults() const { /// Return the indicated result. SSAValue *Operation::getResult(unsigned idx) { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->getResult(idx); return llvm::cast(this)->getResult(idx); @@ -136,8 +136,8 @@ SSAValue *Operation::getResult(unsigned idx) { unsigned Operation::getNumSuccessors() const { assert(isTerminator() && "Only terminators have successors."); - if (llvm::isa(this)) - return llvm::cast(this)->getNumSuccessors(); + if (llvm::isa(this)) + return llvm::cast(this)->getNumSuccessors(); // OperationStmt currently only has a return terminator. assert(llvm::cast(this)->isReturn() && @@ -147,36 +147,33 @@ unsigned Operation::getNumSuccessors() const { unsigned Operation::getNumSuccessorOperands(unsigned index) const { assert(isTerminator() && "Only terminators have successors."); - assert(llvm::isa(this) && - "Only instructions have successors."); - return llvm::cast(this)->getNumSuccessorOperands(index); + assert(llvm::isa(this) && "Only instructions have successors."); + return llvm::cast(this)->getNumSuccessorOperands(index); } BasicBlock *Operation::getSuccessor(unsigned index) { assert(isTerminator() && "Only terminators have successors."); - assert(llvm::isa(this) && + assert(llvm::isa(this) && "Only instructions have basic block successors."); - return llvm::cast(this)->getSuccessor(index); + return llvm::cast(this)->getSuccessor(index); } void Operation::setSuccessor(BasicBlock *block, unsigned index) { assert(isTerminator() && "Only terminators have successors."); - assert(llvm::isa(this) && + assert(llvm::isa(this) && "Only instructions have basic block successors."); - llvm::cast(this)->setSuccessor(block, index); + llvm::cast(this)->setSuccessor(block, index); } void Operation::addSuccessorOperand(unsigned index, SSAValue *value) { assert(isTerminator() && "Only terminators have successors."); - assert(llvm::isa(this) && - "Only instructions have successors."); - return llvm::cast(this)->addSuccessorOperand( + assert(llvm::isa(this) && "Only instructions have successors."); + return llvm::cast(this)->addSuccessorOperand( index, llvm::cast(value)); } auto Operation::getSuccessorOperands(unsigned index) const -> llvm::iterator_range { assert(isTerminator() && "Only terminators have successors."); - assert(llvm::isa(this) && - "Only instructions have successors."); + assert(llvm::isa(this) && "Only instructions have successors."); unsigned succOperandIndex = - llvm::cast(this)->getSuccessorOperandIndex(index); + llvm::cast(this)->getSuccessorOperandIndex(index); return {const_operand_iterator(this, succOperandIndex), const_operand_iterator(this, succOperandIndex + getNumSuccessorOperands(index))}; @@ -184,10 +181,9 @@ auto Operation::getSuccessorOperands(unsigned index) const auto Operation::getSuccessorOperands(unsigned index) -> llvm::iterator_range { assert(isTerminator() && "Only terminators have successors."); - assert(llvm::isa(this) && - "Only instructions have successors."); + assert(llvm::isa(this) && "Only instructions have successors."); unsigned succOperandIndex = - llvm::cast(this)->getSuccessorOperandIndex(index); + llvm::cast(this)->getSuccessorOperandIndex(index); return {operand_iterator(this, succOperandIndex), operand_iterator(this, succOperandIndex + getNumSuccessorOperands(index))}; @@ -278,7 +274,7 @@ bool Operation::emitOpError(const Twine &message) const { /// Remove this operation from its parent block and delete it. void Operation::erase() { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->erase(); return llvm::cast(this)->erase(); } @@ -302,26 +298,23 @@ bool Operation::constantFold(ArrayRef operands, } void Operation::print(raw_ostream &os) const { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->print(os); return llvm::cast(this)->print(os); } void Operation::dump() const { - if (auto *inst = llvm::dyn_cast(this)) + if (auto *inst = llvm::dyn_cast(this)) return inst->dump(); return llvm::cast(this)->dump(); } /// Methods for support type inquiry through isa, cast, and dyn_cast. -bool Operation::classof(const Instruction *inst) { - return inst->getKind() == Instruction::Kind::Operation; -} bool Operation::classof(const Statement *stmt) { return stmt->getKind() == Statement::Kind::Operation; } bool Operation::classof(const IROperandOwner *ptr) { - return ptr->getKind() == IROperandOwner::Kind::OperationInst || + return ptr->getKind() == IROperandOwner::Kind::Instruction || ptr->getKind() == IROperandOwner::Kind::OperationStmt; } @@ -337,7 +330,7 @@ llvm::cast_convert_val(value)) op = ptr; else - op = cast(value); + op = cast(value); return const_cast(op); } @@ -540,7 +533,7 @@ bool OpTrait::impl::verifyIsTerminator(const Operation *op) { if (!block || !isa(block) || &block->back() != stmt) return op->emitOpError("must be the last statement in the ML function"); } else { - const OperationInst *inst = cast(op); + const Instruction *inst = cast(op); const BasicBlock *block = inst->getBlock(); if (!block || &block->back() != inst) return op->emitOpError( diff --git a/mlir/lib/IR/SSAValue.cpp b/mlir/lib/IR/SSAValue.cpp index eb631f1760c4..14fd4a459d3e 100644 --- a/mlir/lib/IR/SSAValue.cpp +++ b/mlir/lib/IR/SSAValue.cpp @@ -23,9 +23,9 @@ using namespace mlir; -/// If this value is the result of an OperationInst, return the instruction +/// If this value is the result of an Instruction, return the instruction /// that defines it. -OperationInst *SSAValue::getDefiningInst() { +Instruction *SSAValue::getDefiningInst() { if (auto *result = dyn_cast(this)) return result->getOwner(); return nullptr; @@ -77,7 +77,7 @@ MLIRContext *IROperandOwner::getContext() const { case Kind::IfStmt: return cast(this)->getContext(); - case Kind::OperationInst: + case Kind::Instruction: // If we have an instruction, we can efficiently get this from the function // the instruction is in. auto *fn = cast(this)->getFunction(); diff --git a/mlir/lib/Parser/Parser.cpp b/mlir/lib/Parser/Parser.cpp index 2d07443d1e67..f55504588511 100644 --- a/mlir/lib/Parser/Parser.cpp +++ b/mlir/lib/Parser/Parser.cpp @@ -1936,10 +1936,10 @@ SSAValue *FunctionParser::createForwardReferencePlaceholder(SMLoc loc, // cannot be created through normal user input, allowing us to distinguish // them. auto name = OperationName("placeholder", getContext()); - auto *inst = OperationInst::create(getEncodedSourceLocation(loc), name, - /*operands=*/{}, type, - /*attributes=*/{}, - /*successors=*/{}, getContext()); + auto *inst = Instruction::create(getEncodedSourceLocation(loc), name, + /*operands=*/{}, type, + /*attributes=*/{}, + /*successors=*/{}, getContext()); forwardReferencePlaceholders[inst->getResult(0)] = loc; return inst->getResult(0); }