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