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     struct Oracle {
     54       virtual bool operator()(Value *L, Value *R) = 0;
     55 
     56     protected:
     57       virtual ~Oracle() {}
     58     };
     59 
     60     DifferenceEngine(LLVMContext &context, Consumer &consumer)
     61       : context(context), consumer(consumer), globalValueOracle(0) {}
     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     LLVMContext &context;
     86     Consumer &consumer;
     87     Oracle *globalValueOracle;
     88   };
     89 }
     90 
     91 #endif
     92