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