• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 {
ContextContext36       Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) {
37         Engine.consumer.enterContext(L, R);
38       }
39 
~ContextContext40       ~Context() {
41         Engine.consumer.exitContext();
42       }
43 
44     private:
45       DifferenceEngine &Engine;
46     };
47 
48     /// An oracle for answering whether two values are equivalent as
49     /// operands.
50     class Oracle {
51       virtual void anchor();
52     public:
53       virtual bool operator()(Value *L, Value *R) = 0;
54 
55     protected:
~Oracle()56       virtual ~Oracle() {}
57     };
58 
DifferenceEngine(Consumer & consumer)59     DifferenceEngine(Consumer &consumer)
60       : consumer(consumer), globalValueOracle(nullptr) {}
61 
62     void diff(Module *L, Module *R);
63     void diff(Function *L, Function *R);
log(StringRef text)64     void log(StringRef text) {
65       consumer.log(text);
66     }
logf(StringRef text)67     LogBuilder logf(StringRef text) {
68       return LogBuilder(consumer, text);
69     }
getConsumer()70     Consumer& getConsumer() const { return consumer; }
71 
72     /// Installs an oracle to decide whether two global values are
73     /// equivalent as operands.  Without an oracle, global values are
74     /// considered equivalent as operands precisely when they have the
75     /// same name.
setGlobalValueOracle(Oracle * oracle)76     void setGlobalValueOracle(Oracle *oracle) {
77       globalValueOracle = oracle;
78     }
79 
80     /// Determines whether two global values are equivalent.
81     bool equivalentAsOperands(GlobalValue *L, GlobalValue *R);
82 
83   private:
84     Consumer &consumer;
85     Oracle *globalValueOracle;
86   };
87 }
88 
89 #endif
90