1*349cc55cSDimitry Andric //===-- DiffConsumer.h - Difference Consumer --------------------*- C++ -*-===// 2*349cc55cSDimitry Andric // 3*349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4*349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 5*349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6*349cc55cSDimitry Andric // 7*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 8*349cc55cSDimitry Andric // 9*349cc55cSDimitry Andric // This header defines the interface to the LLVM difference Consumer 10*349cc55cSDimitry Andric // 11*349cc55cSDimitry Andric //===----------------------------------------------------------------------===// 12*349cc55cSDimitry Andric 13*349cc55cSDimitry Andric #ifndef LLVM_TOOLS_LLVM_DIFF_DIFFCONSUMER_H 14*349cc55cSDimitry Andric #define LLVM_TOOLS_LLVM_DIFF_DIFFCONSUMER_H 15*349cc55cSDimitry Andric 16*349cc55cSDimitry Andric #include "DiffLog.h" 17*349cc55cSDimitry Andric #include "llvm/ADT/DenseMap.h" 18*349cc55cSDimitry Andric #include "llvm/ADT/SmallVector.h" 19*349cc55cSDimitry Andric #include "llvm/IR/Value.h" 20*349cc55cSDimitry Andric #include "llvm/Support/Casting.h" 21*349cc55cSDimitry Andric #include "llvm/Support/raw_ostream.h" 22*349cc55cSDimitry Andric 23*349cc55cSDimitry Andric namespace llvm { 24*349cc55cSDimitry Andric class StringRef; 25*349cc55cSDimitry Andric class Module; 26*349cc55cSDimitry Andric class Value; 27*349cc55cSDimitry Andric class Function; 28*349cc55cSDimitry Andric 29*349cc55cSDimitry Andric /// The interface for consumers of difference data. 30*349cc55cSDimitry Andric class Consumer { 31*349cc55cSDimitry Andric virtual void anchor(); 32*349cc55cSDimitry Andric public: 33*349cc55cSDimitry Andric /// Record that a local context has been entered. Left and 34*349cc55cSDimitry Andric /// Right are IR "containers" of some sort which are being 35*349cc55cSDimitry Andric /// considered for structural equivalence: global variables, 36*349cc55cSDimitry Andric /// functions, blocks, instructions, etc. 37*349cc55cSDimitry Andric virtual void enterContext(const Value *Left, const Value *Right) = 0; 38*349cc55cSDimitry Andric 39*349cc55cSDimitry Andric /// Record that a local context has been exited. 40*349cc55cSDimitry Andric virtual void exitContext() = 0; 41*349cc55cSDimitry Andric 42*349cc55cSDimitry Andric /// Record a difference within the current context. 43*349cc55cSDimitry Andric virtual void log(StringRef Text) = 0; 44*349cc55cSDimitry Andric 45*349cc55cSDimitry Andric /// Record a formatted difference within the current context. 46*349cc55cSDimitry Andric virtual void logf(const LogBuilder &Log) = 0; 47*349cc55cSDimitry Andric 48*349cc55cSDimitry Andric /// Record a line-by-line instruction diff. 49*349cc55cSDimitry Andric virtual void logd(const DiffLogBuilder &Log) = 0; 50*349cc55cSDimitry Andric 51*349cc55cSDimitry Andric protected: ~Consumer()52*349cc55cSDimitry Andric virtual ~Consumer() {} 53*349cc55cSDimitry Andric }; 54*349cc55cSDimitry Andric 55*349cc55cSDimitry Andric class DiffConsumer : public Consumer { 56*349cc55cSDimitry Andric private: 57*349cc55cSDimitry Andric struct DiffContext { DiffContextDiffContext58*349cc55cSDimitry Andric DiffContext(const Value *L, const Value *R) 59*349cc55cSDimitry Andric : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {} 60*349cc55cSDimitry Andric const Value *L; 61*349cc55cSDimitry Andric const Value *R; 62*349cc55cSDimitry Andric bool Differences; 63*349cc55cSDimitry Andric bool IsFunction; 64*349cc55cSDimitry Andric DenseMap<const Value *, unsigned> LNumbering; 65*349cc55cSDimitry Andric DenseMap<const Value *, unsigned> RNumbering; 66*349cc55cSDimitry Andric }; 67*349cc55cSDimitry Andric 68*349cc55cSDimitry Andric raw_ostream &out; 69*349cc55cSDimitry Andric SmallVector<DiffContext, 5> contexts; 70*349cc55cSDimitry Andric bool Differences; 71*349cc55cSDimitry Andric unsigned Indent; 72*349cc55cSDimitry Andric 73*349cc55cSDimitry Andric void printValue(const Value *V, bool isL); 74*349cc55cSDimitry Andric void header(); 75*349cc55cSDimitry Andric void indent(); 76*349cc55cSDimitry Andric 77*349cc55cSDimitry Andric public: DiffConsumer()78*349cc55cSDimitry Andric DiffConsumer() 79*349cc55cSDimitry Andric : out(errs()), Differences(false), Indent(0) {} 80*349cc55cSDimitry Andric 81*349cc55cSDimitry Andric void reset(); 82*349cc55cSDimitry Andric bool hadDifferences() const; 83*349cc55cSDimitry Andric void enterContext(const Value *L, const Value *R) override; 84*349cc55cSDimitry Andric void exitContext() override; 85*349cc55cSDimitry Andric void log(StringRef text) override; 86*349cc55cSDimitry Andric void logf(const LogBuilder &Log) override; 87*349cc55cSDimitry Andric void logd(const DiffLogBuilder &Log) override; 88*349cc55cSDimitry Andric }; 89*349cc55cSDimitry Andric } 90*349cc55cSDimitry Andric 91*349cc55cSDimitry Andric #endif 92