1 //===-- StructuralHash.cpp - IR Hash for expensive checks -------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
10 #ifdef EXPENSIVE_CHECKS
12 #include "llvm/IR/StructuralHash.h"
13 #include "llvm/IR/Function.h"
14 #include "llvm/IR/Module.h"
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
); }
31 StructuralHash() = default;
33 void update(const Function
&F
) {
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
)
55 BBs
.push_back(Term
->getSuccessor(i
));
60 void update(const Module
&M
) {
61 for (const Function
&F
: M
)
65 uint64_t getHash() const { return Hash
; }
68 } // namespace details
72 uint64_t llvm::StructuralHash(const Function
&F
) {
73 details::StructuralHash H
;
78 uint64_t llvm::StructuralHash(const Module
&M
) {
79 details::StructuralHash H
;