[ORC] Add std::tuple support to SimplePackedSerialization.
[llvm-project.git] / llvm / lib / IR / StructuralHash.cpp
blob5a6e074513268046c4720a560a07c1aef8d6695d
1 //===-- StructuralHash.cpp - IR Hash for expensive checks -------*- C++ -*-===//
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 //
10 #ifdef EXPENSIVE_CHECKS
12 #include "llvm/IR/StructuralHash.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/Module.h"
16 using namespace llvm;
18 namespace {
19 namespace details {
21 // Basic hashing mechanism to detect structural change to the IR, used to verify
22 // pass return status consistency with actual change. Loosely copied from
23 // llvm/lib/Transforms/Utils/FunctionComparator.cpp
25 class StructuralHash {
26 uint64_t Hash = 0x6acaa36bef8325c5ULL;
28 void update(uint64_t V) { Hash = hashing::detail::hash_16_bytes(Hash, V); }
30 public:
31 StructuralHash() = default;
33 void update(const Function &F) {
34 if (F.empty())
35 return;
37 update(F.isVarArg());
38 update(F.arg_size());
40 SmallVector<const BasicBlock *, 8> BBs;
41 SmallPtrSet<const BasicBlock *, 16> VisitedBBs;
43 BBs.push_back(&F.getEntryBlock());
44 VisitedBBs.insert(BBs[0]);
45 while (!BBs.empty()) {
46 const BasicBlock *BB = BBs.pop_back_val();
47 update(45798); // Block header
48 for (auto &Inst : *BB)
49 update(Inst.getOpcode());
51 const Instruction *Term = BB->getTerminator();
52 for (unsigned i = 0, e = Term->getNumSuccessors(); i != e; ++i) {
53 if (!VisitedBBs.insert(Term->getSuccessor(i)).second)
54 continue;
55 BBs.push_back(Term->getSuccessor(i));
60 void update(const Module &M) {
61 for (const Function &F : M)
62 update(F);
65 uint64_t getHash() const { return Hash; }
68 } // namespace details
70 } // namespace
72 uint64_t llvm::StructuralHash(const Function &F) {
73 details::StructuralHash H;
74 H.update(F);
75 return H.getHash();
78 uint64_t llvm::StructuralHash(const Module &M) {
79 details::StructuralHash H;
80 H.update(M);
81 return H.getHash();
84 #endif