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