13dd706b5288b83967968287c0950480948e8c3f6John McCall//===-- DifferenceEngine.h - Module comparator ------------------*- C++ -*-===//
23dd706b5288b83967968287c0950480948e8c3f6John McCall//
33dd706b5288b83967968287c0950480948e8c3f6John McCall//                     The LLVM Compiler Infrastructure
43dd706b5288b83967968287c0950480948e8c3f6John McCall//
53dd706b5288b83967968287c0950480948e8c3f6John McCall// This file is distributed under the University of Illinois Open Source
63dd706b5288b83967968287c0950480948e8c3f6John McCall// License. See LICENSE.TXT for details.
73dd706b5288b83967968287c0950480948e8c3f6John McCall//
83dd706b5288b83967968287c0950480948e8c3f6John McCall//===----------------------------------------------------------------------===//
93dd706b5288b83967968287c0950480948e8c3f6John McCall//
103dd706b5288b83967968287c0950480948e8c3f6John McCall// This header defines the interface to the LLVM difference engine,
113dd706b5288b83967968287c0950480948e8c3f6John McCall// which structurally compares functions within a module.
123dd706b5288b83967968287c0950480948e8c3f6John McCall//
133dd706b5288b83967968287c0950480948e8c3f6John McCall//===----------------------------------------------------------------------===//
143dd706b5288b83967968287c0950480948e8c3f6John McCall
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_TOOLS_LLVM_DIFF_DIFFERENCEENGINE_H
1637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_TOOLS_LLVM_DIFF_DIFFERENCEENGINE_H
173dd706b5288b83967968287c0950480948e8c3f6John McCall
18f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "DiffConsumer.h"
19f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "DiffLog.h"
2073b21b738ee74f33f16ca6bf88bd4344b3fca0a9John McCall#include "llvm/ADT/SmallVector.h"
2173b21b738ee74f33f16ca6bf88bd4344b3fca0a9John McCall#include "llvm/ADT/StringRef.h"
223dd706b5288b83967968287c0950480948e8c3f6John McCall#include <utility>
233dd706b5288b83967968287c0950480948e8c3f6John McCall
243dd706b5288b83967968287c0950480948e8c3f6John McCallnamespace llvm {
2573b21b738ee74f33f16ca6bf88bd4344b3fca0a9John McCall  class Function;
2673b21b738ee74f33f16ca6bf88bd4344b3fca0a9John McCall  class GlobalValue;
2773b21b738ee74f33f16ca6bf88bd4344b3fca0a9John McCall  class Instruction;
283dd706b5288b83967968287c0950480948e8c3f6John McCall  class LLVMContext;
293dd706b5288b83967968287c0950480948e8c3f6John McCall  class Module;
303dd706b5288b83967968287c0950480948e8c3f6John McCall  class Twine;
313dd706b5288b83967968287c0950480948e8c3f6John McCall  class Value;
323dd706b5288b83967968287c0950480948e8c3f6John McCall
333dd706b5288b83967968287c0950480948e8c3f6John McCall  /// A class for performing structural comparisons of LLVM assembly.
343dd706b5288b83967968287c0950480948e8c3f6John McCall  class DifferenceEngine {
353dd706b5288b83967968287c0950480948e8c3f6John McCall  public:
363dd706b5288b83967968287c0950480948e8c3f6John McCall    /// A RAII object for recording the current context.
373dd706b5288b83967968287c0950480948e8c3f6John McCall    struct Context {
383dd706b5288b83967968287c0950480948e8c3f6John McCall      Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) {
393dd706b5288b83967968287c0950480948e8c3f6John McCall        Engine.consumer.enterContext(L, R);
403dd706b5288b83967968287c0950480948e8c3f6John McCall      }
413dd706b5288b83967968287c0950480948e8c3f6John McCall
423dd706b5288b83967968287c0950480948e8c3f6John McCall      ~Context() {
433dd706b5288b83967968287c0950480948e8c3f6John McCall        Engine.consumer.exitContext();
443dd706b5288b83967968287c0950480948e8c3f6John McCall      }
453dd706b5288b83967968287c0950480948e8c3f6John McCall
463dd706b5288b83967968287c0950480948e8c3f6John McCall    private:
473dd706b5288b83967968287c0950480948e8c3f6John McCall      DifferenceEngine &Engine;
483dd706b5288b83967968287c0950480948e8c3f6John McCall    };
493dd706b5288b83967968287c0950480948e8c3f6John McCall
503dd706b5288b83967968287c0950480948e8c3f6John McCall    /// An oracle for answering whether two values are equivalent as
513dd706b5288b83967968287c0950480948e8c3f6John McCall    /// operands.
522d24e2a396a1d211baaeedf32148a3b657240170David Blaikie    class Oracle {
532d24e2a396a1d211baaeedf32148a3b657240170David Blaikie      virtual void anchor();
542d24e2a396a1d211baaeedf32148a3b657240170David Blaikie    public:
553dd706b5288b83967968287c0950480948e8c3f6John McCall      virtual bool operator()(Value *L, Value *R) = 0;
563dd706b5288b83967968287c0950480948e8c3f6John McCall
573dd706b5288b83967968287c0950480948e8c3f6John McCall    protected:
58ac530614641a3702a90702b78acb6b9d8588881bBill Wendling      virtual ~Oracle() {}
593dd706b5288b83967968287c0950480948e8c3f6John McCall    };
603dd706b5288b83967968287c0950480948e8c3f6John McCall
61a7542d5f870c5d98960d1676e23ac1d1d975d7e5Benjamin Kramer    DifferenceEngine(Consumer &consumer)
62dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines      : consumer(consumer), globalValueOracle(nullptr) {}
633dd706b5288b83967968287c0950480948e8c3f6John McCall
643dd706b5288b83967968287c0950480948e8c3f6John McCall    void diff(Module *L, Module *R);
653dd706b5288b83967968287c0950480948e8c3f6John McCall    void diff(Function *L, Function *R);
663dd706b5288b83967968287c0950480948e8c3f6John McCall    void log(StringRef text) {
673dd706b5288b83967968287c0950480948e8c3f6John McCall      consumer.log(text);
683dd706b5288b83967968287c0950480948e8c3f6John McCall    }
693dd706b5288b83967968287c0950480948e8c3f6John McCall    LogBuilder logf(StringRef text) {
707d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      return LogBuilder(consumer, text);
713dd706b5288b83967968287c0950480948e8c3f6John McCall    }
727d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    Consumer& getConsumer() const { return consumer; }
733dd706b5288b83967968287c0950480948e8c3f6John McCall
743dd706b5288b83967968287c0950480948e8c3f6John McCall    /// Installs an oracle to decide whether two global values are
753dd706b5288b83967968287c0950480948e8c3f6John McCall    /// equivalent as operands.  Without an oracle, global values are
763dd706b5288b83967968287c0950480948e8c3f6John McCall    /// considered equivalent as operands precisely when they have the
773dd706b5288b83967968287c0950480948e8c3f6John McCall    /// same name.
783dd706b5288b83967968287c0950480948e8c3f6John McCall    void setGlobalValueOracle(Oracle *oracle) {
793dd706b5288b83967968287c0950480948e8c3f6John McCall      globalValueOracle = oracle;
803dd706b5288b83967968287c0950480948e8c3f6John McCall    }
813dd706b5288b83967968287c0950480948e8c3f6John McCall
823dd706b5288b83967968287c0950480948e8c3f6John McCall    /// Determines whether two global values are equivalent.
833dd706b5288b83967968287c0950480948e8c3f6John McCall    bool equivalentAsOperands(GlobalValue *L, GlobalValue *R);
843dd706b5288b83967968287c0950480948e8c3f6John McCall
853dd706b5288b83967968287c0950480948e8c3f6John McCall  private:
863dd706b5288b83967968287c0950480948e8c3f6John McCall    Consumer &consumer;
873dd706b5288b83967968287c0950480948e8c3f6John McCall    Oracle *globalValueOracle;
883dd706b5288b83967968287c0950480948e8c3f6John McCall  };
893dd706b5288b83967968287c0950480948e8c3f6John McCall}
903dd706b5288b83967968287c0950480948e8c3f6John McCall
913dd706b5288b83967968287c0950480948e8c3f6John McCall#endif
92