xref: /llvm-project/llvm/lib/Analysis/StructuralHash.cpp (revision 0dd9fdcf83cd00f51669b32c96937a97ef4b339e)
13a42b1fdSAiden Grossman //===- StructuralHash.cpp - Function Hash Printing ------------------------===//
23a42b1fdSAiden Grossman //
33a42b1fdSAiden Grossman // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43a42b1fdSAiden Grossman // See https://llvm.org/LICENSE.txt for license information.
53a42b1fdSAiden Grossman // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63a42b1fdSAiden Grossman //
73a42b1fdSAiden Grossman //===----------------------------------------------------------------------===//
83a42b1fdSAiden Grossman //
93a42b1fdSAiden Grossman // This file defines the StructuralHashPrinterPass which is used to show
103a42b1fdSAiden Grossman // the structural hash of all functions in a module and the module itself.
113a42b1fdSAiden Grossman //
123a42b1fdSAiden Grossman //===----------------------------------------------------------------------===//
133a42b1fdSAiden Grossman 
143a42b1fdSAiden Grossman #include "llvm/Analysis/StructuralHash.h"
154169338eSNikita Popov #include "llvm/IR/Module.h"
163a42b1fdSAiden Grossman #include "llvm/IR/StructuralHash.h"
174a98f522SSergei Barannikov #include "llvm/Support/Format.h"
183a42b1fdSAiden Grossman 
193a42b1fdSAiden Grossman using namespace llvm;
203a42b1fdSAiden Grossman 
213a42b1fdSAiden Grossman PreservedAnalyses StructuralHashPrinterPass::run(Module &M,
223a42b1fdSAiden Grossman                                                  ModuleAnalysisManager &MAM) {
233a42b1fdSAiden Grossman   OS << "Module Hash: "
24*0dd9fdcfSKyungwoo Lee      << format("%016" PRIx64,
25*0dd9fdcfSKyungwoo Lee                StructuralHash(M, Options != StructuralHashOptions::None))
263a42b1fdSAiden Grossman      << "\n";
273a42b1fdSAiden Grossman   for (Function &F : M) {
283a42b1fdSAiden Grossman     if (F.isDeclaration())
293a42b1fdSAiden Grossman       continue;
30*0dd9fdcfSKyungwoo Lee     if (Options == StructuralHashOptions::CallTargetIgnored) {
31*0dd9fdcfSKyungwoo Lee       auto IgnoreOp = [&](const Instruction *I, unsigned OpndIdx) {
32*0dd9fdcfSKyungwoo Lee         return I->getOpcode() == Instruction::Call &&
33*0dd9fdcfSKyungwoo Lee                isa<Constant>(I->getOperand(OpndIdx));
34*0dd9fdcfSKyungwoo Lee       };
35*0dd9fdcfSKyungwoo Lee       auto FuncHashInfo = StructuralHashWithDifferences(F, IgnoreOp);
36*0dd9fdcfSKyungwoo Lee       OS << "Function " << F.getName()
37*0dd9fdcfSKyungwoo Lee          << " Hash: " << format("%016" PRIx64, FuncHashInfo.FunctionHash)
383a42b1fdSAiden Grossman          << "\n";
39*0dd9fdcfSKyungwoo Lee       for (auto &[IndexPair, OpndHash] : *FuncHashInfo.IndexOperandHashMap) {
40*0dd9fdcfSKyungwoo Lee         auto [InstIndex, OpndIndex] = IndexPair;
41*0dd9fdcfSKyungwoo Lee         OS << "\tIgnored Operand Hash: " << format("%016" PRIx64, OpndHash)
42*0dd9fdcfSKyungwoo Lee            << " at (" << InstIndex << "," << OpndIndex << ")\n";
43*0dd9fdcfSKyungwoo Lee       }
44*0dd9fdcfSKyungwoo Lee     } else {
45*0dd9fdcfSKyungwoo Lee       OS << "Function " << F.getName() << " Hash: "
46*0dd9fdcfSKyungwoo Lee          << format(
47*0dd9fdcfSKyungwoo Lee                 "%016" PRIx64,
48*0dd9fdcfSKyungwoo Lee                 StructuralHash(F, Options == StructuralHashOptions::Detailed))
49*0dd9fdcfSKyungwoo Lee          << "\n";
50*0dd9fdcfSKyungwoo Lee     }
513a42b1fdSAiden Grossman   }
523a42b1fdSAiden Grossman   return PreservedAnalyses::all();
533a42b1fdSAiden Grossman }
54