diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h --- a/mlir/include/mlir/IR/OperationSupport.h +++ b/mlir/include/mlir/IR/OperationSupport.h @@ -894,6 +894,29 @@ /// Enable Bitmask enums for OperationEquivalence::Flags. LLVM_ENABLE_BITMASK_ENUMS_IN_NAMESPACE(); +//===----------------------------------------------------------------------===// +// OperationFingerPrint +//===----------------------------------------------------------------------===// + +/// A unique fingerprint for a specific operation, and all of it's internal +/// operations. +class OperationFingerPrint { +public: + OperationFingerPrint(Operation *topOp); + OperationFingerPrint(const OperationFingerPrint &) = default; + OperationFingerPrint &operator=(const OperationFingerPrint &) = default; + + bool operator==(const OperationFingerPrint &other) const { + return hash == other.hash; + } + bool operator!=(const OperationFingerPrint &other) const { + return !(*this == other); + } + +private: + std::array hash; +}; + } // namespace mlir namespace llvm { diff --git a/mlir/lib/IR/OperationSupport.cpp b/mlir/lib/IR/OperationSupport.cpp --- a/mlir/lib/IR/OperationSupport.cpp +++ b/mlir/lib/IR/OperationSupport.cpp @@ -16,6 +16,7 @@ #include "mlir/IR/BuiltinTypes.h" #include "mlir/IR/OpDefinition.h" #include "llvm/ADT/BitVector.h" +#include "llvm/Support/SHA1.h" #include using namespace mlir; @@ -757,3 +758,42 @@ return false; return true; } + +//===----------------------------------------------------------------------===// +// OperationFingerPrint +//===----------------------------------------------------------------------===// + +template +static void addDataToHash(llvm::SHA1 &hasher, const T &data) { + hasher.update( + ArrayRef(reinterpret_cast(&data), sizeof(T))); +} + +OperationFingerPrint::OperationFingerPrint(Operation *topOp) { + llvm::SHA1 hasher; + + // Hash each of the operations based upon their mutable bits: + topOp->walk([&](Operation *op) { + // - Operation pointer + addDataToHash(hasher, op); + // - Attributes + addDataToHash(hasher, op->getAttrDictionary()); + // - Blocks in Regions + for (Region ®ion : op->getRegions()) { + for (Block &block : region) { + addDataToHash(hasher, &block); + for (BlockArgument arg : block.getArguments()) + addDataToHash(hasher, arg); + } + } + // - Location + addDataToHash(hasher, op->getLoc().getAsOpaquePointer()); + // - Operands + for (Value operand : op->getOperands()) + addDataToHash(hasher, operand); + // - Successors + for (unsigned i = 0, e = op->getNumSuccessors(); i != e; ++i) + addDataToHash(hasher, op->getSuccessor(i)); + }); + hash = hasher.result(); +} diff --git a/mlir/lib/Pass/IRPrinting.cpp b/mlir/lib/Pass/IRPrinting.cpp --- a/mlir/lib/Pass/IRPrinting.cpp +++ b/mlir/lib/Pass/IRPrinting.cpp @@ -11,66 +11,11 @@ #include "mlir/Pass/PassManager.h" #include "llvm/Support/Format.h" #include "llvm/Support/FormatVariadic.h" -#include "llvm/Support/SHA1.h" using namespace mlir; using namespace mlir::detail; namespace { -//===----------------------------------------------------------------------===// -// OperationFingerPrint -//===----------------------------------------------------------------------===// - -/// A unique fingerprint for a specific operation, and all of it's internal -/// operations. -class OperationFingerPrint { -public: - OperationFingerPrint(Operation *topOp) { - llvm::SHA1 hasher; - - // Hash each of the operations based upon their mutable bits: - topOp->walk([&](Operation *op) { - // - Operation pointer - addDataToHash(hasher, op); - // - Attributes - addDataToHash(hasher, op->getAttrDictionary()); - // - Blocks in Regions - for (Region ®ion : op->getRegions()) { - for (Block &block : region) { - addDataToHash(hasher, &block); - for (BlockArgument arg : block.getArguments()) - addDataToHash(hasher, arg); - } - } - // - Location - addDataToHash(hasher, op->getLoc().getAsOpaquePointer()); - // - Operands - for (Value operand : op->getOperands()) - addDataToHash(hasher, operand); - // - Successors - for (unsigned i = 0, e = op->getNumSuccessors(); i != e; ++i) - addDataToHash(hasher, op->getSuccessor(i)); - }); - hash = hasher.result(); - } - - bool operator==(const OperationFingerPrint &other) const { - return hash == other.hash; - } - bool operator!=(const OperationFingerPrint &other) const { - return !(*this == other); - } - -private: - template - void addDataToHash(llvm::SHA1 &hasher, const T &data) { - hasher.update( - ArrayRef(reinterpret_cast(&data), sizeof(T))); - } - - std::array hash; -}; - //===----------------------------------------------------------------------===// // IRPrinter //===----------------------------------------------------------------------===//