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