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 22namespace 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, Value *L, Value *R) : Engine(Engine) { 37 Engine.consumer.enterContext(L, R); 38 } 39 40 ~Context() { 41 Engine.consumer.exitContext(); 42 } 43 44 private: 45 DifferenceEngine &Engine; 46 }; 47 48 /// An oracle for answering whether two values are equivalent as 49 /// operands. 50 class Oracle { 51 virtual void anchor(); 52 public: 53 virtual bool operator()(Value *L, Value *R) = 0; 54 55 protected: 56 virtual ~Oracle() {} 57 }; 58 59 DifferenceEngine(Consumer &consumer) 60 : consumer(consumer), globalValueOracle(nullptr) {} 61 62 void diff(Module *L, Module *R); 63 void diff(Function *L, Function *R); 64 void log(StringRef text) { 65 consumer.log(text); 66 } 67 LogBuilder logf(StringRef text) { 68 return LogBuilder(consumer, text); 69 } 70 Consumer& getConsumer() const { return consumer; } 71 72 /// Installs an oracle to decide whether two global values are 73 /// equivalent as operands. Without an oracle, global values are 74 /// considered equivalent as operands precisely when they have the 75 /// same name. 76 void setGlobalValueOracle(Oracle *oracle) { 77 globalValueOracle = oracle; 78 } 79 80 /// Determines whether two global values are equivalent. 81 bool equivalentAsOperands(GlobalValue *L, GlobalValue *R); 82 83 private: 84 Consumer &consumer; 85 Oracle *globalValueOracle; 86 }; 87} 88 89#endif 90