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