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