1212793Sdim//===-- DifferenceEngine.h - Module comparator ------------------*- C++ -*-===// 2212793Sdim// 3212793Sdim// The LLVM Compiler Infrastructure 4212793Sdim// 5212793Sdim// This file is distributed under the University of Illinois Open Source 6212793Sdim// License. See LICENSE.TXT for details. 7212793Sdim// 8212793Sdim//===----------------------------------------------------------------------===// 9212793Sdim// 10212793Sdim// This header defines the interface to the LLVM difference engine, 11212793Sdim// which structurally compares functions within a module. 12212793Sdim// 13212793Sdim//===----------------------------------------------------------------------===// 14212793Sdim 15212793Sdim#ifndef _LLVM_DIFFERENCE_ENGINE_H_ 16212793Sdim#define _LLVM_DIFFERENCE_ENGINE_H_ 17212793Sdim 18249423Sdim#include "DiffConsumer.h" 19249423Sdim#include "DiffLog.h" 20212793Sdim#include "llvm/ADT/SmallVector.h" 21212793Sdim#include "llvm/ADT/StringRef.h" 22212793Sdim#include <utility> 23212793Sdim 24212793Sdimnamespace llvm { 25212793Sdim class Function; 26212793Sdim class GlobalValue; 27212793Sdim class Instruction; 28212793Sdim class LLVMContext; 29212793Sdim class Module; 30212793Sdim class Twine; 31212793Sdim class Value; 32212793Sdim 33212793Sdim /// A class for performing structural comparisons of LLVM assembly. 34212793Sdim class DifferenceEngine { 35212793Sdim public: 36212793Sdim /// A RAII object for recording the current context. 37212793Sdim struct Context { 38212793Sdim Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) { 39212793Sdim Engine.consumer.enterContext(L, R); 40212793Sdim } 41212793Sdim 42212793Sdim ~Context() { 43212793Sdim Engine.consumer.exitContext(); 44212793Sdim } 45212793Sdim 46212793Sdim private: 47212793Sdim DifferenceEngine &Engine; 48212793Sdim }; 49212793Sdim 50212793Sdim /// An oracle for answering whether two values are equivalent as 51212793Sdim /// operands. 52234353Sdim class Oracle { 53234353Sdim virtual void anchor(); 54234353Sdim public: 55212793Sdim virtual bool operator()(Value *L, Value *R) = 0; 56212793Sdim 57212793Sdim protected: 58212793Sdim virtual ~Oracle() {} 59212793Sdim }; 60212793Sdim 61239462Sdim DifferenceEngine(Consumer &consumer) 62239462Sdim : consumer(consumer), globalValueOracle(0) {} 63212793Sdim 64212793Sdim void diff(Module *L, Module *R); 65212793Sdim void diff(Function *L, Function *R); 66212793Sdim void log(StringRef text) { 67212793Sdim consumer.log(text); 68212793Sdim } 69212793Sdim LogBuilder logf(StringRef text) { 70221337Sdim return LogBuilder(consumer, text); 71212793Sdim } 72221337Sdim Consumer& getConsumer() const { return consumer; } 73212793Sdim 74212793Sdim /// Installs an oracle to decide whether two global values are 75212793Sdim /// equivalent as operands. Without an oracle, global values are 76212793Sdim /// considered equivalent as operands precisely when they have the 77212793Sdim /// same name. 78212793Sdim void setGlobalValueOracle(Oracle *oracle) { 79212793Sdim globalValueOracle = oracle; 80212793Sdim } 81212793Sdim 82212793Sdim /// Determines whether two global values are equivalent. 83212793Sdim bool equivalentAsOperands(GlobalValue *L, GlobalValue *R); 84212793Sdim 85212793Sdim private: 86212793Sdim Consumer &consumer; 87212793Sdim Oracle *globalValueOracle; 88212793Sdim }; 89212793Sdim} 90212793Sdim 91212793Sdim#endif 92