Skip to content

Commit 3a42b1f

Browse files
[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
1 parent 732f63d commit 3a42b1f

File tree

7 files changed

+121
-0
lines changed

7 files changed

+121
-0
lines changed
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
//=- StructuralHash.h - Structural Hash Printing --*- C++ -*-----------------=//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef LLVM_ANALYSIS_STRUCTURALHASH_H
10+
#define LLVM_ANALYSIS_STRUCTURALHASH_H
11+
12+
#include "llvm/IR/PassManager.h"
13+
14+
namespace llvm {
15+
16+
/// Printer pass for StructuralHashes
17+
class StructuralHashPrinterPass
18+
: public PassInfoMixin<StructuralHashPrinterPass> {
19+
raw_ostream &OS;
20+
bool EnableDetailedStructuralHash;
21+
22+
public:
23+
explicit StructuralHashPrinterPass(raw_ostream &OS, bool Detailed)
24+
: OS(OS), EnableDetailedStructuralHash(Detailed) {}
25+
26+
PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM);
27+
};
28+
29+
} // namespace llvm
30+
31+
#endif // LLVM_ANALYSIS_STRUCTURALHASH_H

llvm/lib/Analysis/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,7 @@ add_llvm_component_library(LLVMAnalysis
124124
ScalarEvolutionNormalization.cpp
125125
StackLifetime.cpp
126126
StackSafetyAnalysis.cpp
127+
StructuralHash.cpp
127128
SyntheticCountsUtils.cpp
128129
TFLiteUtils.cpp
129130
TargetLibraryInfo.cpp

llvm/lib/Analysis/StructuralHash.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
//===- StructuralHash.cpp - Function Hash Printing ------------------------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file defines the StructuralHashPrinterPass which is used to show
10+
// the structural hash of all functions in a module and the module itself.
11+
//
12+
//===----------------------------------------------------------------------===//
13+
14+
#include "llvm/Analysis/StructuralHash.h"
15+
#include "llvm/IR/StructuralHash.h"
16+
#include "llvm/Support/CommandLine.h"
17+
18+
using namespace llvm;
19+
20+
PreservedAnalyses StructuralHashPrinterPass::run(Module &M,
21+
ModuleAnalysisManager &MAM) {
22+
OS << "Module Hash: "
23+
<< Twine::utohexstr(StructuralHash(M, EnableDetailedStructuralHash))
24+
<< "\n";
25+
for (Function &F : M) {
26+
if (F.isDeclaration())
27+
continue;
28+
OS << "Function " << F.getName() << " Hash: "
29+
<< Twine::utohexstr(StructuralHash(F, EnableDetailedStructuralHash))
30+
<< "\n";
31+
}
32+
return PreservedAnalyses::all();
33+
}

llvm/lib/Passes/PassBuilder.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@
6767
#include "llvm/Analysis/ScopedNoAliasAA.h"
6868
#include "llvm/Analysis/StackLifetime.h"
6969
#include "llvm/Analysis/StackSafetyAnalysis.h"
70+
#include "llvm/Analysis/StructuralHash.h"
7071
#include "llvm/Analysis/TargetLibraryInfo.h"
7172
#include "llvm/Analysis/TargetTransformInfo.h"
7273
#include "llvm/Analysis/TypeBasedAliasAnalysis.h"
@@ -1093,6 +1094,11 @@ Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
10931094
return Result;
10941095
}
10951096

1097+
Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) {
1098+
return parseSinglePassOption(Params, "detailed",
1099+
"StructuralHashPrinterPass");
1100+
}
1101+
10961102
} // namespace
10971103

10981104
/// Tests whether a pass name starts with a valid prefix for a default pipeline

llvm/lib/Passes/PassRegistry.def

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,15 @@ MODULE_PASS_WITH_PARAMS("memprof-use",
191191
},
192192
parseMemProfUsePassOptions,
193193
"profile-filename=S")
194+
MODULE_PASS_WITH_PARAMS("print<structural-hash>",
195+
"StructuralHashPrinterPass",
196+
[](bool EnableDetailedStructuralHash) {
197+
return StructuralHashPrinterPass(
198+
dbgs(),
199+
EnableDetailedStructuralHash);
200+
},
201+
parseStructuralHashPrinterPassOptions,
202+
"detailed")
194203
#undef MODULE_PASS_WITH_PARAMS
195204

196205
#ifndef CGSCC_ANALYSIS
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
; Require 64 bits here as the hash will change depending upon whether we are on a 32-bit
2+
; or 64-bit platform.
3+
; REQUIRE: llvm-64-bits
4+
5+
; RUN: opt -passes='print<structural-hash><detailed>' -disable-output %s 2>&1 | FileCheck %s
6+
7+
define i64 @f1(i64 %a) {
8+
ret i64 %a
9+
}
10+
11+
; These values here are explicitly defined to ensure that they are deterministic
12+
; on all 64-bit platforms and across runs.
13+
14+
; CHECK: Module Hash: 81f1328ced269bd
15+
; CHECK: Function f1 Hash: 81f1328ced269bd
16+
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
; RUN: opt -passes='print<structural-hash>' -disable-output %s 2>&1 | FileCheck %s
2+
; RUN: opt -passes='print<structural-hash><detailed>' -disable-output %s 2>&1 | FileCheck %s -check-prefix=DETAILED-HASH
3+
4+
; Add a declaration so that we can test we skip it.
5+
declare i64 @d1()
6+
7+
define i64 @f1(i64 %a) {
8+
%b = add i64 %a, 1
9+
ret i64 %b
10+
}
11+
12+
define i32 @f2(i32 %a) {
13+
%b = add i32 %a, 2
14+
ret i32 %b
15+
}
16+
17+
; CHECK: Module Hash: {{([a-z0-9]{14,})}}
18+
; CHECK-NEXT: Function f1 Hash: [[F1H:([a-z0-9]{14,})]]
19+
; CHECK-NEXT: Function f2 Hash: [[F1H]]
20+
21+
; DETAILED-HASH: Module Hash: {{([a-z0-9]{14,})}}
22+
; DETAILED-HASH-NEXT: Function f1 Hash: [[DF1H:([a-z0-9]{14,})]]
23+
; DETAILED-HASH-NOT: [[DF1H]]
24+
; DETAILED-HASH-NEXT: Function f2 Hash: {{([a-z0-9]{14,})}}
25+

0 commit comments

Comments
 (0)