17d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===-- DiffConsumer.h - Difference Consumer --------------------*- C++ -*-===//
27d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
37d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//                     The LLVM Compiler Infrastructure
47d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
57d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// This file is distributed under the University of Illinois Open Source
67d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// License. See LICENSE.TXT for details.
77d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
87d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===----------------------------------------------------------------------===//
97d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
107d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin// This header defines the interface to the LLVM difference Consumer
117d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//
127d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin//===----------------------------------------------------------------------===//
137d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
1437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#ifndef LLVM_TOOLS_LLVM_DIFF_DIFFCONSUMER_H
1537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#define LLVM_TOOLS_LLVM_DIFF_DIFFCONSUMER_H
167d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
177d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "DiffLog.h"
187d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "llvm/ADT/DenseMap.h"
19f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/ADT/SmallVector.h"
207d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "llvm/ADT/StringRef.h"
217d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#include "llvm/Support/Casting.h"
22f010c464a11444733ec67e31aace8bcebeaf2588Chandler Carruth#include "llvm/Support/raw_ostream.h"
237d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
247d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golinnamespace llvm {
257d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class Module;
267d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class Value;
277d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class Function;
287d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
297d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  /// The interface for consumers of difference data.
30875c3ffcc992efd21e3a54bae36b1961ff0f8333Francois Pichet  class Consumer {
312d24e2a396a1d211baaeedf32148a3b657240170David Blaikie    virtual void anchor();
32875c3ffcc992efd21e3a54bae36b1961ff0f8333Francois Pichet  public:
337d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// Record that a local context has been entered.  Left and
347d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// Right are IR "containers" of some sort which are being
357d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// considered for structural equivalence: global variables,
367d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// functions, blocks, instructions, etc.
377d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    virtual void enterContext(Value *Left, Value *Right) = 0;
387d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
397d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// Record that a local context has been exited.
407d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    virtual void exitContext() = 0;
417d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
427d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// Record a difference within the current context.
437d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    virtual void log(StringRef Text) = 0;
447d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
457d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// Record a formatted difference within the current context.
467d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    virtual void logf(const LogBuilder &Log) = 0;
477d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
487d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    /// Record a line-by-line instruction diff.
497d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    virtual void logd(const DiffLogBuilder &Log) = 0;
507d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
517d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  protected:
527d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    virtual ~Consumer() {}
537d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  };
547d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
557d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  class DiffConsumer : public Consumer {
567d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  private:
577d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    struct DiffContext {
587d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      DiffContext(Value *L, Value *R)
597d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin        : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
607d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Value *L;
617d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      Value *R;
627d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      bool Differences;
637d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      bool IsFunction;
647d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      DenseMap<Value*,unsigned> LNumbering;
657d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin      DenseMap<Value*,unsigned> RNumbering;
667d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    };
677d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
687d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    raw_ostream &out;
697d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    SmallVector<DiffContext, 5> contexts;
707d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    bool Differences;
717d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    unsigned Indent;
727d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
737d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    void printValue(Value *V, bool isL);
747d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    void header();
757d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    void indent();
767d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
777d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  public:
78a7542d5f870c5d98960d1676e23ac1d1d975d7e5Benjamin Kramer    DiffConsumer()
79a7542d5f870c5d98960d1676e23ac1d1d975d7e5Benjamin Kramer      : out(errs()), Differences(false), Indent(0) {}
807d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
817d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin    bool hadDifferences() const;
8236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void enterContext(Value *L, Value *R) override;
8336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void exitContext() override;
8436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void log(StringRef text) override;
8536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void logf(const LogBuilder &Log) override;
8636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines    void logd(const DiffLogBuilder &Log) override;
877d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin  };
887d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin}
897d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin
907d4fc4fb345ee8a1de15c718a854b5f38c1e6e46Renato Golin#endif
91