1*4d293f21SBill Wendling //===-- DifferenceEngine.h - Module comparator ------------------*- C++ -*-===// 2*4d293f21SBill Wendling // 3*4d293f21SBill Wendling // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*4d293f21SBill Wendling // See https://llvm.org/LICENSE.txt for license information. 5*4d293f21SBill Wendling // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*4d293f21SBill Wendling // 7*4d293f21SBill Wendling //===----------------------------------------------------------------------===// 8*4d293f21SBill Wendling // 9*4d293f21SBill Wendling // This header defines the interface to the LLVM difference engine, 10*4d293f21SBill Wendling // which structurally compares functions within a module. 11*4d293f21SBill Wendling // 12*4d293f21SBill Wendling //===----------------------------------------------------------------------===// 13*4d293f21SBill Wendling 14*4d293f21SBill Wendling #ifndef LLVM_TOOLS_LLVM_DIFF_DIFFERENCEENGINE_H 15*4d293f21SBill Wendling #define LLVM_TOOLS_LLVM_DIFF_DIFFERENCEENGINE_H 16*4d293f21SBill Wendling 17*4d293f21SBill Wendling #include "DiffConsumer.h" 18*4d293f21SBill Wendling #include "DiffLog.h" 19*4d293f21SBill Wendling #include "llvm/ADT/StringRef.h" 20*4d293f21SBill Wendling #include <utility> 21*4d293f21SBill Wendling 22*4d293f21SBill Wendling namespace llvm { 23*4d293f21SBill Wendling class Function; 24*4d293f21SBill Wendling class GlobalValue; 25*4d293f21SBill Wendling class Instruction; 26*4d293f21SBill Wendling class LLVMContext; 27*4d293f21SBill Wendling class Module; 28*4d293f21SBill Wendling class Twine; 29*4d293f21SBill Wendling class Value; 30*4d293f21SBill Wendling 31*4d293f21SBill Wendling /// A class for performing structural comparisons of LLVM assembly. 32*4d293f21SBill Wendling class DifferenceEngine { 33*4d293f21SBill Wendling public: 34*4d293f21SBill Wendling /// A RAII object for recording the current context. 35*4d293f21SBill Wendling struct Context { ContextContext36*4d293f21SBill Wendling Context(DifferenceEngine &Engine, const Value *L, const Value *R) 37*4d293f21SBill Wendling : Engine(Engine) { 38*4d293f21SBill Wendling Engine.consumer.enterContext(L, R); 39*4d293f21SBill Wendling } 40*4d293f21SBill Wendling ~ContextContext41*4d293f21SBill Wendling ~Context() { 42*4d293f21SBill Wendling Engine.consumer.exitContext(); 43*4d293f21SBill Wendling } 44*4d293f21SBill Wendling 45*4d293f21SBill Wendling private: 46*4d293f21SBill Wendling DifferenceEngine &Engine; 47*4d293f21SBill Wendling }; 48*4d293f21SBill Wendling 49*4d293f21SBill Wendling /// An oracle for answering whether two values are equivalent as 50*4d293f21SBill Wendling /// operands. 51*4d293f21SBill Wendling class Oracle { 52*4d293f21SBill Wendling virtual void anchor(); 53*4d293f21SBill Wendling public: 54*4d293f21SBill Wendling virtual bool operator()(const Value *L, const Value *R) = 0; 55*4d293f21SBill Wendling 56*4d293f21SBill Wendling protected: ~Oracle()57*4d293f21SBill Wendling virtual ~Oracle() {} 58*4d293f21SBill Wendling }; 59*4d293f21SBill Wendling DifferenceEngine(Consumer & consumer)60*4d293f21SBill Wendling DifferenceEngine(Consumer &consumer) 61*4d293f21SBill Wendling : consumer(consumer), globalValueOracle(nullptr) {} 62*4d293f21SBill Wendling 63*4d293f21SBill Wendling void diff(const Module *L, const Module *R); 64*4d293f21SBill Wendling void diff(const Function *L, const Function *R); log(StringRef text)65*4d293f21SBill Wendling void log(StringRef text) { 66*4d293f21SBill Wendling consumer.log(text); 67*4d293f21SBill Wendling } logf(StringRef text)68*4d293f21SBill Wendling LogBuilder logf(StringRef text) { 69*4d293f21SBill Wendling return LogBuilder(consumer, text); 70*4d293f21SBill Wendling } getConsumer()71*4d293f21SBill Wendling Consumer& getConsumer() const { return consumer; } 72*4d293f21SBill Wendling 73*4d293f21SBill Wendling /// Installs an oracle to decide whether two global values are 74*4d293f21SBill Wendling /// equivalent as operands. Without an oracle, global values are 75*4d293f21SBill Wendling /// considered equivalent as operands precisely when they have the 76*4d293f21SBill Wendling /// same name. setGlobalValueOracle(Oracle * oracle)77*4d293f21SBill Wendling void setGlobalValueOracle(Oracle *oracle) { 78*4d293f21SBill Wendling globalValueOracle = oracle; 79*4d293f21SBill Wendling } 80*4d293f21SBill Wendling 81*4d293f21SBill Wendling /// Determines whether two global values are equivalent. 82*4d293f21SBill Wendling bool equivalentAsOperands(const GlobalValue *L, const GlobalValue *R); 83*4d293f21SBill Wendling 84*4d293f21SBill Wendling private: 85*4d293f21SBill Wendling Consumer &consumer; 86*4d293f21SBill Wendling Oracle *globalValueOracle; 87*4d293f21SBill Wendling }; 88*4d293f21SBill Wendling } 89*4d293f21SBill Wendling 90*4d293f21SBill Wendling #endif 91