diff --git a/llvm/include/llvm/Analysis/StructuralHash.h b/llvm/include/llvm/Analysis/StructuralHash.h new file mode 100644 --- /dev/null +++ b/llvm/include/llvm/Analysis/StructuralHash.h @@ -0,0 +1,33 @@ +//=- StructuralHash.h - Structural Hash Printing --*- C++ -*---------------0-=// +// +// 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 +// +//===----------------------------------------------------------------------===// + +#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 { + raw_ostream &OS; + +public: + explicit StructuralHashPrinterPass(raw_ostream &OS) : OS(OS) {} + + 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 --- a/llvm/lib/Analysis/CMakeLists.txt +++ b/llvm/lib/Analysis/CMakeLists.txt @@ -124,6 +124,7 @@ 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 --- /dev/null +++ b/llvm/lib/Analysis/StructuralHash.cpp @@ -0,0 +1,35 @@ +//===- 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; + +cl::opt EnableDetailedStructuralHashing( + "enable-detailed-structural-hash", cl::Hidden, cl::init(false), + cl::desc("Whether or not to enable detailed structural hashing.")); + +PreservedAnalyses StructuralHashPrinterPass::run(Module &M, + ModuleAnalysisManager &MAM) { + OS << "Module Hash: " + << Twine::utohexstr(StructuralHash(M, EnableDetailedStructuralHashing)) + << "\n"; + for (Function &F : M) { + OS << "Function " << F.getName() << " Hash: " + << Twine::utohexstr(StructuralHash(F, EnableDetailedStructuralHashing)) + << "\n"; + } + return PreservedAnalyses::all(); +} diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp --- 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" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -128,6 +128,7 @@ MODULE_PASS("memprof-module", ModuleMemProfilerPass()) MODULE_PASS("poison-checking", PoisonCheckingPass()) MODULE_PASS("pseudo-probe-update", PseudoProbeUpdatePass()) +MODULE_PASS("print", StructuralHashPrinterPass(dbgs())); #undef MODULE_PASS #ifndef MODULE_PASS_WITH_PARAMS diff --git a/llvm/test/Analysis/StructuralHash/structural-hash-printer.ll b/llvm/test/Analysis/StructuralHash/structural-hash-printer.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/StructuralHash/structural-hash-printer.ll @@ -0,0 +1,21 @@ +; RUN: opt -passes='print' -disable-output %s 2>&1 | FileCheck %s +; RUN: opt -passes='print' -enable-detailed-structural-hash -disable-output %s 2>&1 | FileCheck %s -check-prefix=DETAILED-HASH + +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]{16})}} +; CHECK: Function f1 Hash: {{([a-z0-9]{16})}} +; CHECK: Function f2 Hash: {{([a-z0-9]{16})}} + +; DETAILED-HASH: Module Hash: {{([a-z0-9]{16})}} +; DETAILED-HASH: Function f1 Hash: {{([a-z0-9]{16})}} +; DETAILED-HASH: Function f2 Hash: {{([a-z0-9]{16})}} +