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