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