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