forked from OSchip/llvm-project
Merge OperationInst functionality into Instruction.
We do some limited renaming here but define an alias for OperationInst so that a follow up cl can solely perform the large scale renaming. PiperOrigin-RevId: 221726963
This commit is contained in:
parent
711047c0cd
commit
8b6bc09f48
|
@ -78,7 +78,7 @@ public:
|
|||
//===--------------------------------------------------------------------===//
|
||||
|
||||
/// This is the list of operations in the block.
|
||||
using OperationListType = llvm::iplist<OperationInst>;
|
||||
using OperationListType = llvm::iplist<Instruction>;
|
||||
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<BasicBlock *>(this)->back();
|
||||
}
|
||||
|
||||
OperationInst &front() { return operations.front(); }
|
||||
const OperationInst &front() const {
|
||||
Instruction &front() { return operations.front(); }
|
||||
const Instruction &front() const {
|
||||
return const_cast<BasicBlock*>(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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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<OpTy>();
|
||||
assert(result && "Builder didn't return the right type");
|
||||
|
@ -266,7 +266,7 @@ public:
|
|||
return OpPointer<OpTy>();
|
||||
}
|
||||
|
||||
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<OperationInst>(op)) {
|
||||
builder = builderUnion(cast<OperationInst>(op));
|
||||
if (auto *inst = dyn_cast<Instruction>(op)) {
|
||||
builder = builderUnion(inst);
|
||||
kind = Function::Kind::CFGFunc;
|
||||
} else {
|
||||
builder = builderUnion(cast<OperationStmt>(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<OperationInst>(op));
|
||||
builder.cfg.setInsertionPoint(cast<Instruction>(op));
|
||||
else
|
||||
builder.ml.setInsertionPoint(cast<OperationStmt>(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() {}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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<OperationInst>::iterator;
|
||||
template <> struct ilist_traits<::mlir::Instruction> {
|
||||
using Instruction = ::mlir::Instruction;
|
||||
using instr_iterator = simple_ilist<Instruction>::iterator;
|
||||
|
||||
static void deleteNode(OperationInst *inst);
|
||||
void addNodeToList(OperationInst *inst);
|
||||
void removeNodeFromList(OperationInst *inst);
|
||||
void transferNodesFromList(ilist_traits<OperationInst> &otherList,
|
||||
static void deleteNode(Instruction *inst);
|
||||
void addNodeToList(Instruction *inst);
|
||||
void removeNodeFromList(Instruction *inst);
|
||||
void transferNodesFromList(ilist_traits<Instruction> &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<BasicBlock, Instruction>;
|
||||
|
||||
/// 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<Instruction, BasicBlock>,
|
||||
private llvm::TrailingObjects<Instruction, InstResult, BasicBlockOperand,
|
||||
unsigned> {
|
||||
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<Instruction *>(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<InstOperand> getInstOperands();
|
||||
ArrayRef<InstOperand> getInstOperands() const {
|
||||
return const_cast<Instruction *>(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<OperationInst>;
|
||||
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<OperationInst, BasicBlock>,
|
||||
private llvm::TrailingObjects<OperationInst, InstResult,
|
||||
BasicBlockOperand, unsigned> {
|
||||
public:
|
||||
/// Create a new OperationInst with the specified fields.
|
||||
static OperationInst *
|
||||
create(Location location, OperationName name, ArrayRef<CFGValue *> operands,
|
||||
ArrayRef<Type> resultTypes, ArrayRef<NamedAttribute> attributes,
|
||||
ArrayRef<BasicBlock *> 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<OperationInst, CFGValue>;
|
||||
|
||||
operand_iterator operand_begin() { return operand_iterator(this, 0); }
|
||||
|
||||
operand_iterator operand_end() {
|
||||
return operand_iterator(this, getNumOperands());
|
||||
}
|
||||
|
||||
llvm::iterator_range<operand_iterator> getOperands() {
|
||||
return {operand_begin(), operand_end()};
|
||||
}
|
||||
|
||||
// Support const operand iteration.
|
||||
using const_operand_iterator =
|
||||
OperandIterator<const OperationInst, const CFGValue>;
|
||||
|
||||
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<const_operand_iterator> getOperands() const {
|
||||
return {operand_begin(), operand_end()};
|
||||
}
|
||||
|
||||
MutableArrayRef<InstOperand> getInstOperands() { return operands; }
|
||||
ArrayRef<InstOperand> 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<OperationInst, CFGValue>;
|
||||
using result_iterator = ResultIterator<Instruction, CFGValue>;
|
||||
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<const OperationInst, const CFGValue>;
|
||||
ResultIterator<const Instruction, const CFGValue>;
|
||||
const_result_iterator result_begin() const {
|
||||
return const_result_iterator(this, 0);
|
||||
}
|
||||
|
@ -332,7 +187,7 @@ public:
|
|||
return {getTrailingObjects<BasicBlockOperand>(), numSuccs};
|
||||
}
|
||||
ArrayRef<BasicBlockOperand> getBasicBlockOperands() const {
|
||||
return const_cast<OperationInst *>(this)->getBasicBlockOperands();
|
||||
return const_cast<Instruction *>(this)->getBasicBlockOperands();
|
||||
}
|
||||
|
||||
MutableArrayRef<InstOperand> getSuccessorInstOperands(unsigned index) {
|
||||
|
@ -343,7 +198,7 @@ public:
|
|||
return {operandBegin, getNumSuccessorOperands(index)};
|
||||
}
|
||||
ArrayRef<InstOperand> getSuccessorInstOperands(unsigned index) const {
|
||||
return const_cast<OperationInst *>(this)->getSuccessorInstOperands(index);
|
||||
return const_cast<Instruction *>(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<OperationInst *>(this)->getSuccessor(index);
|
||||
return const_cast<Instruction *>(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<CFGValue *> operands,
|
||||
ArrayRef<Type> resultTypes, ArrayRef<NamedAttribute> attributes,
|
||||
ArrayRef<BasicBlock *> 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<Instruction *>(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<OperationInst>::iterator iterator);
|
||||
llvm::iplist<Instruction>::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<InstOperand> operands;
|
||||
BasicBlock *block = nullptr;
|
||||
|
||||
OperationInst(Location location, OperationName name, unsigned numResults,
|
||||
unsigned numSuccessors, ArrayRef<NamedAttribute> attributes,
|
||||
MLIRContext *context);
|
||||
~OperationInst();
|
||||
Instruction(Location location, OperationName name, unsigned numResults,
|
||||
unsigned numSuccessors, ArrayRef<NamedAttribute> 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<Instruction>;
|
||||
friend class BasicBlock;
|
||||
|
||||
// This stuff is used by the TrailingObjects template.
|
||||
friend llvm::TrailingObjects<OperationInst, InstResult, BasicBlockOperand,
|
||||
friend llvm::TrailingObjects<Instruction, InstResult, BasicBlockOperand,
|
||||
unsigned>;
|
||||
size_t numTrailingObjects(OverloadToken<InstResult>) const {
|
||||
return numResults;
|
||||
|
@ -441,6 +343,14 @@ private:
|
|||
size_t numTrailingObjects(OverloadToken<unsigned>) 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
|
||||
|
|
|
@ -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 <typename OpClass> OpPointer<OpClass> dyn_cast() {
|
||||
if (isa<OpClass>()) {
|
||||
|
@ -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 <typename OpClass> ConstOpPointer<OpClass> dyn_cast() const {
|
||||
if (isa<OpClass>()) {
|
||||
|
@ -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 <typename OpClass> OpPointer<OpClass> 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 <typename OpClass> ConstOpPointer<OpClass> 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<OperationInst>(someOp) instead.
|
||||
// call it directly. Use something like isa<Instruction>(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<OperationName, 1, bool> nameAndIsInstruction;
|
||||
|
||||
/// This holds general named attributes for the operation.
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
|
||||
namespace mlir {
|
||||
class Function;
|
||||
class OperationInst;
|
||||
class Instruction;
|
||||
class OperationStmt;
|
||||
class Operation;
|
||||
|
||||
|
@ -67,10 +67,10 @@ public:
|
|||
return const_cast<SSAValue *>(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<SSAValue *>(this)->getDefiningInst();
|
||||
}
|
||||
|
||||
|
|
|
@ -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(); }
|
||||
|
|
|
@ -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<OperationInst>(a);
|
||||
if (aOp->isTerminator())
|
||||
if (a->isTerminator())
|
||||
return false;
|
||||
|
||||
auto *bOp = cast<OperationInst>(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;
|
||||
|
|
|
@ -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 << "<<null instruction>>\n";
|
||||
return;
|
||||
}
|
||||
switch (inst->getKind()) {
|
||||
case Instruction::Kind::Operation:
|
||||
return print(cast<OperationInst>(inst));
|
||||
}
|
||||
}
|
||||
|
||||
void CFGFunctionPrinter::print(const OperationInst *inst) {
|
||||
printOperation(inst);
|
||||
}
|
||||
|
||||
|
|
|
@ -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<OperationInst>(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<OperationInst>(this)->getNumOperands();
|
||||
}
|
||||
}
|
||||
|
||||
MutableArrayRef<InstOperand> Instruction::getInstOperands() {
|
||||
switch (getKind()) {
|
||||
case Kind::Operation:
|
||||
return cast<OperationInst>(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<OperationInst>(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<CFGValue *> operands,
|
||||
ArrayRef<Type> resultTypes,
|
||||
ArrayRef<NamedAttribute> attributes,
|
||||
ArrayRef<BasicBlock *> successors,
|
||||
MLIRContext *context) {
|
||||
/// Create a new Instruction with the specified fields.
|
||||
Instruction *Instruction::create(Location location, OperationName name,
|
||||
ArrayRef<CFGValue *> operands,
|
||||
ArrayRef<Type> resultTypes,
|
||||
ArrayRef<NamedAttribute> attributes,
|
||||
ArrayRef<BasicBlock *> successors,
|
||||
MLIRContext *context) {
|
||||
unsigned numSuccessors = successors.size();
|
||||
auto byteSize = totalSizeToAlloc<InstResult, BasicBlockOperand, unsigned>(
|
||||
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<CFGValue *, 8> operands;
|
||||
SmallVector<Type, 8> resultTypes;
|
||||
SmallVector<BasicBlock *, 1> successors;
|
||||
|
@ -238,15 +158,17 @@ OperationInst *OperationInst::clone() const {
|
|||
successors, getContext());
|
||||
}
|
||||
|
||||
OperationInst::OperationInst(Location location, OperationName name,
|
||||
unsigned numResults, unsigned numSuccessors,
|
||||
ArrayRef<NamedAttribute> attributes,
|
||||
MLIRContext *context)
|
||||
Instruction::Instruction(Location location, OperationName name,
|
||||
unsigned numResults, unsigned numSuccessors,
|
||||
ArrayRef<NamedAttribute> 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<unsigned>() + index + 1,
|
||||
|
@ -267,47 +235,45 @@ void OperationInst::addSuccessorOperand(unsigned index, CFGValue *value) {
|
|||
++getTrailingObjects<unsigned>()[index];
|
||||
}
|
||||
|
||||
void OperationInst::addSuccessorOperands(unsigned index,
|
||||
ArrayRef<CFGValue *> values) {
|
||||
void Instruction::addSuccessorOperands(unsigned index,
|
||||
ArrayRef<CFGValue *> 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<OperationInst> *Anchor(static_cast<iplist<OperationInst> *>(this));
|
||||
iplist<Instruction> *Anchor(static_cast<iplist<Instruction> *>(this));
|
||||
return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(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<OperationInst> &otherList, instr_iterator first,
|
||||
void llvm::ilist_traits<::mlir::Instruction>::transferNodesFromList(
|
||||
ilist_traits<Instruction> &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<OperationInst>::iterator iterator) {
|
||||
void Instruction::moveBefore(BasicBlock *block,
|
||||
llvm::iplist<Instruction>::iterator iterator) {
|
||||
block->getOperations().splice(iterator, getBlock()->getOperations(),
|
||||
getIterator());
|
||||
}
|
||||
|
|
|
@ -74,7 +74,7 @@ Operation::~Operation() {}
|
|||
|
||||
/// Return the context this operation is associated with.
|
||||
MLIRContext *Operation::getContext() const {
|
||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->getContext();
|
||||
return llvm::cast<OperationStmt>(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<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->getLoc();
|
||||
return llvm::cast<OperationStmt>(this)->getLoc();
|
||||
}
|
||||
|
||||
/// Return the function this operation is defined in.
|
||||
Function *Operation::getOperationFunction() {
|
||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->getFunction();
|
||||
return llvm::cast<OperationStmt>(this)->findFunction();
|
||||
}
|
||||
|
||||
/// Return the number of operands this operation has.
|
||||
unsigned Operation::getNumOperands() const {
|
||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->getNumOperands();
|
||||
|
||||
return llvm::cast<OperationStmt>(this)->getNumOperands();
|
||||
}
|
||||
|
||||
SSAValue *Operation::getOperand(unsigned idx) {
|
||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->getOperand(idx);
|
||||
|
||||
return llvm::cast<OperationStmt>(this)->getOperand(idx);
|
||||
}
|
||||
|
||||
void Operation::setOperand(unsigned idx, SSAValue *value) {
|
||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this)) {
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this)) {
|
||||
inst->setOperand(idx, llvm::cast<CFGValue>(value));
|
||||
} else {
|
||||
auto *stmt = llvm::cast<OperationStmt>(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<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->getNumResults();
|
||||
|
||||
return llvm::cast<OperationStmt>(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<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->getResult(idx);
|
||||
|
||||
return llvm::cast<OperationStmt>(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<OperationInst>(this))
|
||||
return llvm::cast<OperationInst>(this)->getNumSuccessors();
|
||||
if (llvm::isa<Instruction>(this))
|
||||
return llvm::cast<Instruction>(this)->getNumSuccessors();
|
||||
|
||||
// OperationStmt currently only has a return terminator.
|
||||
assert(llvm::cast<OperationStmt>(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<OperationInst>(this) &&
|
||||
"Only instructions have successors.");
|
||||
return llvm::cast<OperationInst>(this)->getNumSuccessorOperands(index);
|
||||
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||
return llvm::cast<Instruction>(this)->getNumSuccessorOperands(index);
|
||||
}
|
||||
BasicBlock *Operation::getSuccessor(unsigned index) {
|
||||
assert(isTerminator() && "Only terminators have successors.");
|
||||
assert(llvm::isa<OperationInst>(this) &&
|
||||
assert(llvm::isa<Instruction>(this) &&
|
||||
"Only instructions have basic block successors.");
|
||||
return llvm::cast<OperationInst>(this)->getSuccessor(index);
|
||||
return llvm::cast<Instruction>(this)->getSuccessor(index);
|
||||
}
|
||||
void Operation::setSuccessor(BasicBlock *block, unsigned index) {
|
||||
assert(isTerminator() && "Only terminators have successors.");
|
||||
assert(llvm::isa<OperationInst>(this) &&
|
||||
assert(llvm::isa<Instruction>(this) &&
|
||||
"Only instructions have basic block successors.");
|
||||
llvm::cast<OperationInst>(this)->setSuccessor(block, index);
|
||||
llvm::cast<Instruction>(this)->setSuccessor(block, index);
|
||||
}
|
||||
void Operation::addSuccessorOperand(unsigned index, SSAValue *value) {
|
||||
assert(isTerminator() && "Only terminators have successors.");
|
||||
assert(llvm::isa<OperationInst>(this) &&
|
||||
"Only instructions have successors.");
|
||||
return llvm::cast<OperationInst>(this)->addSuccessorOperand(
|
||||
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||
return llvm::cast<Instruction>(this)->addSuccessorOperand(
|
||||
index, llvm::cast<CFGValue>(value));
|
||||
}
|
||||
auto Operation::getSuccessorOperands(unsigned index) const
|
||||
-> llvm::iterator_range<const_operand_iterator> {
|
||||
assert(isTerminator() && "Only terminators have successors.");
|
||||
assert(llvm::isa<OperationInst>(this) &&
|
||||
"Only instructions have successors.");
|
||||
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||
unsigned succOperandIndex =
|
||||
llvm::cast<OperationInst>(this)->getSuccessorOperandIndex(index);
|
||||
llvm::cast<Instruction>(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<operand_iterator> {
|
||||
assert(isTerminator() && "Only terminators have successors.");
|
||||
assert(llvm::isa<OperationInst>(this) &&
|
||||
"Only instructions have successors.");
|
||||
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||
unsigned succOperandIndex =
|
||||
llvm::cast<OperationInst>(this)->getSuccessorOperandIndex(index);
|
||||
llvm::cast<Instruction>(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<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->erase();
|
||||
return llvm::cast<OperationStmt>(this)->erase();
|
||||
}
|
||||
|
@ -302,26 +298,23 @@ bool Operation::constantFold(ArrayRef<Attribute> operands,
|
|||
}
|
||||
|
||||
void Operation::print(raw_ostream &os) const {
|
||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->print(os);
|
||||
return llvm::cast<OperationStmt>(this)->print(os);
|
||||
}
|
||||
|
||||
void Operation::dump() const {
|
||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
||||
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||
return inst->dump();
|
||||
return llvm::cast<OperationStmt>(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<mlir::Operation, mlir::IROperandOwner *,
|
|||
if (auto *ptr = dyn_cast<OperationStmt>(value))
|
||||
op = ptr;
|
||||
else
|
||||
op = cast<OperationInst>(value);
|
||||
op = cast<Instruction>(value);
|
||||
return const_cast<Operation *>(op);
|
||||
}
|
||||
|
||||
|
@ -540,7 +533,7 @@ bool OpTrait::impl::verifyIsTerminator(const Operation *op) {
|
|||
if (!block || !isa<MLFunction>(block) || &block->back() != stmt)
|
||||
return op->emitOpError("must be the last statement in the ML function");
|
||||
} else {
|
||||
const OperationInst *inst = cast<OperationInst>(op);
|
||||
const Instruction *inst = cast<Instruction>(op);
|
||||
const BasicBlock *block = inst->getBlock();
|
||||
if (!block || &block->back() != inst)
|
||||
return op->emitOpError(
|
||||
|
|
|
@ -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<InstResult>(this))
|
||||
return result->getOwner();
|
||||
return nullptr;
|
||||
|
@ -77,7 +77,7 @@ MLIRContext *IROperandOwner::getContext() const {
|
|||
case Kind::IfStmt:
|
||||
return cast<IfStmt>(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<Instruction>(this)->getFunction();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue