[llvm-commits] [llvm] r127627 - in /llvm/trunk/tools/llvm-diff: CMakeLists.txt DiffConsumer.cpp DiffConsumer.h DiffLog.cpp DiffLog.h DifferenceEngine.cpp DifferenceEngine.h llvm-diff.cpp

Renato Golin renato.golin at arm.com
Mon Mar 14 15:22:46 PDT 2011


Author: rengolin
Date: Mon Mar 14 17:22:46 2011
New Revision: 127627

URL: http://llvm.org/viewvc/llvm-project?rev=127627&view=rev
Log:
This patch is a big refactoring of llvm-diff. It doesn't add new features, but it re-organizes the old features, so I can insert the MetadataEngine to use the same infrastructure.

Added:
    llvm/trunk/tools/llvm-diff/DiffConsumer.cpp
    llvm/trunk/tools/llvm-diff/DiffConsumer.h
    llvm/trunk/tools/llvm-diff/DiffLog.cpp
    llvm/trunk/tools/llvm-diff/DiffLog.h
Modified:
    llvm/trunk/tools/llvm-diff/CMakeLists.txt
    llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp
    llvm/trunk/tools/llvm-diff/DifferenceEngine.h
    llvm/trunk/tools/llvm-diff/llvm-diff.cpp

Modified: llvm/trunk/tools/llvm-diff/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/CMakeLists.txt?rev=127627&r1=127626&r2=127627&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-diff/CMakeLists.txt (original)
+++ llvm/trunk/tools/llvm-diff/CMakeLists.txt Mon Mar 14 17:22:46 2011
@@ -2,5 +2,7 @@
 
 add_llvm_tool(llvm-diff
   llvm-diff.cpp
+  DiffConsumer.cpp
+  DiffLog.cpp
   DifferenceEngine.cpp
   )

Added: llvm/trunk/tools/llvm-diff/DiffConsumer.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffConsumer.cpp?rev=127627&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-diff/DiffConsumer.cpp (added)
+++ llvm/trunk/tools/llvm-diff/DiffConsumer.cpp Mon Mar 14 17:22:46 2011
@@ -0,0 +1,209 @@
+//===-- DiffConsumer.cpp - Difference Consumer ------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This files implements the the LLVM difference Consumer
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiffConsumer.h"
+
+#include "llvm/Module.h"
+#include "llvm/Instructions.h"
+#include "llvm/Support/ErrorHandling.h"
+
+using namespace llvm;
+
+static void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering){
+  unsigned IN = 0;
+
+  // Arguments get the first numbers.
+  for (Function::arg_iterator
+         AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI)
+    if (!AI->hasName())
+      Numbering[&*AI] = IN++;
+
+  // Walk the basic blocks in order.
+  for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) {
+    if (!FI->hasName())
+      Numbering[&*FI] = IN++;
+
+    // Walk the instructions in order.
+    for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI)
+      // void instructions don't get numbers.
+      if (!BI->hasName() && !BI->getType()->isVoidTy())
+        Numbering[&*BI] = IN++;
+  }
+
+  assert(!Numbering.empty() && "asked for numbering but numbering was no-op");
+}
+
+
+void DiffConsumer::printValue(Value *V, bool isL) {
+  if (V->hasName()) {
+    out << (isa<GlobalValue>(V) ? '@' : '%') << V->getName();
+    return;
+  }
+  if (V->getType()->isVoidTy()) {
+    if (isa<StoreInst>(V)) {
+      out << "store to ";
+      printValue(cast<StoreInst>(V)->getPointerOperand(), isL);
+    } else if (isa<CallInst>(V)) {
+      out << "call to ";
+      printValue(cast<CallInst>(V)->getCalledValue(), isL);
+    } else if (isa<InvokeInst>(V)) {
+      out << "invoke to ";
+      printValue(cast<InvokeInst>(V)->getCalledValue(), isL);
+    } else {
+      out << *V;
+    }
+    return;
+  }
+
+  unsigned N = contexts.size();
+  while (N > 0) {
+    --N;
+    DiffContext &ctxt = contexts[N];
+    if (!ctxt.IsFunction) continue;
+    if (isL) {
+      if (ctxt.LNumbering.empty())
+        ComputeNumbering(cast<Function>(ctxt.L), ctxt.LNumbering);
+      out << '%' << ctxt.LNumbering[V];
+      return;
+    } else {
+      if (ctxt.RNumbering.empty())
+        ComputeNumbering(cast<Function>(ctxt.R), ctxt.RNumbering);
+      out << '%' << ctxt.RNumbering[V];
+      return;
+    }
+  }
+
+  out << "<anonymous>";
+}
+
+void DiffConsumer::header() {
+  if (contexts.empty()) return;
+  for (SmallVectorImpl<DiffContext>::iterator
+         I = contexts.begin(), E = contexts.end(); I != E; ++I) {
+    if (I->Differences) continue;
+    if (isa<Function>(I->L)) {
+      // Extra newline between functions.
+      if (Differences) out << "\n";
+
+      Function *L = cast<Function>(I->L);
+      Function *R = cast<Function>(I->R);
+      if (L->getName() != R->getName())
+        out << "in function " << L->getName()
+            << " / " << R->getName() << ":\n";
+      else
+        out << "in function " << L->getName() << ":\n";
+    } else if (isa<BasicBlock>(I->L)) {
+      BasicBlock *L = cast<BasicBlock>(I->L);
+      BasicBlock *R = cast<BasicBlock>(I->R);
+      if (L->hasName() && R->hasName() && L->getName() == R->getName())
+        out << "  in block %" << L->getName() << ":\n";
+      else {
+        out << "  in block ";
+        printValue(L, true);
+        out << " / ";
+        printValue(R, false);
+        out << ":\n";
+      }
+    } else if (isa<Instruction>(I->L)) {
+      out << "    in instruction ";
+      printValue(I->L, true);
+      out << " / ";
+      printValue(I->R, false);
+      out << ":\n";
+    }
+
+    I->Differences = true;
+  }
+}
+
+void DiffConsumer::indent() {
+  unsigned N = Indent;
+  while (N--) out << ' ';
+}
+
+bool DiffConsumer::hadDifferences() const {
+  return Differences;
+}
+
+void DiffConsumer::enterContext(Value *L, Value *R) {
+  contexts.push_back(DiffContext(L, R));
+  Indent += 2;
+}
+
+void DiffConsumer::exitContext() {
+  Differences |= contexts.back().Differences;
+  contexts.pop_back();
+  Indent -= 2;
+}
+
+void DiffConsumer::log(StringRef text) {
+  header();
+  indent();
+  out << text << '\n';
+}
+
+void DiffConsumer::logf(const LogBuilder &Log) {
+  header();
+  indent();
+
+  unsigned arg = 0;
+
+  StringRef format = Log.getFormat();
+  while (true) {
+    size_t percent = format.find('%');
+    if (percent == StringRef::npos) {
+      out << format;
+      break;
+    }
+    assert(format[percent] == '%');
+
+    if (percent > 0) out << format.substr(0, percent);
+
+    switch (format[percent+1]) {
+    case '%': out << '%'; break;
+    case 'l': printValue(Log.getArgument(arg++), true); break;
+    case 'r': printValue(Log.getArgument(arg++), false); break;
+    default: llvm_unreachable("unknown format character");
+    }
+
+    format = format.substr(percent+2);
+  }
+
+  out << '\n';
+}
+
+void DiffConsumer::logd(const DiffLogBuilder &Log) {
+  header();
+
+  for (unsigned I = 0, E = Log.getNumLines(); I != E; ++I) {
+    indent();
+    switch (Log.getLineKind(I)) {
+    case DC_match:
+      out << "  ";
+      Log.getLeft(I)->dump();
+      //printValue(Log.getLeft(I), true);
+      break;
+    case DC_left:
+      out << "< ";
+      Log.getLeft(I)->dump();
+      //printValue(Log.getLeft(I), true);
+      break;
+    case DC_right:
+      out << "> ";
+      Log.getRight(I)->dump();
+      //printValue(Log.getRight(I), false);
+      break;
+    }
+    //out << "\n";
+  }
+}

Added: llvm/trunk/tools/llvm-diff/DiffConsumer.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffConsumer.h?rev=127627&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-diff/DiffConsumer.h (added)
+++ llvm/trunk/tools/llvm-diff/DiffConsumer.h Mon Mar 14 17:22:46 2011
@@ -0,0 +1,91 @@
+//===-- DiffConsumer.h - Difference Consumer --------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the interface to the LLVM difference Consumer
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LLVM_DIFFCONSUMER_H_
+#define _LLVM_DIFFCONSUMER_H_
+
+#include "DiffLog.h"
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/StringRef.h"
+#include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/Casting.h"
+
+namespace llvm {
+  class Module;
+  class Value;
+  class Function;
+
+  /// The interface for consumers of difference data.
+  struct Consumer {
+    /// Record that a local context has been entered.  Left and
+    /// Right are IR "containers" of some sort which are being
+    /// considered for structural equivalence: global variables,
+    /// functions, blocks, instructions, etc.
+    virtual void enterContext(Value *Left, Value *Right) = 0;
+
+    /// Record that a local context has been exited.
+    virtual void exitContext() = 0;
+
+    /// Record a difference within the current context.
+    virtual void log(StringRef Text) = 0;
+
+    /// Record a formatted difference within the current context.
+    virtual void logf(const LogBuilder &Log) = 0;
+
+    /// Record a line-by-line instruction diff.
+    virtual void logd(const DiffLogBuilder &Log) = 0;
+
+  protected:
+    virtual ~Consumer() {}
+  };
+
+  class DiffConsumer : public Consumer {
+  private:
+    struct DiffContext {
+      DiffContext(Value *L, Value *R)
+        : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
+      Value *L;
+      Value *R;
+      bool Differences;
+      bool IsFunction;
+      DenseMap<Value*,unsigned> LNumbering;
+      DenseMap<Value*,unsigned> RNumbering;
+    };
+
+    raw_ostream &out;
+    Module *LModule;
+    Module *RModule;
+    SmallVector<DiffContext, 5> contexts;
+    bool Differences;
+    unsigned Indent;
+
+    void printValue(Value *V, bool isL);
+    void header();
+    void indent();
+
+  public:
+    DiffConsumer(Module *L, Module *R)
+      : out(errs()), LModule(L), RModule(R), Differences(false), Indent(0) {}
+
+    bool hadDifferences() const;
+    void enterContext(Value *L, Value *R);
+    void exitContext();
+    void log(StringRef text);
+    void logf(const LogBuilder &Log);
+    void logd(const DiffLogBuilder &Log);
+  };
+}
+
+#endif

