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/StringRef.h"
     21 #include <utility>
     22 
     23 namespace llvm {
     24   class Function;
     25   class GlobalValue;
     26   class Instruction;
     27   class LLVMContext;
     28   class Module;
     29   class Twine;
     30   class Value;
     31 
     32   /// A class for performing structural comparisons of LLVM assembly.
     33   class DifferenceEngine {
     34   public:
     35     /// A RAII object for recording the current context.
     36     struct Context {
     37       Context(DifferenceEngine &Engine, Value *L, Value *R) : 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()(Value *L, Value *R) = 0;
     55 
     56     protected:
     57       virtual ~Oracle() {}
     58     };
     59 
     60     DifferenceEngine(Consumer &consumer)
     61       : consumer(consumer), globalValueOracle(nullptr) {}
     62 
     63     void diff(Module *L, Module *R);
     64     void diff(Function *L, 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(GlobalValue *L, GlobalValue *R);
     83 
     84   private:
     85     Consumer &consumer;
     86     Oracle *globalValueOracle;
     87   };
     88 }
     89 
     90 #endif
     91