1 | //===-- DifferenceEngine.h - Module comparator ------------------*- 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 | // |
9 | // This header defines the interface to the LLVM difference engine, |
10 | // which structurally compares functions within a module. |
11 | // |
12 | //===----------------------------------------------------------------------===// |
13 | |
14 | #ifndef LLVM_TOOLS_LLVM_DIFF_DIFFERENCEENGINE_H |
15 | #define LLVM_TOOLS_LLVM_DIFF_DIFFERENCEENGINE_H |
16 | |
17 | #include "DiffConsumer.h" |
18 | #include "DiffLog.h" |
19 | #include "llvm/ADT/StringRef.h" |
20 | #include <utility> |
21 | |
22 | namespace llvm { |
23 | class Function; |
24 | class GlobalValue; |
25 | class Instruction; |
26 | class LLVMContext; |
27 | class Module; |
28 | class Twine; |
29 | class Value; |
30 | |
31 | /// A class for performing structural comparisons of LLVM assembly. |
32 | class DifferenceEngine { |
33 | public: |
34 | /// A RAII object for recording the current context. |
35 | struct Context { |
36 | Context(DifferenceEngine &Engine, const Value *L, const Value *R) |
37 | : Engine(Engine) { |
38 | Engine.consumer.enterContext(Left: L, Right: R); |
39 | } |
40 | |
41 | ~Context() { |
42 | Engine.consumer.exitContext(); |
43 | } |
44 | |
45 | private: |
46 | DifferenceEngine &Engine; |
47 | }; |
48 | |
49 | /// An oracle for answering whether two values are equivalent as |
50 | /// operands. |
51 | class Oracle { |
52 | virtual void anchor(); |
53 | public: |
54 | virtual bool operator()(const Value *L, const Value *R) = 0; |
55 | |
56 | protected: |
57 | virtual ~Oracle() {} |
58 | }; |
59 | |
60 | DifferenceEngine(Consumer &consumer) |
61 | : consumer(consumer), globalValueOracle(nullptr) {} |
62 | |
63 | void diff(const Module *L, const Module *R); |
64 | void diff(const Function *L, const Function *R); |
65 | void log(StringRef text) { |
66 | consumer.log(Text: text); |
67 | } |
68 | LogBuilder logf(StringRef text) { |
69 | return LogBuilder(consumer, text); |
70 | } |
71 | Consumer& getConsumer() const { return consumer; } |
72 | |
73 | /// Installs an oracle to decide whether two global values are |
74 | /// equivalent as operands. Without an oracle, global values are |
75 | /// considered equivalent as operands precisely when they have the |
76 | /// same name. |
77 | void setGlobalValueOracle(Oracle *oracle) { |
78 | globalValueOracle = oracle; |
79 | } |
80 | |
81 | /// Determines whether two global values are equivalent. |
82 | bool equivalentAsOperands(const GlobalValue *L, const GlobalValue *R); |
83 | |
84 | private: |
85 | Consumer &consumer; |
86 | Oracle *globalValueOracle; |
87 | }; |
88 | } |
89 | |
90 | #endif |
91 | |