[llvm] 3a42b1f - [IR] Add SturcturalHash printer pass

Aiden Grossman via llvm-commits llvm-commits at lists.llvm.org
Tue Aug 29 19:01:11 PDT 2023


Author: Aiden Grossman
Date: 2023-08-29T18:59:52-07:00
New Revision: 3a42b1fd3eeca542d683e0e39bd3ddef9948242a

URL: https://github.com/llvm/llvm-project/commit/3a42b1fd3eeca542d683e0e39bd3ddef9948242a
DIFF: https://github.com/llvm/llvm-project/commit/3a42b1fd3eeca542d683e0e39bd3ddef9948242a.diff

LOG: [IR] Add SturcturalHash printer pass

This patch adds in a StructuralHash printer pass that prints out the
hexadeicmal representation of the hash of a module and all of the
functions within it.

Reviewed By: aeubanks

Differential Revision: https://reviews.llvm.org/D158317

Added: 
    llvm/include/llvm/Analysis/StructuralHash.h
    llvm/lib/Analysis/StructuralHash.cpp
    llvm/test/Analysis/StructuralHash/structural-hash-detailed.ll
    llvm/test/Analysis/StructuralHash/structural-hash-printer.ll

Modified: 
    llvm/lib/Analysis/CMakeLists.txt
    llvm/lib/Passes/PassBuilder.cpp
    llvm/lib/Passes/PassRegistry.def

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/Analysis/StructuralHash.h b/llvm/include/llvm/Analysis/StructuralHash.h
new file mode 100644
index 00000000000000..0eef17d637c8f8
--- /dev/null
+++ b/llvm/include/llvm/Analysis/StructuralHash.h
@@ -0,0 +1,31 @@
+//=- StructuralHash.h - Structural Hash Printing --*- C++ -*-----------------=//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_ANALYSIS_STRUCTURALHASH_H
+#define LLVM_ANALYSIS_STRUCTURALHASH_H
+
+#include "llvm/IR/PassManager.h"
+
+namespace llvm {
+
+/// Printer pass for  StructuralHashes
+class StructuralHashPrinterPass
+    : public PassInfoMixin<StructuralHashPrinterPass> {
+  raw_ostream &OS;
+  bool EnableDetailedStructuralHash;
+
+public:
+  explicit StructuralHashPrinterPass(raw_ostream &OS, bool Detailed)
+      : OS(OS), EnableDetailedStructuralHash(Detailed) {}
+
+  PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
+};
+
+} // namespace llvm
+
+#endif // LLVM_ANALYSIS_STRUCTURALHASH_H

diff  --git a/llvm/lib/Analysis/CMakeLists.txt b/llvm/lib/Analysis/CMakeLists.txt
index 4a1797c42789a0..9d8c9cfda66c92 100644
--- a/llvm/lib/Analysis/CMakeLists.txt
+++ b/llvm/lib/Analysis/CMakeLists.txt
@@ -124,6 +124,7 @@ add_llvm_component_library(LLVMAnalysis
   ScalarEvolutionNormalization.cpp
   StackLifetime.cpp
   StackSafetyAnalysis.cpp
+  StructuralHash.cpp
   SyntheticCountsUtils.cpp
   TFLiteUtils.cpp
   TargetLibraryInfo.cpp

diff  --git a/llvm/lib/Analysis/StructuralHash.cpp b/llvm/lib/Analysis/StructuralHash.cpp
new file mode 100644
index 00000000000000..244ed5d55f3f81
--- /dev/null
+++ b/llvm/lib/Analysis/StructuralHash.cpp
@@ -0,0 +1,33 @@
+//===- StructuralHash.cpp - Function Hash Printing ------------------------===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the StructuralHashPrinterPass which is used to show
+// the structural hash of all functions in a module and the module itself.
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Analysis/StructuralHash.h"
+#include "llvm/IR/StructuralHash.h"
+#include "llvm/Support/CommandLine.h"
+
+using namespace llvm;
+
+PreservedAnalyses StructuralHashPrinterPass::run(Module &M,
+                                                 ModuleAnalysisManager &MAM) {
+  OS << "Module Hash: "
+     << Twine::utohexstr(StructuralHash(M, EnableDetailedStructuralHash))
+     << "\n";
+  for (Function &F : M) {
+    if (F.isDeclaration())
+      continue;
+    OS << "Function " << F.getName() << " Hash: "
+       << Twine::utohexstr(StructuralHash(F, EnableDetailedStructuralHash))
+       << "\n";
+  }
+  return PreservedAnalyses::all();
+}

diff  --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp
index 2b46a82c769a96..1fdeb13706ca6a 100644
--- a/llvm/lib/Passes/PassBuilder.cpp
+++ b/llvm/lib/Passes/PassBuilder.cpp
@@ -67,6 +67,7 @@
 #include "llvm/Analysis/ScopedNoAliasAA.h"
 #include "llvm/Analysis/StackLifetime.h"
 #include "llvm/Analysis/StackSafetyAnalysis.h"
+#include "llvm/Analysis/StructuralHash.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
 #include "llvm/Analysis/TargetTransformInfo.h"
 #include "llvm/Analysis/TypeBasedAliasAnalysis.h"
@@ -1093,6 +1094,11 @@ Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
   return Result;
 }
 
+Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) {
+  return parseSinglePassOption(Params, "detailed",
+                               "StructuralHashPrinterPass");
+}
+
 } // namespace
 
 /// Tests whether a pass name starts with a valid prefix for a default pipeline

diff  --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def
index 63704d2d1b0c1a..adfbce53f56f18 100644
--- a/llvm/lib/Passes/PassRegistry.def
+++ b/llvm/lib/Passes/PassRegistry.def
@@ -191,6 +191,15 @@ MODULE_PASS_WITH_PARAMS("memprof-use",
                         },
                         parseMemProfUsePassOptions,
                         "profile-filename=S")
+MODULE_PASS_WITH_PARAMS("print<structural-hash>",
+                        "StructuralHashPrinterPass",
+                        [](bool EnableDetailedStructuralHash) {
+                          return StructuralHashPrinterPass(
+                              dbgs(),
+                              EnableDetailedStructuralHash);
+                        },
+                        parseStructuralHashPrinterPassOptions,
+                        "detailed")
 #undef MODULE_PASS_WITH_PARAMS
 
 #ifndef CGSCC_ANALYSIS

diff  --git a/llvm/test/Analysis/StructuralHash/structural-hash-detailed.ll b/llvm/test/Analysis/StructuralHash/structural-hash-detailed.ll
new file mode 100644
index 00000000000000..153fd4c5cd4a64
--- /dev/null
+++ b/llvm/test/Analysis/StructuralHash/structural-hash-detailed.ll
@@ -0,0 +1,16 @@
+; Require 64 bits here as the hash will change depending upon whether we are on a 32-bit
+; or 64-bit platform.
+; REQUIRE: llvm-64-bits
+
+; RUN: opt -passes='print<structural-hash><detailed>' -disable-output %s 2>&1 | FileCheck %s
+
+define i64 @f1(i64 %a) {
+	ret i64 %a
+}
+
+; These values here are explicitly defined to ensure that they are deterministic
+; on all 64-bit platforms and across runs.
+
+; CHECK: Module Hash: 81f1328ced269bd
+; CHECK: Function f1 Hash: 81f1328ced269bd
+

diff  --git a/llvm/test/Analysis/StructuralHash/structural-hash-printer.ll b/llvm/test/Analysis/StructuralHash/structural-hash-printer.ll
new file mode 100644
index 00000000000000..569abae5567f70
--- /dev/null
+++ b/llvm/test/Analysis/StructuralHash/structural-hash-printer.ll
@@ -0,0 +1,25 @@
+; RUN: opt -passes='print<structural-hash>' -disable-output %s 2>&1 | FileCheck %s
+; RUN: opt -passes='print<structural-hash><detailed>' -disable-output %s 2>&1 | FileCheck %s -check-prefix=DETAILED-HASH
+
+; Add a declaration so that we can test we skip it.
+declare i64 @d1()
+
+define i64 @f1(i64 %a) {
+	%b = add i64 %a, 1
+	ret i64 %b
+}
+
+define i32 @f2(i32 %a) {
+	%b = add i32 %a, 2
+	ret i32 %b
+}
+
+; CHECK: Module Hash: {{([a-z0-9]{14,})}}
+; CHECK-NEXT: Function f1 Hash: [[F1H:([a-z0-9]{14,})]]
+; CHECK-NEXT: Function f2 Hash: [[F1H]]
+
+; DETAILED-HASH: Module Hash: {{([a-z0-9]{14,})}}
+; DETAILED-HASH-NEXT: Function f1 Hash: [[DF1H:([a-z0-9]{14,})]]
+; DETAILED-HASH-NOT: [[DF1H]]
+; DETAILED-HASH-NEXT: Function f2 Hash: {{([a-z0-9]{14,})}}
+


        


More information about the llvm-commits mailing list