Home | History | Annotate | Download | only in llvm-diff
      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 {
     38       Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) {
     39         Engine.consumer.enterContext(L, R);
     40       }
     41 
     42       ~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:
     58       virtual ~Oracle() {}
     59     };
     60 
     61     DifferenceEngine(Consumer &consumer)
     62       : consumer(consumer), globalValueOracle(nullptr) {}
     63 
     64     void diff(Module *L, Module *R);
     65     void diff(Function *L, Function *R);
     66     void log(StringRef text) {
     67       consumer.log(text);
     68     }
     69     LogBuilder logf(StringRef text) {
     70       return LogBuilder(consumer, text);
     71     }
     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.
     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