#include <optional>
namespace mlir {
-class IRListeners {
-public:
- class ListenerInterface {
- public:
- ~ListenerInterface() = default;
- virtual void notifyOpInserted(Operation *op, Block *oldBlock, Block *newBlock);
- virtual void notifyOpDestroyed(Operation *op);
- };
- void notifyOpInserted(Operation *op, Block *oldBlock, Block *newBlock) {
- for (auto &listener : listeners)
- listener.notifyOpInserted(op, oldBlock, newBlock);
- }
- void notifyOpDestroyed(Operation *op) {
- for (auto &listener : listeners)
- listener.notifyOpDestroyed(op);
- }
- void addListener(std::shared_ptr<ListenerInterface> listener) {
- listeners.push_back(std::move(listener));
- }
- private:
- std::vector<std::shared_ptr<ListenerInterface>> listeners;
-};
-
-
/// Operation is the basic unit of execution within MLIR.
///
/// The following documentation are recommended to understand this class:
/// Returns true if this operation has a valid order.
bool hasValidOrder() { return orderIndex != kInvalidOrderIdx; }
- /// Attach a listener to this operation.
- void addListener(std::shared_ptr<ListenerInterface> listener) {
- if (!listeners) listeners = std::make_unique<IRListeners>();
- listeners->addListener(std::move(listener));
- }
-
private:
Operation(Location location, OperationName name, unsigned numResults,
unsigned numSuccessors, unsigned numRegions,
// Operations are deleted through the destroy() member because they are
// allocated with malloc.
~Operation();
-g
+
/// Returns the additional size necessary for allocating the given objects
/// before an Operation in-memory.
static size_t prefixAllocSize(unsigned numOutOfLineResults,
/// This holds general named attributes for the operation.
DictionaryAttr attrs;
- /// Optionally defined listeners that register here to capture IR modification events.
- std::unique_ptr<IRListeners> listeners;
-
// allow ilist_traits access to 'block' field.
friend struct llvm::ilist_traits<Operation>;
/// Destroy this operation or one of its subclasses.
void Operation::destroy() {
- if (listeners) listeners->notifyOpDestroyed(this);
// Operations may have additional prefixed allocation, which needs to be
// accounted for here when computing the address to free.
char *rawMem = reinterpret_cast<char *>(this) -
/// keep the block pointer up to date.
void llvm::ilist_traits<::mlir::Operation>::addNodeToList(Operation *op) {
assert(!op->getBlock() && "already in an operation block!");
- auto oldBlock = op->block;
op->block = getContainingBlock();
- if (listeners) listeners->notifyOpInserted(op, oldBlock, newBlock);
+
// Invalidate the order on the operation.
op->orderIndex = Operation::kInvalidOrderIdx;
}
/// We keep the block pointer up to date.
void llvm::ilist_traits<::mlir::Operation>::removeNodeFromList(Operation *op) {
assert(op->block && "not already in an operation block!");
- if (listeners) listeners->notifyOpRemoved(op);
op->block = nullptr;
}