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_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 {
     39       Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) {
     40         Engine.consumer.enterContext(L, R);
     41       }
     42 
     43       ~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:
     59       virtual ~Oracle() {}
     60     };
     61 
     62     DifferenceEngine(LLVMContext &context, Consumer &consumer)
     63       : context(context), consumer(consumer), globalValueOracle(0) {}
     64 
     65     void diff(Module *L, Module *R);
     66     void diff(Function *L, Function *R);
     67     void log(StringRef text) {
     68       consumer.log(text);
     69     }
     70     LogBuilder logf(StringRef text) {
     71       return LogBuilder(consumer, text);
     72     }
     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.
     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     LLVMContext &context;
     88     Consumer &consumer;
     89     Oracle *globalValueOracle;
     90   };
     91 }
     92 
     93 #endif
     94