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
/// 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<uint8_t, 20> hash;
+};
+
} // namespace mlir
namespace llvm {
#include "mlir/IR/BuiltinTypes.h"
#include "mlir/IR/OpDefinition.h"
#include "llvm/ADT/BitVector.h"
+#include "llvm/Support/SHA1.h"
#include <numeric>
using namespace mlir;
return false;
return true;
}
+
+//===----------------------------------------------------------------------===//
+// OperationFingerPrint
+//===----------------------------------------------------------------------===//
+
+template <typename T>
+static void addDataToHash(llvm::SHA1 &hasher, const T &data) {
+ hasher.update(
+ ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&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();
+}
#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 <typename T>
- void addDataToHash(llvm::SHA1 &hasher, const T &data) {
- hasher.update(
- ArrayRef<uint8_t>(reinterpret_cast<const uint8_t *>(&data), sizeof(T)));
- }
-
- std::array<uint8_t, 20> hash;
-};
-
-//===----------------------------------------------------------------------===//
// IRPrinter
//===----------------------------------------------------------------------===//