From 2e36dadbd6eab10641ac53969ae3dee0b0391e25 Mon Sep 17 00:00:00 2001 From: Ivan Butygin Date: Mon, 31 Oct 2022 14:16:03 +0100 Subject: [PATCH] [mlir] Make `OperationFingerPrint` class public It can be useful to external users as well for detecting if there were any changes in IR between passes. Differential Revision: https://reviews.llvm.org/D137078 --- mlir/include/mlir/IR/OperationSupport.h | 23 ++++++++++++++ mlir/lib/IR/OperationSupport.cpp | 40 ++++++++++++++++++++++++ mlir/lib/Pass/IRPrinting.cpp | 55 --------------------------------- 3 files changed, 63 insertions(+), 55 deletions(-) diff --git a/mlir/include/mlir/IR/OperationSupport.h b/mlir/include/mlir/IR/OperationSupport.h index 3ce7ff3..24732dec 100644 --- a/mlir/include/mlir/IR/OperationSupport.h +++ b/mlir/include/mlir/IR/OperationSupport.h @@ -894,6 +894,29 @@ struct OperationEquivalence { /// 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 index 33828a9..d46f1b4 100644 --- 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 @@ bool OperationEquivalence::isEquivalentTo( 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 index c20d9b1..ee52bf8 100644 --- a/mlir/lib/Pass/IRPrinting.cpp +++ b/mlir/lib/Pass/IRPrinting.cpp @@ -11,67 +11,12 @@ #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 //===----------------------------------------------------------------------===// -- 2.7.4