xref: /llvm-project/llvm/lib/Analysis/StructuralHash.cpp (revision 0dd9fdcf83cd00f51669b32c96937a97ef4b339e)
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/Module.h"
16 #include "llvm/IR/StructuralHash.h"
17 #include "llvm/Support/Format.h"
18 
19 using namespace llvm;
20 
21 PreservedAnalyses StructuralHashPrinterPass::run(Module &M,
22                                                  ModuleAnalysisManager &MAM) {
23   OS << "Module Hash: "
24      << format("%016" PRIx64,
25                StructuralHash(M, Options != StructuralHashOptions::None))
26      << "\n";
27   for (Function &F : M) {
28     if (F.isDeclaration())
29       continue;
30     if (Options == StructuralHashOptions::CallTargetIgnored) {
31       auto IgnoreOp = [&](const Instruction *I, unsigned OpndIdx) {
32         return I->getOpcode() == Instruction::Call &&
33                isa<Constant>(I->getOperand(OpndIdx));
34       };
35       auto FuncHashInfo = StructuralHashWithDifferences(F, IgnoreOp);
36       OS << "Function " << F.getName()
37          << " Hash: " << format("%016" PRIx64, FuncHashInfo.FunctionHash)
38          << "\n";
39       for (auto &[IndexPair, OpndHash] : *FuncHashInfo.IndexOperandHashMap) {
40         auto [InstIndex, OpndIndex] = IndexPair;
41         OS << "\tIgnored Operand Hash: " << format("%016" PRIx64, OpndHash)
42            << " at (" << InstIndex << "," << OpndIndex << ")\n";
43       }
44     } else {
45       OS << "Function " << F.getName() << " Hash: "
46          << format(
47                 "%016" PRIx64,
48                 StructuralHash(F, Options == StructuralHashOptions::Detailed))
49          << "\n";
50     }
51   }
52   return PreservedAnalyses::all();
53 }
54