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.
|
/// This is the list of operations in the block.
|
||||||
using OperationListType = llvm::iplist<OperationInst>;
|
using OperationListType = llvm::iplist<Instruction>;
|
||||||
OperationListType &getOperations() { return operations; }
|
OperationListType &getOperations() { return operations; }
|
||||||
const OperationListType &getOperations() const { return operations; }
|
const OperationListType &getOperations() const { return operations; }
|
||||||
|
|
||||||
|
@ -98,16 +98,16 @@ public:
|
||||||
const_reverse_iterator rend() const { return operations.rend(); }
|
const_reverse_iterator rend() const { return operations.rend(); }
|
||||||
|
|
||||||
bool empty() const { return operations.empty(); }
|
bool empty() const { return operations.empty(); }
|
||||||
void push_back(OperationInst *inst) { operations.push_back(inst); }
|
void push_back(Instruction *inst) { operations.push_back(inst); }
|
||||||
void push_front(OperationInst *inst) { operations.push_front(inst); }
|
void push_front(Instruction *inst) { operations.push_front(inst); }
|
||||||
|
|
||||||
OperationInst &back() { return operations.back(); }
|
Instruction &back() { return operations.back(); }
|
||||||
const OperationInst &back() const {
|
const Instruction &back() const {
|
||||||
return const_cast<BasicBlock *>(this)->back();
|
return const_cast<BasicBlock *>(this)->back();
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationInst &front() { return operations.front(); }
|
Instruction &front() { return operations.front(); }
|
||||||
const OperationInst &front() const {
|
const Instruction &front() const {
|
||||||
return const_cast<BasicBlock*>(this)->front();
|
return const_cast<BasicBlock*>(this)->front();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,7 +117,7 @@ public:
|
||||||
|
|
||||||
/// Get the terminator instruction of this block, or null if the block is
|
/// Get the terminator instruction of this block, or null if the block is
|
||||||
/// malformed.
|
/// malformed.
|
||||||
OperationInst *getTerminator() const;
|
Instruction *getTerminator() const;
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Predecessors and successors.
|
// Predecessors and successors.
|
||||||
|
@ -189,7 +189,7 @@ public:
|
||||||
///
|
///
|
||||||
/// This function invalidates the specified iterator.
|
/// This function invalidates the specified iterator.
|
||||||
BasicBlock *splitBasicBlock(iterator splitBefore);
|
BasicBlock *splitBasicBlock(iterator splitBefore);
|
||||||
BasicBlock *splitBasicBlock(OperationInst *splitBeforeInst) {
|
BasicBlock *splitBasicBlock(Instruction *splitBeforeInst) {
|
||||||
return splitBasicBlock(iterator(splitBeforeInst));
|
return splitBasicBlock(iterator(splitBeforeInst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -202,7 +202,7 @@ public:
|
||||||
void printAsOperand(raw_ostream &os, bool printType = true);
|
void printAsOperand(raw_ostream &os, bool printType = true);
|
||||||
|
|
||||||
/// getSublistAccess() - Returns pointer to member of operation list
|
/// getSublistAccess() - Returns pointer to member of operation list
|
||||||
static OperationListType BasicBlock::*getSublistAccess(OperationInst*) {
|
static OperationListType BasicBlock::*getSublistAccess(Instruction *) {
|
||||||
return &BasicBlock::operations;
|
return &BasicBlock::operations;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -169,7 +169,7 @@ public:
|
||||||
setInsertionPoint(block, insertPoint);
|
setInsertionPoint(block, insertPoint);
|
||||||
}
|
}
|
||||||
|
|
||||||
CFGFuncBuilder(OperationInst *insertBefore)
|
CFGFuncBuilder(Instruction *insertBefore)
|
||||||
: CFGFuncBuilder(insertBefore->getBlock(),
|
: CFGFuncBuilder(insertBefore->getBlock(),
|
||||||
BasicBlock::iterator(insertBefore)) {}
|
BasicBlock::iterator(insertBefore)) {}
|
||||||
|
|
||||||
|
@ -210,7 +210,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the insertion point to the specified operation.
|
/// Set the insertion point to the specified operation.
|
||||||
void setInsertionPoint(OperationInst *inst) {
|
void setInsertionPoint(Instruction *inst) {
|
||||||
setInsertionPoint(inst->getBlock(), BasicBlock::iterator(inst));
|
setInsertionPoint(inst->getBlock(), BasicBlock::iterator(inst));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +219,7 @@ public:
|
||||||
setInsertionPoint(block, block->end());
|
setInsertionPoint(block, block->end());
|
||||||
}
|
}
|
||||||
|
|
||||||
void insert(OperationInst *opInst) {
|
void insert(Instruction *opInst) {
|
||||||
block->getOperations().insert(insertPoint, opInst);
|
block->getOperations().insert(insertPoint, opInst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -230,7 +230,7 @@ public:
|
||||||
BasicBlock *createBlock(BasicBlock *insertBefore = nullptr);
|
BasicBlock *createBlock(BasicBlock *insertBefore = nullptr);
|
||||||
|
|
||||||
/// Create an operation given the fields represented as an OperationState.
|
/// 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
|
/// Create operation of specific op type at the current insertion point
|
||||||
/// without verifying to see if it is valid.
|
/// without verifying to see if it is valid.
|
||||||
|
@ -253,7 +253,7 @@ public:
|
||||||
OpTy::build(this, &state, args...);
|
OpTy::build(this, &state, args...);
|
||||||
auto *inst = createOperation(state);
|
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)) {
|
if (!OpTy::verifyInvariants(inst)) {
|
||||||
auto result = inst->dyn_cast<OpTy>();
|
auto result = inst->dyn_cast<OpTy>();
|
||||||
assert(result && "Builder didn't return the right type");
|
assert(result && "Builder didn't return the right type");
|
||||||
|
@ -266,7 +266,7 @@ public:
|
||||||
return OpPointer<OpTy>();
|
return OpPointer<OpTy>();
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationInst *cloneOperation(const OperationInst &srcOpInst) {
|
Instruction *cloneOperation(const Instruction &srcOpInst) {
|
||||||
auto *op = srcOpInst.clone();
|
auto *op = srcOpInst.clone();
|
||||||
insert(op);
|
insert(op);
|
||||||
return op;
|
return op;
|
||||||
|
@ -437,8 +437,8 @@ public:
|
||||||
: Builder(mlFuncBuilder.getContext()), builder(mlFuncBuilder),
|
: Builder(mlFuncBuilder.getContext()), builder(mlFuncBuilder),
|
||||||
kind(Function::Kind::MLFunc) {}
|
kind(Function::Kind::MLFunc) {}
|
||||||
FuncBuilder(Operation *op) : Builder(op->getContext()) {
|
FuncBuilder(Operation *op) : Builder(op->getContext()) {
|
||||||
if (isa<OperationInst>(op)) {
|
if (auto *inst = dyn_cast<Instruction>(op)) {
|
||||||
builder = builderUnion(cast<OperationInst>(op));
|
builder = builderUnion(inst);
|
||||||
kind = Function::Kind::CFGFunc;
|
kind = Function::Kind::CFGFunc;
|
||||||
} else {
|
} else {
|
||||||
builder = builderUnion(cast<OperationStmt>(op));
|
builder = builderUnion(cast<OperationStmt>(op));
|
||||||
|
@ -473,11 +473,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Set the insertion point to the specified operation. This requires that the
|
/// 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.
|
/// OperationStmt when building a ML function.
|
||||||
void setInsertionPoint(Operation *op) {
|
void setInsertionPoint(Operation *op) {
|
||||||
if (kind == Function::Kind::CFGFunc)
|
if (kind == Function::Kind::CFGFunc)
|
||||||
builder.cfg.setInsertionPoint(cast<OperationInst>(op));
|
builder.cfg.setInsertionPoint(cast<Instruction>(op));
|
||||||
else
|
else
|
||||||
builder.ml.setInsertionPoint(cast<OperationStmt>(op));
|
builder.ml.setInsertionPoint(cast<OperationStmt>(op));
|
||||||
}
|
}
|
||||||
|
@ -487,7 +487,7 @@ private:
|
||||||
union builderUnion {
|
union builderUnion {
|
||||||
builderUnion(CFGFuncBuilder cfg) : cfg(cfg) {}
|
builderUnion(CFGFuncBuilder cfg) : cfg(cfg) {}
|
||||||
builderUnion(MLFuncBuilder ml) : ml(ml) {}
|
builderUnion(MLFuncBuilder ml) : ml(ml) {}
|
||||||
builderUnion(OperationInst *op) : cfg(op) {}
|
builderUnion(Instruction *op) : cfg(op) {}
|
||||||
builderUnion(OperationStmt *op) : ml(op) {}
|
builderUnion(OperationStmt *op) : ml(op) {}
|
||||||
// Default initializer to allow deferring initialization of member.
|
// Default initializer to allow deferring initialization of member.
|
||||||
builderUnion() {}
|
builderUnion() {}
|
||||||
|
|
|
@ -99,15 +99,15 @@ private:
|
||||||
/// Instruction results are CFG Values.
|
/// Instruction results are CFG Values.
|
||||||
class InstResult : public CFGValue {
|
class InstResult : public CFGValue {
|
||||||
public:
|
public:
|
||||||
InstResult(Type type, OperationInst *owner)
|
InstResult(Type type, Instruction *owner)
|
||||||
: CFGValue(CFGValueKind::InstResult, type), owner(owner) {}
|
: CFGValue(CFGValueKind::InstResult, type), owner(owner) {}
|
||||||
|
|
||||||
static bool classof(const SSAValue *value) {
|
static bool classof(const SSAValue *value) {
|
||||||
return value->getKind() == SSAValueKind::InstResult;
|
return value->getKind() == SSAValueKind::InstResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationInst *getOwner() { return owner; }
|
Instruction *getOwner() { return owner; }
|
||||||
const OperationInst *getOwner() const { return owner; }
|
const Instruction *getOwner() const { return owner; }
|
||||||
|
|
||||||
/// Return the number of this result.
|
/// Return the number of this result.
|
||||||
unsigned getResultNumber() const;
|
unsigned getResultNumber() const;
|
||||||
|
@ -116,7 +116,7 @@ private:
|
||||||
/// The owner of this operand.
|
/// The owner of this operand.
|
||||||
/// TODO: can encode this more efficiently to avoid the space hit of this
|
/// TODO: can encode this more efficiently to avoid the space hit of this
|
||||||
/// through bitpacking shenanigans.
|
/// through bitpacking shenanigans.
|
||||||
OperationInst *const owner;
|
Instruction *const owner;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mlir
|
} // namespace mlir
|
||||||
|
|
|
@ -32,24 +32,22 @@
|
||||||
namespace mlir {
|
namespace mlir {
|
||||||
class BasicBlock;
|
class BasicBlock;
|
||||||
class CFGFunction;
|
class CFGFunction;
|
||||||
class OperationInst;
|
|
||||||
class TerminatorInst;
|
|
||||||
} // end namespace mlir
|
} // end namespace mlir
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// ilist_traits for OperationInst
|
// ilist_traits for Instruction
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
template <> struct ilist_traits<::mlir::OperationInst> {
|
template <> struct ilist_traits<::mlir::Instruction> {
|
||||||
using OperationInst = ::mlir::OperationInst;
|
using Instruction = ::mlir::Instruction;
|
||||||
using instr_iterator = simple_ilist<OperationInst>::iterator;
|
using instr_iterator = simple_ilist<Instruction>::iterator;
|
||||||
|
|
||||||
static void deleteNode(OperationInst *inst);
|
static void deleteNode(Instruction *inst);
|
||||||
void addNodeToList(OperationInst *inst);
|
void addNodeToList(Instruction *inst);
|
||||||
void removeNodeFromList(OperationInst *inst);
|
void removeNodeFromList(Instruction *inst);
|
||||||
void transferNodesFromList(ilist_traits<OperationInst> &otherList,
|
void transferNodesFromList(ilist_traits<Instruction> &otherList,
|
||||||
instr_iterator first, instr_iterator last);
|
instr_iterator first, instr_iterator last);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -63,44 +61,35 @@ namespace mlir {
|
||||||
/// The operand of a Terminator contains a BasicBlock.
|
/// The operand of a Terminator contains a BasicBlock.
|
||||||
using BasicBlockOperand = IROperandImpl<BasicBlock, Instruction>;
|
using BasicBlockOperand = IROperandImpl<BasicBlock, Instruction>;
|
||||||
|
|
||||||
/// Instruction is the root of the operation and terminator instructions in the
|
// The trailing objects of an instruction are layed out as follows:
|
||||||
/// hierarchy.
|
// - InstResult : The results of the instruction.
|
||||||
class Instruction : public IROperandOwner {
|
// - 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:
|
public:
|
||||||
enum class Kind {
|
using IROperandOwner::getContext;
|
||||||
Operation = (int)IROperandOwner::Kind::OperationInst,
|
using IROperandOwner::getLoc;
|
||||||
};
|
|
||||||
|
|
||||||
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;
|
|
||||||
|
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
// Operands
|
// Operands
|
||||||
//===--------------------------------------------------------------------===//
|
//===--------------------------------------------------------------------===//
|
||||||
|
|
||||||
unsigned getNumOperands() const;
|
unsigned getNumOperands() const { return operands.size(); }
|
||||||
|
|
||||||
CFGValue *getOperand(unsigned idx) { return getInstOperand(idx).get(); }
|
CFGValue *getOperand(unsigned idx) { return getInstOperand(idx).get(); }
|
||||||
const CFGValue *getOperand(unsigned idx) const {
|
const CFGValue *getOperand(unsigned idx) const {
|
||||||
return getInstOperand(idx).get();
|
return getInstOperand(idx).get();
|
||||||
}
|
}
|
||||||
void setOperand(unsigned idx, CFGValue *value) {
|
void setOperand(unsigned idx, CFGValue *value) {
|
||||||
return getInstOperand(idx).set(value);
|
getInstOperand(idx).set(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Support non-const operand iteration.
|
// Support non-const operand iteration.
|
||||||
|
@ -132,144 +121,10 @@ public:
|
||||||
return {operand_begin(), operand_end()};
|
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; }
|
MutableArrayRef<InstOperand> getInstOperands() { return operands; }
|
||||||
ArrayRef<InstOperand> getInstOperands() const { return operands; }
|
ArrayRef<InstOperand> getInstOperands() const { return operands; }
|
||||||
|
|
||||||
// Accessors to InstOperand. Without these methods invoking getInstOperand()
|
// Accessors to InstOperand.
|
||||||
// calls Instruction::getInstOperands() resulting in execution of
|
|
||||||
// an unnecessary switch statement.
|
|
||||||
InstOperand &getInstOperand(unsigned idx) { return getInstOperands()[idx]; }
|
InstOperand &getInstOperand(unsigned idx) { return getInstOperands()[idx]; }
|
||||||
const InstOperand &getInstOperand(unsigned idx) const {
|
const InstOperand &getInstOperand(unsigned idx) const {
|
||||||
return getInstOperands()[idx];
|
return getInstOperands()[idx];
|
||||||
|
@ -285,7 +140,7 @@ public:
|
||||||
const CFGValue *getResult(unsigned idx) const { return &getInstResult(idx); }
|
const CFGValue *getResult(unsigned idx) const { return &getInstResult(idx); }
|
||||||
|
|
||||||
// Support non-const result iteration.
|
// 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_begin() { return result_iterator(this, 0); }
|
||||||
result_iterator result_end() {
|
result_iterator result_end() {
|
||||||
return result_iterator(this, getNumResults());
|
return result_iterator(this, getNumResults());
|
||||||
|
@ -296,7 +151,7 @@ public:
|
||||||
|
|
||||||
// Support const operand iteration.
|
// Support const operand iteration.
|
||||||
using const_result_iterator =
|
using const_result_iterator =
|
||||||
ResultIterator<const OperationInst, const CFGValue>;
|
ResultIterator<const Instruction, const CFGValue>;
|
||||||
const_result_iterator result_begin() const {
|
const_result_iterator result_begin() const {
|
||||||
return const_result_iterator(this, 0);
|
return const_result_iterator(this, 0);
|
||||||
}
|
}
|
||||||
|
@ -332,7 +187,7 @@ public:
|
||||||
return {getTrailingObjects<BasicBlockOperand>(), numSuccs};
|
return {getTrailingObjects<BasicBlockOperand>(), numSuccs};
|
||||||
}
|
}
|
||||||
ArrayRef<BasicBlockOperand> getBasicBlockOperands() const {
|
ArrayRef<BasicBlockOperand> getBasicBlockOperands() const {
|
||||||
return const_cast<OperationInst *>(this)->getBasicBlockOperands();
|
return const_cast<Instruction *>(this)->getBasicBlockOperands();
|
||||||
}
|
}
|
||||||
|
|
||||||
MutableArrayRef<InstOperand> getSuccessorInstOperands(unsigned index) {
|
MutableArrayRef<InstOperand> getSuccessorInstOperands(unsigned index) {
|
||||||
|
@ -343,7 +198,7 @@ public:
|
||||||
return {operandBegin, getNumSuccessorOperands(index)};
|
return {operandBegin, getNumSuccessorOperands(index)};
|
||||||
}
|
}
|
||||||
ArrayRef<InstOperand> getSuccessorInstOperands(unsigned index) const {
|
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(); }
|
unsigned getNumSuccessors() const { return getBasicBlockOperands().size(); }
|
||||||
|
@ -358,7 +213,7 @@ public:
|
||||||
return getBasicBlockOperands()[index].get();
|
return getBasicBlockOperands()[index].get();
|
||||||
}
|
}
|
||||||
BasicBlock *getSuccessor(unsigned index) const {
|
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) {
|
void setSuccessor(BasicBlock *block, unsigned index) {
|
||||||
assert(index < getNumSuccessors());
|
assert(index < getNumSuccessors());
|
||||||
|
@ -395,26 +250,66 @@ public:
|
||||||
// Other
|
// 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.
|
/// Unlink this instruction from its BasicBlock and delete it.
|
||||||
void erase();
|
void erase();
|
||||||
|
|
||||||
/// Delete an instruction that is not linked into a block.
|
/// Destroy this instruction and its subclass data.
|
||||||
void destroy();
|
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
|
/// it right before `existingInst` which may be in the same or another block
|
||||||
/// of the same function.
|
/// 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
|
/// it right before `iterator` in the specified basic block, which must be in
|
||||||
/// the same function.
|
/// the same function.
|
||||||
void moveBefore(BasicBlock *block,
|
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.
|
/// Methods for support type inquiry through isa, cast, and dyn_cast.
|
||||||
static bool classof(const IROperandOwner *ptr) {
|
static bool classof(const IROperandOwner *ptr) {
|
||||||
return ptr->getKind() == IROperandOwner::Kind::OperationInst;
|
return ptr->getKind() == IROperandOwner::Kind::Instruction;
|
||||||
}
|
}
|
||||||
static bool classof(const Operation *op) {
|
static bool classof(const Operation *op) {
|
||||||
return op->getOperationKind() == OperationKind::Instruction;
|
return op->getOperationKind() == OperationKind::Instruction;
|
||||||
|
@ -423,14 +318,21 @@ public:
|
||||||
private:
|
private:
|
||||||
const unsigned numResults, numSuccs;
|
const unsigned numResults, numSuccs;
|
||||||
std::vector<InstOperand> operands;
|
std::vector<InstOperand> operands;
|
||||||
|
BasicBlock *block = nullptr;
|
||||||
|
|
||||||
OperationInst(Location location, OperationName name, unsigned numResults,
|
Instruction(Location location, OperationName name, unsigned numResults,
|
||||||
unsigned numSuccessors, ArrayRef<NamedAttribute> attributes,
|
unsigned numSuccessors, ArrayRef<NamedAttribute> attributes,
|
||||||
MLIRContext *context);
|
MLIRContext *context);
|
||||||
~OperationInst();
|
|
||||||
|
// 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.
|
// This stuff is used by the TrailingObjects template.
|
||||||
friend llvm::TrailingObjects<OperationInst, InstResult, BasicBlockOperand,
|
friend llvm::TrailingObjects<Instruction, InstResult, BasicBlockOperand,
|
||||||
unsigned>;
|
unsigned>;
|
||||||
size_t numTrailingObjects(OverloadToken<InstResult>) const {
|
size_t numTrailingObjects(OverloadToken<InstResult>) const {
|
||||||
return numResults;
|
return numResults;
|
||||||
|
@ -441,6 +343,14 @@ private:
|
||||||
size_t numTrailingObjects(OverloadToken<unsigned>) const { return numSuccs; }
|
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
|
} // end namespace mlir
|
||||||
|
|
||||||
#endif // MLIR_IR_INSTRUCTIONS_H
|
#endif // MLIR_IR_INSTRUCTIONS_H
|
||||||
|
|
|
@ -35,7 +35,7 @@ class Instruction;
|
||||||
class Statement;
|
class Statement;
|
||||||
|
|
||||||
/// Operations represent all of the arithmetic and other basic computation in
|
/// 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.
|
/// and OperationStmt.
|
||||||
///
|
///
|
||||||
class Operation {
|
class Operation {
|
||||||
|
@ -196,7 +196,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The dyn_cast methods perform a dynamic cast from an Operation (like
|
/// 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.
|
/// a null OpPointer on failure.
|
||||||
template <typename OpClass> OpPointer<OpClass> dyn_cast() {
|
template <typename OpClass> OpPointer<OpClass> dyn_cast() {
|
||||||
if (isa<OpClass>()) {
|
if (isa<OpClass>()) {
|
||||||
|
@ -207,7 +207,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The dyn_cast methods perform a dynamic cast from an Operation (like
|
/// 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.
|
/// a null ConstOpPointer on failure.
|
||||||
template <typename OpClass> ConstOpPointer<OpClass> dyn_cast() const {
|
template <typename OpClass> ConstOpPointer<OpClass> dyn_cast() const {
|
||||||
if (isa<OpClass>()) {
|
if (isa<OpClass>()) {
|
||||||
|
@ -218,7 +218,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The cast methods perform a cast from an Operation (like
|
/// 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
|
/// if the parameter to the template isn't an instance of the template type
|
||||||
/// argument.
|
/// argument.
|
||||||
template <typename OpClass> OpPointer<OpClass> cast() {
|
template <typename OpClass> OpPointer<OpClass> cast() {
|
||||||
|
@ -227,7 +227,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The cast methods perform a cast from an Operation (like
|
/// 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
|
/// if the parameter to the template isn't an instance of the template type
|
||||||
/// argument.
|
/// argument.
|
||||||
template <typename OpClass> ConstOpPointer<OpClass> cast() const {
|
template <typename OpClass> ConstOpPointer<OpClass> cast() const {
|
||||||
|
@ -243,7 +243,7 @@ public:
|
||||||
|
|
||||||
enum class OperationKind { Instruction, Statement };
|
enum class OperationKind { Instruction, Statement };
|
||||||
// This is used to implement the dynamic casting logic, but you shouldn't
|
// 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 {
|
OperationKind getOperationKind() const {
|
||||||
return nameAndIsInstruction.getInt() ? OperationKind::Instruction
|
return nameAndIsInstruction.getInt() ? OperationKind::Instruction
|
||||||
: OperationKind::Statement;
|
: OperationKind::Statement;
|
||||||
|
@ -285,7 +285,6 @@ public:
|
||||||
void dump() const;
|
void dump() const;
|
||||||
|
|
||||||
/// Methods for support type inquiry through isa, cast, and dyn_cast.
|
/// 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 Statement *stmt);
|
||||||
static bool classof(const IROperandOwner *ptr);
|
static bool classof(const IROperandOwner *ptr);
|
||||||
|
|
||||||
|
@ -299,7 +298,7 @@ private:
|
||||||
void operator=(const Operation&) = delete;
|
void operator=(const Operation&) = delete;
|
||||||
|
|
||||||
/// This holds the name of the operation, and a bool. The bool is true if
|
/// 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;
|
llvm::PointerIntPair<OperationName, 1, bool> nameAndIsInstruction;
|
||||||
|
|
||||||
/// This holds general named attributes for the operation.
|
/// This holds general named attributes for the operation.
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
|
|
||||||
namespace mlir {
|
namespace mlir {
|
||||||
class Function;
|
class Function;
|
||||||
class OperationInst;
|
class Instruction;
|
||||||
class OperationStmt;
|
class OperationStmt;
|
||||||
class Operation;
|
class Operation;
|
||||||
|
|
||||||
|
@ -67,10 +67,10 @@ public:
|
||||||
return const_cast<SSAValue *>(this)->getFunction();
|
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.
|
/// that defines it.
|
||||||
OperationInst *getDefiningInst();
|
Instruction *getDefiningInst();
|
||||||
const OperationInst *getDefiningInst() const {
|
const Instruction *getDefiningInst() const {
|
||||||
return const_cast<SSAValue *>(this)->getDefiningInst();
|
return const_cast<SSAValue *>(this)->getDefiningInst();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,11 +79,10 @@ public:
|
||||||
OperationStmt,
|
OperationStmt,
|
||||||
ForStmt,
|
ForStmt,
|
||||||
IfStmt,
|
IfStmt,
|
||||||
OperationInst,
|
Instruction,
|
||||||
|
|
||||||
/// These enums define ranges used for classof implementations.
|
/// These enums define ranges used for classof implementations.
|
||||||
STMT_LAST = IfStmt,
|
STMT_LAST = IfStmt,
|
||||||
INST_FIRST = OperationInst,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
Kind getKind() const { return locationAndKind.getInt(); }
|
Kind getKind() const { return locationAndKind.getInt(); }
|
||||||
|
|
|
@ -49,17 +49,15 @@ bool DominanceInfo::properlyDominates(const Instruction *a,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// If one is a terminator, then the other dominates it.
|
// If one is a terminator, then the other dominates it.
|
||||||
auto *aOp = cast<OperationInst>(a);
|
if (a->isTerminator())
|
||||||
if (aOp->isTerminator())
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto *bOp = cast<OperationInst>(b);
|
if (b->isTerminator())
|
||||||
if (bOp->isTerminator())
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// Otherwise, do a linear scan to determine whether B comes after A.
|
// Otherwise, do a linear scan to determine whether B comes after A.
|
||||||
auto aIter = BasicBlock::const_iterator(aOp);
|
auto aIter = BasicBlock::const_iterator(a);
|
||||||
auto bIter = BasicBlock::const_iterator(bOp);
|
auto bIter = BasicBlock::const_iterator(b);
|
||||||
auto fIter = aBlock->begin();
|
auto fIter = aBlock->begin();
|
||||||
while (bIter != fIter) {
|
while (bIter != fIter) {
|
||||||
--bIter;
|
--bIter;
|
||||||
|
|
|
@ -1168,7 +1168,6 @@ public:
|
||||||
void print(const BasicBlock *block);
|
void print(const BasicBlock *block);
|
||||||
|
|
||||||
void print(const Instruction *inst);
|
void print(const Instruction *inst);
|
||||||
void print(const OperationInst *inst);
|
|
||||||
|
|
||||||
void printSuccessorAndUseList(const Operation *term, unsigned index);
|
void printSuccessorAndUseList(const Operation *term, unsigned index);
|
||||||
|
|
||||||
|
@ -1277,13 +1276,6 @@ void CFGFunctionPrinter::print(const Instruction *inst) {
|
||||||
os << "<<null instruction>>\n";
|
os << "<<null instruction>>\n";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
switch (inst->getKind()) {
|
|
||||||
case Instruction::Kind::Operation:
|
|
||||||
return print(cast<OperationInst>(inst));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void CFGFunctionPrinter::print(const OperationInst *inst) {
|
|
||||||
printOperation(inst);
|
printOperation(inst);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -41,101 +41,21 @@ unsigned InstResult::getResultNumber() const {
|
||||||
// Instruction
|
// Instruction
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// Instructions are deleted through the destroy() member because we don't have
|
/// Create a new Instruction with the specified fields.
|
||||||
// a virtual destructor.
|
Instruction *Instruction::create(Location location, OperationName name,
|
||||||
Instruction::~Instruction() {
|
ArrayRef<CFGValue *> operands,
|
||||||
assert(block == nullptr && "instruction destroyed but still in a block");
|
ArrayRef<Type> resultTypes,
|
||||||
}
|
ArrayRef<NamedAttribute> attributes,
|
||||||
|
ArrayRef<BasicBlock *> successors,
|
||||||
/// Destroy this instruction or one of its subclasses.
|
MLIRContext *context) {
|
||||||
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) {
|
|
||||||
unsigned numSuccessors = successors.size();
|
unsigned numSuccessors = successors.size();
|
||||||
auto byteSize = totalSizeToAlloc<InstResult, BasicBlockOperand, unsigned>(
|
auto byteSize = totalSizeToAlloc<InstResult, BasicBlockOperand, unsigned>(
|
||||||
resultTypes.size(), numSuccessors, numSuccessors);
|
resultTypes.size(), numSuccessors, numSuccessors);
|
||||||
void *rawMem = malloc(byteSize);
|
void *rawMem = malloc(byteSize);
|
||||||
|
|
||||||
// Initialize the OperationInst part of the instruction.
|
// Initialize the Instruction part of the instruction.
|
||||||
auto inst = ::new (rawMem) OperationInst(location, name, resultTypes.size(),
|
auto inst = ::new (rawMem) Instruction(location, name, resultTypes.size(),
|
||||||
numSuccessors, attributes, context);
|
numSuccessors, attributes, context);
|
||||||
|
|
||||||
// Initialize the results and operands.
|
// Initialize the results and operands.
|
||||||
auto instResults = inst->getInstResults();
|
auto instResults = inst->getInstResults();
|
||||||
|
@ -193,7 +113,7 @@ OperationInst *OperationInst::create(Location location, OperationName name,
|
||||||
return inst;
|
return inst;
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationInst *OperationInst::clone() const {
|
Instruction *Instruction::clone() const {
|
||||||
SmallVector<CFGValue *, 8> operands;
|
SmallVector<CFGValue *, 8> operands;
|
||||||
SmallVector<Type, 8> resultTypes;
|
SmallVector<Type, 8> resultTypes;
|
||||||
SmallVector<BasicBlock *, 1> successors;
|
SmallVector<BasicBlock *, 1> successors;
|
||||||
|
@ -238,15 +158,17 @@ OperationInst *OperationInst::clone() const {
|
||||||
successors, getContext());
|
successors, getContext());
|
||||||
}
|
}
|
||||||
|
|
||||||
OperationInst::OperationInst(Location location, OperationName name,
|
Instruction::Instruction(Location location, OperationName name,
|
||||||
unsigned numResults, unsigned numSuccessors,
|
unsigned numResults, unsigned numSuccessors,
|
||||||
ArrayRef<NamedAttribute> attributes,
|
ArrayRef<NamedAttribute> attributes,
|
||||||
MLIRContext *context)
|
MLIRContext *context)
|
||||||
: Operation(/*isInstruction=*/true, name, attributes, context),
|
: Operation(/*isInstruction=*/true, name, attributes, context),
|
||||||
Instruction(Kind::Operation, location), numResults(numResults),
|
IROperandOwner(IROperandOwner::Kind::Instruction, location),
|
||||||
numSuccs(numSuccessors) {}
|
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.
|
// Explicitly run the destructors for the results and successors.
|
||||||
for (auto &result : getInstResults())
|
for (auto &result : getInstResults())
|
||||||
result.~InstResult();
|
result.~InstResult();
|
||||||
|
@ -256,7 +178,53 @@ OperationInst::~OperationInst() {
|
||||||
successor.~BasicBlockOperand();
|
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(isTerminator() && "Only terminators have successors.");
|
||||||
assert(index < getNumSuccessors());
|
assert(index < getNumSuccessors());
|
||||||
assert(std::accumulate(getTrailingObjects<unsigned>() + index + 1,
|
assert(std::accumulate(getTrailingObjects<unsigned>() + index + 1,
|
||||||
|
@ -267,47 +235,45 @@ void OperationInst::addSuccessorOperand(unsigned index, CFGValue *value) {
|
||||||
++getTrailingObjects<unsigned>()[index];
|
++getTrailingObjects<unsigned>()[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
void OperationInst::addSuccessorOperands(unsigned index,
|
void Instruction::addSuccessorOperands(unsigned index,
|
||||||
ArrayRef<CFGValue *> values) {
|
ArrayRef<CFGValue *> values) {
|
||||||
operands.reserve(operands.size() + values.size());
|
operands.reserve(operands.size() + values.size());
|
||||||
for (auto *value : values)
|
for (auto *value : values)
|
||||||
addSuccessorOperand(index, value);
|
addSuccessorOperand(index, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
void llvm::ilist_traits<::mlir::OperationInst>::deleteNode(
|
void llvm::ilist_traits<::mlir::Instruction>::deleteNode(Instruction *inst) {
|
||||||
OperationInst *inst) {
|
|
||||||
inst->destroy();
|
inst->destroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
mlir::BasicBlock *
|
mlir::BasicBlock *
|
||||||
llvm::ilist_traits<::mlir::OperationInst>::getContainingBlock() {
|
llvm::ilist_traits<::mlir::Instruction>::getContainingBlock() {
|
||||||
size_t Offset(
|
size_t Offset(
|
||||||
size_t(&((BasicBlock *)nullptr->*BasicBlock::getSublistAccess(nullptr))));
|
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) -
|
return reinterpret_cast<BasicBlock *>(reinterpret_cast<char *>(Anchor) -
|
||||||
Offset);
|
Offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a trait method invoked when an instruction is added to a block. We
|
/// This is a trait method invoked when an instruction is added to a block. We
|
||||||
/// keep the block pointer up to date.
|
/// keep the block pointer up to date.
|
||||||
void llvm::ilist_traits<::mlir::OperationInst>::addNodeToList(
|
void llvm::ilist_traits<::mlir::Instruction>::addNodeToList(Instruction *inst) {
|
||||||
OperationInst *inst) {
|
|
||||||
assert(!inst->getBlock() && "already in a basic block!");
|
assert(!inst->getBlock() && "already in a basic block!");
|
||||||
inst->block = getContainingBlock();
|
inst->block = getContainingBlock();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a trait method invoked when an instruction is removed from a block.
|
/// This is a trait method invoked when an instruction is removed from a block.
|
||||||
/// We keep the block pointer up to date.
|
/// We keep the block pointer up to date.
|
||||||
void llvm::ilist_traits<::mlir::OperationInst>::removeNodeFromList(
|
void llvm::ilist_traits<::mlir::Instruction>::removeNodeFromList(
|
||||||
OperationInst *inst) {
|
Instruction *inst) {
|
||||||
assert(inst->block && "not already in a basic block!");
|
assert(inst->block && "not already in a basic block!");
|
||||||
inst->block = nullptr;
|
inst->block = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This is a trait method invoked when an instruction is moved from one block
|
/// This is a trait method invoked when an instruction is moved from one block
|
||||||
/// to another. We keep the block pointer up to date.
|
/// to another. We keep the block pointer up to date.
|
||||||
void llvm::ilist_traits<::mlir::OperationInst>::transferNodesFromList(
|
void llvm::ilist_traits<::mlir::Instruction>::transferNodesFromList(
|
||||||
ilist_traits<OperationInst> &otherList, instr_iterator first,
|
ilist_traits<Instruction> &otherList, instr_iterator first,
|
||||||
instr_iterator last) {
|
instr_iterator last) {
|
||||||
// If we are transferring instructions within the same basic block, the block
|
// If we are transferring instructions within the same basic block, the block
|
||||||
// pointer doesn't need to be updated.
|
// 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.
|
/// Unlink this instruction from its BasicBlock and delete it.
|
||||||
void OperationInst::erase() {
|
void Instruction::erase() {
|
||||||
assert(getBlock() && "Instruction has no parent");
|
assert(getBlock() && "Instruction has no parent");
|
||||||
getBlock()->getOperations().erase(this);
|
getBlock()->getOperations().erase(this);
|
||||||
}
|
}
|
||||||
|
@ -329,15 +295,15 @@ void OperationInst::erase() {
|
||||||
/// Unlink this operation instruction from its current basic block and insert
|
/// Unlink this operation instruction from its current basic block and insert
|
||||||
/// it right before `existingInst` which may be in the same or another block
|
/// it right before `existingInst` which may be in the same or another block
|
||||||
/// in the same function.
|
/// in the same function.
|
||||||
void OperationInst::moveBefore(OperationInst *existingInst) {
|
void Instruction::moveBefore(Instruction *existingInst) {
|
||||||
assert(existingInst && "Cannot move before a null instruction");
|
assert(existingInst && "Cannot move before a null instruction");
|
||||||
return moveBefore(existingInst->getBlock(), existingInst->getIterator());
|
return moveBefore(existingInst->getBlock(), existingInst->getIterator());
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Unlink this operation instruction from its current basic block and insert
|
/// Unlink this operation instruction from its current basic block and insert
|
||||||
/// it right before `iterator` in the specified basic block.
|
/// it right before `iterator` in the specified basic block.
|
||||||
void OperationInst::moveBefore(BasicBlock *block,
|
void Instruction::moveBefore(BasicBlock *block,
|
||||||
llvm::iplist<OperationInst>::iterator iterator) {
|
llvm::iplist<Instruction>::iterator iterator) {
|
||||||
block->getOperations().splice(iterator, getBlock()->getOperations(),
|
block->getOperations().splice(iterator, getBlock()->getOperations(),
|
||||||
getIterator());
|
getIterator());
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ Operation::~Operation() {}
|
||||||
|
|
||||||
/// Return the context this operation is associated with.
|
/// Return the context this operation is associated with.
|
||||||
MLIRContext *Operation::getContext() const {
|
MLIRContext *Operation::getContext() const {
|
||||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||||
return inst->getContext();
|
return inst->getContext();
|
||||||
return llvm::cast<OperationStmt>(this)->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
|
/// The source location the operation was defined or derived from. Note that
|
||||||
/// it is possible for this pointer to be null.
|
/// it is possible for this pointer to be null.
|
||||||
Location Operation::getLoc() const {
|
Location Operation::getLoc() const {
|
||||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||||
return inst->getLoc();
|
return inst->getLoc();
|
||||||
return llvm::cast<OperationStmt>(this)->getLoc();
|
return llvm::cast<OperationStmt>(this)->getLoc();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the function this operation is defined in.
|
/// Return the function this operation is defined in.
|
||||||
Function *Operation::getOperationFunction() {
|
Function *Operation::getOperationFunction() {
|
||||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||||
return inst->getFunction();
|
return inst->getFunction();
|
||||||
return llvm::cast<OperationStmt>(this)->findFunction();
|
return llvm::cast<OperationStmt>(this)->findFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Return the number of operands this operation has.
|
/// Return the number of operands this operation has.
|
||||||
unsigned Operation::getNumOperands() const {
|
unsigned Operation::getNumOperands() const {
|
||||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||||
return inst->getNumOperands();
|
return inst->getNumOperands();
|
||||||
|
|
||||||
return llvm::cast<OperationStmt>(this)->getNumOperands();
|
return llvm::cast<OperationStmt>(this)->getNumOperands();
|
||||||
}
|
}
|
||||||
|
|
||||||
SSAValue *Operation::getOperand(unsigned idx) {
|
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 inst->getOperand(idx);
|
||||||
|
|
||||||
return llvm::cast<OperationStmt>(this)->getOperand(idx);
|
return llvm::cast<OperationStmt>(this)->getOperand(idx);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Operation::setOperand(unsigned idx, SSAValue *value) {
|
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));
|
inst->setOperand(idx, llvm::cast<CFGValue>(value));
|
||||||
} else {
|
} else {
|
||||||
auto *stmt = llvm::cast<OperationStmt>(this);
|
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.
|
/// Return the number of results this operation has.
|
||||||
unsigned Operation::getNumResults() const {
|
unsigned Operation::getNumResults() const {
|
||||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||||
return inst->getNumResults();
|
return inst->getNumResults();
|
||||||
|
|
||||||
return llvm::cast<OperationStmt>(this)->getNumResults();
|
return llvm::cast<OperationStmt>(this)->getNumResults();
|
||||||
|
@ -128,7 +128,7 @@ unsigned Operation::getNumResults() const {
|
||||||
|
|
||||||
/// Return the indicated result.
|
/// Return the indicated result.
|
||||||
SSAValue *Operation::getResult(unsigned idx) {
|
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 inst->getResult(idx);
|
||||||
|
|
||||||
return llvm::cast<OperationStmt>(this)->getResult(idx);
|
return llvm::cast<OperationStmt>(this)->getResult(idx);
|
||||||
|
@ -136,8 +136,8 @@ SSAValue *Operation::getResult(unsigned idx) {
|
||||||
|
|
||||||
unsigned Operation::getNumSuccessors() const {
|
unsigned Operation::getNumSuccessors() const {
|
||||||
assert(isTerminator() && "Only terminators have successors.");
|
assert(isTerminator() && "Only terminators have successors.");
|
||||||
if (llvm::isa<OperationInst>(this))
|
if (llvm::isa<Instruction>(this))
|
||||||
return llvm::cast<OperationInst>(this)->getNumSuccessors();
|
return llvm::cast<Instruction>(this)->getNumSuccessors();
|
||||||
|
|
||||||
// OperationStmt currently only has a return terminator.
|
// OperationStmt currently only has a return terminator.
|
||||||
assert(llvm::cast<OperationStmt>(this)->isReturn() &&
|
assert(llvm::cast<OperationStmt>(this)->isReturn() &&
|
||||||
|
@ -147,36 +147,33 @@ unsigned Operation::getNumSuccessors() const {
|
||||||
|
|
||||||
unsigned Operation::getNumSuccessorOperands(unsigned index) const {
|
unsigned Operation::getNumSuccessorOperands(unsigned index) const {
|
||||||
assert(isTerminator() && "Only terminators have successors.");
|
assert(isTerminator() && "Only terminators have successors.");
|
||||||
assert(llvm::isa<OperationInst>(this) &&
|
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||||
"Only instructions have successors.");
|
return llvm::cast<Instruction>(this)->getNumSuccessorOperands(index);
|
||||||
return llvm::cast<OperationInst>(this)->getNumSuccessorOperands(index);
|
|
||||||
}
|
}
|
||||||
BasicBlock *Operation::getSuccessor(unsigned index) {
|
BasicBlock *Operation::getSuccessor(unsigned index) {
|
||||||
assert(isTerminator() && "Only terminators have successors.");
|
assert(isTerminator() && "Only terminators have successors.");
|
||||||
assert(llvm::isa<OperationInst>(this) &&
|
assert(llvm::isa<Instruction>(this) &&
|
||||||
"Only instructions have basic block successors.");
|
"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) {
|
void Operation::setSuccessor(BasicBlock *block, unsigned index) {
|
||||||
assert(isTerminator() && "Only terminators have successors.");
|
assert(isTerminator() && "Only terminators have successors.");
|
||||||
assert(llvm::isa<OperationInst>(this) &&
|
assert(llvm::isa<Instruction>(this) &&
|
||||||
"Only instructions have basic block successors.");
|
"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) {
|
void Operation::addSuccessorOperand(unsigned index, SSAValue *value) {
|
||||||
assert(isTerminator() && "Only terminators have successors.");
|
assert(isTerminator() && "Only terminators have successors.");
|
||||||
assert(llvm::isa<OperationInst>(this) &&
|
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||||
"Only instructions have successors.");
|
return llvm::cast<Instruction>(this)->addSuccessorOperand(
|
||||||
return llvm::cast<OperationInst>(this)->addSuccessorOperand(
|
|
||||||
index, llvm::cast<CFGValue>(value));
|
index, llvm::cast<CFGValue>(value));
|
||||||
}
|
}
|
||||||
auto Operation::getSuccessorOperands(unsigned index) const
|
auto Operation::getSuccessorOperands(unsigned index) const
|
||||||
-> llvm::iterator_range<const_operand_iterator> {
|
-> llvm::iterator_range<const_operand_iterator> {
|
||||||
assert(isTerminator() && "Only terminators have successors.");
|
assert(isTerminator() && "Only terminators have successors.");
|
||||||
assert(llvm::isa<OperationInst>(this) &&
|
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||||
"Only instructions have successors.");
|
|
||||||
unsigned succOperandIndex =
|
unsigned succOperandIndex =
|
||||||
llvm::cast<OperationInst>(this)->getSuccessorOperandIndex(index);
|
llvm::cast<Instruction>(this)->getSuccessorOperandIndex(index);
|
||||||
return {const_operand_iterator(this, succOperandIndex),
|
return {const_operand_iterator(this, succOperandIndex),
|
||||||
const_operand_iterator(this, succOperandIndex +
|
const_operand_iterator(this, succOperandIndex +
|
||||||
getNumSuccessorOperands(index))};
|
getNumSuccessorOperands(index))};
|
||||||
|
@ -184,10 +181,9 @@ auto Operation::getSuccessorOperands(unsigned index) const
|
||||||
auto Operation::getSuccessorOperands(unsigned index)
|
auto Operation::getSuccessorOperands(unsigned index)
|
||||||
-> llvm::iterator_range<operand_iterator> {
|
-> llvm::iterator_range<operand_iterator> {
|
||||||
assert(isTerminator() && "Only terminators have successors.");
|
assert(isTerminator() && "Only terminators have successors.");
|
||||||
assert(llvm::isa<OperationInst>(this) &&
|
assert(llvm::isa<Instruction>(this) && "Only instructions have successors.");
|
||||||
"Only instructions have successors.");
|
|
||||||
unsigned succOperandIndex =
|
unsigned succOperandIndex =
|
||||||
llvm::cast<OperationInst>(this)->getSuccessorOperandIndex(index);
|
llvm::cast<Instruction>(this)->getSuccessorOperandIndex(index);
|
||||||
return {operand_iterator(this, succOperandIndex),
|
return {operand_iterator(this, succOperandIndex),
|
||||||
operand_iterator(this,
|
operand_iterator(this,
|
||||||
succOperandIndex + getNumSuccessorOperands(index))};
|
succOperandIndex + getNumSuccessorOperands(index))};
|
||||||
|
@ -278,7 +274,7 @@ bool Operation::emitOpError(const Twine &message) const {
|
||||||
|
|
||||||
/// Remove this operation from its parent block and delete it.
|
/// Remove this operation from its parent block and delete it.
|
||||||
void Operation::erase() {
|
void Operation::erase() {
|
||||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||||
return inst->erase();
|
return inst->erase();
|
||||||
return llvm::cast<OperationStmt>(this)->erase();
|
return llvm::cast<OperationStmt>(this)->erase();
|
||||||
}
|
}
|
||||||
|
@ -302,26 +298,23 @@ bool Operation::constantFold(ArrayRef<Attribute> operands,
|
||||||
}
|
}
|
||||||
|
|
||||||
void Operation::print(raw_ostream &os) const {
|
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 inst->print(os);
|
||||||
return llvm::cast<OperationStmt>(this)->print(os);
|
return llvm::cast<OperationStmt>(this)->print(os);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Operation::dump() const {
|
void Operation::dump() const {
|
||||||
if (auto *inst = llvm::dyn_cast<OperationInst>(this))
|
if (auto *inst = llvm::dyn_cast<Instruction>(this))
|
||||||
return inst->dump();
|
return inst->dump();
|
||||||
return llvm::cast<OperationStmt>(this)->dump();
|
return llvm::cast<OperationStmt>(this)->dump();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Methods for support type inquiry through isa, cast, and dyn_cast.
|
/// 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) {
|
bool Operation::classof(const Statement *stmt) {
|
||||||
return stmt->getKind() == Statement::Kind::Operation;
|
return stmt->getKind() == Statement::Kind::Operation;
|
||||||
}
|
}
|
||||||
bool Operation::classof(const IROperandOwner *ptr) {
|
bool Operation::classof(const IROperandOwner *ptr) {
|
||||||
return ptr->getKind() == IROperandOwner::Kind::OperationInst ||
|
return ptr->getKind() == IROperandOwner::Kind::Instruction ||
|
||||||
ptr->getKind() == IROperandOwner::Kind::OperationStmt;
|
ptr->getKind() == IROperandOwner::Kind::OperationStmt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -337,7 +330,7 @@ llvm::cast_convert_val<mlir::Operation, mlir::IROperandOwner *,
|
||||||
if (auto *ptr = dyn_cast<OperationStmt>(value))
|
if (auto *ptr = dyn_cast<OperationStmt>(value))
|
||||||
op = ptr;
|
op = ptr;
|
||||||
else
|
else
|
||||||
op = cast<OperationInst>(value);
|
op = cast<Instruction>(value);
|
||||||
return const_cast<Operation *>(op);
|
return const_cast<Operation *>(op);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,7 +533,7 @@ bool OpTrait::impl::verifyIsTerminator(const Operation *op) {
|
||||||
if (!block || !isa<MLFunction>(block) || &block->back() != stmt)
|
if (!block || !isa<MLFunction>(block) || &block->back() != stmt)
|
||||||
return op->emitOpError("must be the last statement in the ML function");
|
return op->emitOpError("must be the last statement in the ML function");
|
||||||
} else {
|
} else {
|
||||||
const OperationInst *inst = cast<OperationInst>(op);
|
const Instruction *inst = cast<Instruction>(op);
|
||||||
const BasicBlock *block = inst->getBlock();
|
const BasicBlock *block = inst->getBlock();
|
||||||
if (!block || &block->back() != inst)
|
if (!block || &block->back() != inst)
|
||||||
return op->emitOpError(
|
return op->emitOpError(
|
||||||
|
|
|
@ -23,9 +23,9 @@
|
||||||
|
|
||||||
using namespace mlir;
|
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.
|
/// that defines it.
|
||||||
OperationInst *SSAValue::getDefiningInst() {
|
Instruction *SSAValue::getDefiningInst() {
|
||||||
if (auto *result = dyn_cast<InstResult>(this))
|
if (auto *result = dyn_cast<InstResult>(this))
|
||||||
return result->getOwner();
|
return result->getOwner();
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
@ -77,7 +77,7 @@ MLIRContext *IROperandOwner::getContext() const {
|
||||||
case Kind::IfStmt:
|
case Kind::IfStmt:
|
||||||
return cast<IfStmt>(this)->getContext();
|
return cast<IfStmt>(this)->getContext();
|
||||||
|
|
||||||
case Kind::OperationInst:
|
case Kind::Instruction:
|
||||||
// If we have an instruction, we can efficiently get this from the function
|
// If we have an instruction, we can efficiently get this from the function
|
||||||
// the instruction is in.
|
// the instruction is in.
|
||||||
auto *fn = cast<Instruction>(this)->getFunction();
|
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
|
// cannot be created through normal user input, allowing us to distinguish
|
||||||
// them.
|
// them.
|
||||||
auto name = OperationName("placeholder", getContext());
|
auto name = OperationName("placeholder", getContext());
|
||||||
auto *inst = OperationInst::create(getEncodedSourceLocation(loc), name,
|
auto *inst = Instruction::create(getEncodedSourceLocation(loc), name,
|
||||||
/*operands=*/{}, type,
|
/*operands=*/{}, type,
|
||||||
/*attributes=*/{},
|
/*attributes=*/{},
|
||||||
/*successors=*/{}, getContext());
|
/*successors=*/{}, getContext());
|
||||||
forwardReferencePlaceholders[inst->getResult(0)] = loc;
|
forwardReferencePlaceholders[inst->getResult(0)] = loc;
|
||||||
return inst->getResult(0);
|
return inst->getResult(0);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue