90 lines · c
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-exception6//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_H15#define LLVM_TOOLS_LLVM_DIFF_DIFFERENCEENGINE_H16 17#include "DiffConsumer.h"18#include "DiffLog.h"19#include "llvm/ADT/StringRef.h"20 21namespace llvm {22 class Function;23 class GlobalValue;24 class Instruction;25 class LLVMContext;26 class Module;27 class Twine;28 class Value;29 30 /// A class for performing structural comparisons of LLVM assembly.31 class DifferenceEngine {32 public:33 /// A RAII object for recording the current context.34 struct Context {35 Context(DifferenceEngine &Engine, const Value *L, const Value *R)36 : 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 as49 /// operands.50 class Oracle {51 virtual void anchor();52 public:53 virtual bool operator()(const Value *L, const Value *R) = 0;54 55 protected:56 virtual ~Oracle() = default;57 };58 59 DifferenceEngine(Consumer &consumer)60 : consumer(consumer), globalValueOracle(nullptr) {}61 62 void diff(const Module *L, const Module *R);63 void diff(const Function *L, const 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 are73 /// equivalent as operands. Without an oracle, global values are74 /// considered equivalent as operands precisely when they have the75 /// same name.76 void setGlobalValueOracle(Oracle *oracle) {77 globalValueOracle = oracle;78 }79 80 /// Determines whether two global values are equivalent.81 bool equivalentAsOperands(const GlobalValue *L, const GlobalValue *R);82 83 private:84 Consumer &consumer;85 Oracle *globalValueOracle;86 };87}88 89#endif90