Added: llvm/trunk/tools/llvm-diff/DiffLog.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffLog.cpp?rev=127627&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-diff/DiffLog.cpp (added)
+++ llvm/trunk/tools/llvm-diff/DiffLog.cpp Mon Mar 14 17:22:46 2011
@@ -0,0 +1,53 @@
+//===-- DiffLog.h - Difference Log Builder and accessories ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the interface to the LLVM difference log builder.
+//
+//===----------------------------------------------------------------------===//
+
+#include "DiffLog.h"
+#include "DiffConsumer.h"
+
+#include "llvm/Instructions.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+using namespace llvm;
+
+LogBuilder::~LogBuilder() {
+  consumer.logf(*this);
+}
+
+StringRef LogBuilder::getFormat() const { return Format; }
+
+unsigned LogBuilder::getNumArguments() const { return Arguments.size(); }
+Value *LogBuilder::getArgument(unsigned I) const { return Arguments[I]; }
+
+DiffLogBuilder::~DiffLogBuilder() { consumer.logd(*this); }
+
+void DiffLogBuilder::addMatch(Instruction *L, Instruction *R) {
+  Diff.push_back(DiffRecord(L, R));
+}
+void DiffLogBuilder::addLeft(Instruction *L) {
+  // HACK: VS 2010 has a bug in the stdlib that requires this.
+  Diff.push_back(DiffRecord(L, DiffRecord::second_type(0)));
+}
+void DiffLogBuilder::addRight(Instruction *R) {
+  // HACK: VS 2010 has a bug in the stdlib that requires this.
+  Diff.push_back(DiffRecord(DiffRecord::first_type(0), R));
+}
+
+unsigned DiffLogBuilder::getNumLines() const { return Diff.size(); }
+
+DiffChange DiffLogBuilder::getLineKind(unsigned I) const {
+  return (Diff[I].first ? (Diff[I].second ? DC_match : DC_left)
+                        : DC_right);
+}
+Instruction *DiffLogBuilder::getLeft(unsigned I) const { return Diff[I].first; }
+Instruction *DiffLogBuilder::getRight(unsigned I) const { return Diff[I].second; }

Added: llvm/trunk/tools/llvm-diff/DiffLog.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DiffLog.h?rev=127627&view=auto
==============================================================================
--- llvm/trunk/tools/llvm-diff/DiffLog.h (added)
+++ llvm/trunk/tools/llvm-diff/DiffLog.h Mon Mar 14 17:22:46 2011
@@ -0,0 +1,80 @@
+//===-- DiffLog.h - Difference Log Builder and accessories ------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This header defines the interface to the LLVM difference log builder.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef _LLVM_DIFFLOG_H_
+#define _LLVM_DIFFLOG_H_
+
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringRef.h"
+
+namespace llvm {
+  class Instruction;
+  class Value;
+  class Consumer;
+
+  /// Trichotomy assumption
+  enum DiffChange { DC_match, DC_left, DC_right };
+
+  /// A temporary-object class for building up log messages.
+  class LogBuilder {
+    Consumer &consumer;
+
+    /// The use of a stored StringRef here is okay because
+    /// LogBuilder should be used only as a temporary, and as a
+    /// temporary it will be destructed before whatever temporary
+    /// might be initializing this format.
+    StringRef Format;
+
+    SmallVector<Value*, 4> Arguments;
+
+  public:
+    LogBuilder(Consumer &c, StringRef Format)
+      : consumer(c), Format(Format) {}
+
+    LogBuilder &operator<<(Value *V) {
+      Arguments.push_back(V);
+      return *this;
+    }
+
+    ~LogBuilder();
+
+    StringRef getFormat() const;
+    unsigned getNumArguments() const;
+    Value *getArgument(unsigned I) const;
+  };
+
+  /// A temporary-object class for building up diff messages.
+  class DiffLogBuilder {
+    typedef std::pair<Instruction*,Instruction*> DiffRecord;
+    SmallVector<DiffRecord, 20> Diff;
+
+    Consumer &consumer;
+
+  public:
+    DiffLogBuilder(Consumer &c) : consumer(c) {}
+    ~DiffLogBuilder();
+
+    void addMatch(Instruction *L, Instruction *R);
+    // HACK: VS 2010 has a bug in the stdlib that requires this.
+    void addLeft(Instruction *L);
+    void addRight(Instruction *R);
+
+    unsigned getNumLines() const;
+    DiffChange getLineKind(unsigned I) const;
+    Instruction *getLeft(unsigned I) const;
+    Instruction *getRight(unsigned I) const;
+  };
+
+}
+
+#endif

Modified: llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp?rev=127627&r1=127626&r2=127627&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp (original)
+++ llvm/trunk/tools/llvm-diff/DifferenceEngine.cpp Mon Mar 14 17:22:46 2011
@@ -506,30 +506,30 @@
   for (unsigned I = 0; I != NL+1; ++I) {
     Cur[I].Cost = I * LeftCost;
     for (unsigned J = 0; J != I; ++J)
-      Cur[I].Path.push_back(DifferenceEngine::DC_left);
+      Cur[I].Path.push_back(DC_left);
   }
 
   for (BasicBlock::iterator RI = RStart; RI != RE; ++RI) {
     // Initialize the first row.
     Next[0] = Cur[0];
     Next[0].Cost += RightCost;
-    Next[0].Path.push_back(DifferenceEngine::DC_right);
+    Next[0].Path.push_back(DC_right);
 
     unsigned Index = 1;
     for (BasicBlock::iterator LI = LStart; LI != LE; ++LI, ++Index) {
       if (matchForBlockDiff(&*LI, &*RI)) {
         Next[Index] = Cur[Index-1];
         Next[Index].Cost += MatchCost;
-        Next[Index].Path.push_back(DifferenceEngine::DC_match);
+        Next[Index].Path.push_back(DC_match);
         TentativeValues.insert(std::make_pair(&*LI, &*RI));
       } else if (Next[Index-1].Cost <= Cur[Index].Cost) {
         Next[Index] = Next[Index-1];
         Next[Index].Cost += LeftCost;
-        Next[Index].Path.push_back(DifferenceEngine::DC_left);
+        Next[Index].Path.push_back(DC_left);
       } else {
         Next[Index] = Cur[Index];
         Next[Index].Cost += RightCost;
-        Next[Index].Path.push_back(DifferenceEngine::DC_right);
+        Next[Index].Path.push_back(DC_right);
       }
     }
 
@@ -543,23 +543,23 @@
   SmallVectorImpl<char> &Path = Cur[NL].Path;
   BasicBlock::iterator LI = LStart, RI = RStart;
 
-  DifferenceEngine::DiffLogBuilder Diff(Engine);
+  DiffLogBuilder Diff(Engine.getConsumer());
 
   // Drop trailing matches.
-  while (Path.back() == DifferenceEngine::DC_match)
+  while (Path.back() == DC_match)
     Path.pop_back();
 
   // Skip leading matches.
   SmallVectorImpl<char>::iterator
     PI = Path.begin(), PE = Path.end();
-  while (PI != PE && *PI == DifferenceEngine::DC_match) {
+  while (PI != PE && *PI == DC_match) {
     unify(&*LI, &*RI);
     ++PI, ++LI, ++RI;
   }
 
   for (; PI != PE; ++PI) {
-    switch (static_cast<DifferenceEngine::DiffChange>(*PI)) {
-    case DifferenceEngine::DC_match:
+    switch (static_cast<DiffChange>(*PI)) {
+    case DC_match:
       assert(LI != LE && RI != RE);
       {
         Instruction *L = &*LI, *R = &*RI;
@@ -569,13 +569,13 @@
       ++LI; ++RI;
       break;
 
-    case DifferenceEngine::DC_left:
+    case DC_left:
       assert(LI != LE);
       Diff.addLeft(&*LI);
       ++LI;
       break;
 
-    case DifferenceEngine::DC_right:
+    case DC_right:
       assert(RI != RE);
       Diff.addRight(&*RI);
       ++RI;

Modified: llvm/trunk/tools/llvm-diff/DifferenceEngine.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/DifferenceEngine.h?rev=127627&r1=127626&r2=127627&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-diff/DifferenceEngine.h (original)
+++ llvm/trunk/tools/llvm-diff/DifferenceEngine.h Mon Mar 14 17:22:46 2011
@@ -17,6 +17,8 @@
 
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
+#include "DiffLog.h"
+#include "DiffConsumer.h"
 
 #include <utility>
 
@@ -32,95 +34,6 @@
   /// A class for performing structural comparisons of LLVM assembly.
   class DifferenceEngine {
   public:
-    /// A temporary-object class for building up log messages.
-    class LogBuilder {
-      DifferenceEngine &Engine;
-
-      /// The use of a stored StringRef here is okay because
-      /// LogBuilder should be used only as a temporary, and as a
-      /// temporary it will be destructed before whatever temporary
-      /// might be initializing this format.
-      StringRef Format;
-
-      SmallVector<Value*, 4> Arguments;
-
-    public:
-      LogBuilder(DifferenceEngine &Engine, StringRef Format)
-        : Engine(Engine), Format(Format) {}
-
-      LogBuilder &operator<<(Value *V) {
-        Arguments.push_back(V);
-        return *this;
-      }
-
-      ~LogBuilder() {
-        Engine.consumer.logf(*this);
-      }
-
-      StringRef getFormat() const { return Format; }
-
-      unsigned getNumArguments() const { return Arguments.size(); }
-      Value *getArgument(unsigned I) const { return Arguments[I]; }
-    };
-
-    enum DiffChange { DC_match, DC_left, DC_right };
-
-    /// A temporary-object class for building up diff messages.
-    class DiffLogBuilder {
-      typedef std::pair<Instruction*,Instruction*> DiffRecord;
-      SmallVector<DiffRecord, 20> Diff;
-
-      DifferenceEngine &Engine;
-
-    public:
-      DiffLogBuilder(DifferenceEngine &Engine) : Engine(Engine) {}
-      ~DiffLogBuilder() { Engine.consumer.logd(*this); }
-
-      void addMatch(Instruction *L, Instruction *R) {
-        Diff.push_back(DiffRecord(L, R));
-      }
-      void addLeft(Instruction *L) {
-        // HACK: VS 2010 has a bug in the stdlib that requires this.
-        Diff.push_back(DiffRecord(L, DiffRecord::second_type(0)));
-      }
-      void addRight(Instruction *R) {
-        // HACK: VS 2010 has a bug in the stdlib that requires this.
-        Diff.push_back(DiffRecord(DiffRecord::first_type(0), R));
-      }
-
-      unsigned getNumLines() const { return Diff.size(); }
-      DiffChange getLineKind(unsigned I) const {
-        return (Diff[I].first ? (Diff[I].second ? DC_match : DC_left)
-                              : DC_right);
-      }
-      Instruction *getLeft(unsigned I) const { return Diff[I].first; }
-      Instruction *getRight(unsigned I) const { return Diff[I].second; }
-    };
-
-    /// The interface for consumers of difference data.
-    struct Consumer {
-      /// Record that a local context has been entered.  Left and
-      /// Right are IR "containers" of some sort which are being
-      /// considered for structural equivalence: global variables,
-      /// functions, blocks, instructions, etc.
-      virtual void enterContext(Value *Left, Value *Right) = 0;
-
-      /// Record that a local context has been exited.
-      virtual void exitContext() = 0;
-
-      /// Record a difference within the current context.
-      virtual void log(StringRef Text) = 0;
-
-      /// Record a formatted difference within the current context.
-      virtual void logf(const LogBuilder &Log) = 0;
-
-      /// Record a line-by-line instruction diff.
-      virtual void logd(const DiffLogBuilder &Log) = 0;
-
-    protected:
-      virtual ~Consumer() {}
-    };
-
     /// A RAII object for recording the current context.
     struct Context {
       Context(DifferenceEngine &Engine, Value *L, Value *R) : Engine(Engine) {
@@ -149,14 +62,13 @@
 
     void diff(Module *L, Module *R);
     void diff(Function *L, Function *R);
-
     void log(StringRef text) {
       consumer.log(text);
     }
-
     LogBuilder logf(StringRef text) {
-      return LogBuilder(*this, text);
+      return LogBuilder(consumer, text);
     }
+    Consumer& getConsumer() const { return consumer; }
 
     /// Installs an oracle to decide whether two global values are
     /// equivalent as operands.  Without an oracle, global values are

Modified: llvm/trunk/tools/llvm-diff/llvm-diff.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/tools/llvm-diff/llvm-diff.cpp?rev=127627&r1=127626&r2=127627&view=diff
==============================================================================
--- llvm/trunk/tools/llvm-diff/llvm-diff.cpp (original)
+++ llvm/trunk/tools/llvm-diff/llvm-diff.cpp Mon Mar 14 17:22:46 2011
@@ -11,9 +11,9 @@
 //
 //===----------------------------------------------------------------------===//
 
+#include "DiffLog.h"
 #include "DifferenceEngine.h"
 
-#include "llvm/Instructions.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Type.h"
@@ -21,7 +21,6 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/Support/CommandLine.h"
-#include "llvm/Support/ErrorHandling.h"
 #include "llvm/Support/IRReader.h"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/raw_ostream.h"
@@ -43,221 +42,6 @@
   return M;
 }
 
-namespace {
-  struct DiffContext {
-    DiffContext(Value *L, Value *R)
-      : L(L), R(R), Differences(false), IsFunction(isa<Function>(L)) {}
-    Value *L;
-    Value *R;
-    bool Differences;
-    bool IsFunction;
-    DenseMap<Value*,unsigned> LNumbering;
-    DenseMap<Value*,unsigned> RNumbering;
-  };
-}
-
-static void ComputeNumbering(Function *F, DenseMap<Value*,unsigned> &Numbering){
-  unsigned IN = 0;
-
-  // Arguments get the first numbers.
-  for (Function::arg_iterator
-         AI = F->arg_begin(), AE = F->arg_end(); AI != AE; ++AI)
-    if (!AI->hasName())
-      Numbering[&*AI] = IN++;
-
-  // Walk the basic blocks in order.
-  for (Function::iterator FI = F->begin(), FE = F->end(); FI != FE; ++FI) {
-    if (!FI->hasName())
-      Numbering[&*FI] = IN++;
-
-    // Walk the instructions in order.
-    for (BasicBlock::iterator BI = FI->begin(), BE = FI->end(); BI != BE; ++BI)
-      // void instructions don't get numbers.
-      if (!BI->hasName() && !BI->getType()->isVoidTy())
-        Numbering[&*BI] = IN++;
-  }
-
-  assert(!Numbering.empty() && "asked for numbering but numbering was no-op");
-}
-
-namespace {
-class DiffConsumer : public DifferenceEngine::Consumer {
-private:
-  raw_ostream &out;
-  Module *LModule;
-  Module *RModule;
-  SmallVector<DiffContext, 5> contexts;
-  bool Differences;
-  unsigned Indent;
-
-  void printValue(Value *V, bool isL) {
-    if (V->hasName()) {
-      out << (isa<GlobalValue>(V) ? '@' : '%') << V->getName();
-      return;
-    }
-    if (V->getType()->isVoidTy()) {
-      if (isa<StoreInst>(V)) {
-        out << "store to ";
-        printValue(cast<StoreInst>(V)->getPointerOperand(), isL);
-      } else if (isa<CallInst>(V)) {
-        out << "call to ";
-        printValue(cast<CallInst>(V)->getCalledValue(), isL);
-      } else if (isa<InvokeInst>(V)) {
-        out << "invoke to ";
-        printValue(cast<InvokeInst>(V)->getCalledValue(), isL);
-      } else {
-        out << *V;
-      }
-      return;
-    }
-
-    unsigned N = contexts.size();
-    while (N > 0) {
-      --N;
-      DiffContext &ctxt = contexts[N];
-      if (!ctxt.IsFunction) continue;
-      if (isL) {
-        if (ctxt.LNumbering.empty())
-          ComputeNumbering(cast<Function>(ctxt.L), ctxt.LNumbering);
-        out << '%' << ctxt.LNumbering[V];
-        return;
-      } else {
-        if (ctxt.RNumbering.empty())
-          ComputeNumbering(cast<Function>(ctxt.R), ctxt.RNumbering);
-        out << '%' << ctxt.RNumbering[V];
-        return;
-      }
-    }
-
-    out << "<anonymous>";
-  }
-
-  void header() {
-    if (contexts.empty()) return;
-    for (SmallVectorImpl<DiffContext>::iterator
-           I = contexts.begin(), E = contexts.end(); I != E; ++I) {
-      if (I->Differences) continue;
-      if (isa<Function>(I->L)) {
-        // Extra newline between functions.
-        if (Differences) out << "\n";
-
-        Function *L = cast<Function>(I->L);
-        Function *R = cast<Function>(I->R);
-        if (L->getName() != R->getName())
-          out << "in function " << L->getName()
-              << " / " << R->getName() << ":\n";
-        else
-          out << "in function " << L->getName() << ":\n";
-      } else if (isa<BasicBlock>(I->L)) {
-        BasicBlock *L = cast<BasicBlock>(I->L);
-        BasicBlock *R = cast<BasicBlock>(I->R);
-        if (L->hasName() && R->hasName() && L->getName() == R->getName())
-          out << "  in block %" << L->getName() << ":\n";
-        else {
-          out << "  in block ";
-          printValue(L, true);
-          out << " / ";
-          printValue(R, false);
-          out << ":\n";
-        }
-      } else if (isa<Instruction>(I->L)) {
-        out << "    in instruction ";
-        printValue(I->L, true);
-        out << " / ";
-        printValue(I->R, false);
-        out << ":\n";
-      }
-
-      I->Differences = true;
-    }
-  }
-
-  void indent() {
-    unsigned N = Indent;
-    while (N--) out << ' ';
-  }
-
-public:
-  DiffConsumer(Module *L, Module *R)
-    : out(errs()), LModule(L), RModule(R), Differences(false), Indent(0) {}
-
-  bool hadDifferences() const { return Differences; }
-
-  void enterContext(Value *L, Value *R) {
-    contexts.push_back(DiffContext(L, R));
-    Indent += 2;
-  }
-  void exitContext() {
-    Differences |= contexts.back().Differences;
-    contexts.pop_back();
-    Indent -= 2;
-  }
-
-  void log(StringRef text) {
-    header();
-    indent();
-    out << text << '\n';
-  }
-
-  void logf(const DifferenceEngine::LogBuilder &Log) {
-    header();
-    indent();
-
-    unsigned arg = 0;
-
-    StringRef format = Log.getFormat();
-    while (true) {
-      size_t percent = format.find('%');
-      if (percent == StringRef::npos) {
-        out << format;
-        break;
-      }
-      assert(format[percent] == '%');
-
-      if (percent > 0) out << format.substr(0, percent);
-
-      switch (format[percent+1]) {
-      case '%': out << '%'; break;
-      case 'l': printValue(Log.getArgument(arg++), true); break;
-      case 'r': printValue(Log.getArgument(arg++), false); break;
-      default: llvm_unreachable("unknown format character");
-      }
-
-      format = format.substr(percent+2);
-    }
-
-    out << '\n';
-  }
-
-  void logd(const DifferenceEngine::DiffLogBuilder &Log) {
-    header();
-
-    for (unsigned I = 0, E = Log.getNumLines(); I != E; ++I) {
-      indent();
-      switch (Log.getLineKind(I)) {
-      case DifferenceEngine::DC_match:
-        out << "  ";
-        Log.getLeft(I)->dump();
-        //printValue(Log.getLeft(I), true);
-        break;
-      case DifferenceEngine::DC_left:
-        out << "< ";
-        Log.getLeft(I)->dump();
-        //printValue(Log.getLeft(I), true);
-        break;
-      case DifferenceEngine::DC_right:
-        out << "> ";
-        Log.getRight(I)->dump();
-        //printValue(Log.getRight(I), false);
-        break;
-      }
-      //out << "\n";
-    }
-  }
-  
-};
-} // end anonymous namespace
-
 static void diffGlobal(DifferenceEngine &Engine, Module *L, Module *R,
                        StringRef Name) {
   // Drop leading sigils from the global name.





More information about the llvm-commits mailing list