xref: /freebsd/contrib/llvm-project/llvm/tools/llvm-diff/lib/DifferenceEngine.h (revision 0c59e0b4e5817f139ce28486085b2f196351c7a3)
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(L, 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);
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