From c4457bdb4677cff61e1b33b6d2c9ed767d56fbd1 Mon Sep 17 00:00:00 2001
From: Jonas Paulsson <jonas.paulsson@ericsson.com>
Date: Thu, 22 Jan 2015 08:54:04 +0100
Subject: [PATCH] Verbose PBQP dump output.

DEBUG_WITH_TYPE used in pbqp files instead of DEBUG, to avoid conflict with
arm backend.

This is very new and unpolished.
---
 include/llvm/CodeGen/PBQP/Graph.h          | 52 +++++++++++++++++++++++++++---
 include/llvm/CodeGen/PBQP/ReductionRules.h | 24 ++++++++++++++
 include/llvm/CodeGen/RegAllocPBQP.h        | 49 ++++++++++++++++++++++++++++
 3 files changed, 121 insertions(+), 4 deletions(-)

diff --git a/include/llvm/CodeGen/PBQP/Graph.h b/include/llvm/CodeGen/PBQP/Graph.h
index 4dc5674..71a1656 100644
--- a/include/llvm/CodeGen/PBQP/Graph.h
+++ b/include/llvm/CodeGen/PBQP/Graph.h
@@ -15,6 +15,7 @@
 #ifndef LLVM_CODEGEN_PBQP_GRAPH_H
 #define LLVM_CODEGEN_PBQP_GRAPH_H
 
+#include "llvm/CodeGen/MachineRegisterInfo.h"
 #include "llvm/ADT/ilist.h"
 #include "llvm/ADT/ilist_node.h"
 #include "llvm/Support/Debug.h"
@@ -673,14 +674,32 @@ namespace PBQP {
       FreeEdgeIds.clear();
     }
 
+    void dumpVRegAndRC(unsigned NId) {
+      const MachineRegisterInfo &MRI = getMetadata().MF.getRegInfo();
+      unsigned VirtReg = getNodeMetadata(NId).getVReg();
+      unsigned RegIndex = (VirtReg & ~(1u << 31));
+      const TargetRegisterClass *RC = MRI.getRegClass(VirtReg);
+      const char *RCName = MRI.getTargetRegisterInfo()->getRegClassName(RC);
+      dbgs() << "(%vreg"<< RegIndex << ", " << RCName << ") ";
+    }
+
     /// @brief Dump a graph to an output stream.
     template <typename OStream>
     void dumpToStream(OStream &OS) {
-      OS << nodeIds().size() << " " << edgeIds().size() << "\n";
+      const MachineRegisterInfo &MRI = getMetadata().MF.getRegInfo();
+
+      OS << "Num nodes: " << nodeIds().size() << ", Num edges: " << edgeIds().size() << "\n";
 
       for (auto NId : nodeIds()) {
         const Vector& V = getNodeCosts(NId);
-        OS << "\n" << V.getLength() << "\n";
+        unsigned VirtReg = getNodeMetadata(NId).getVReg();
+        unsigned RegIndex = (VirtReg & ~(1u << 31));
+        const TargetRegisterClass *RC = MRI.getRegClass(VirtReg);
+        const char *RCName = MRI.getTargetRegisterInfo()->getRegClassName(RC);
+
+        OS << "\n" << "NId " << NId << "(%vreg"<< RegIndex << ", " << RCName
+           << "), cost vector (length " << V.getLength() << "): \n";
+
         assert(V.getLength() != 0 && "Empty vector in graph.");
         OS << V[0];
         for (unsigned i = 1; i < V.getLength(); ++i) {
@@ -694,8 +713,8 @@ namespace PBQP {
         NodeId N2Id = getEdgeNode2Id(EId);
         assert(N1Id != N2Id && "PBQP graphs shound not have self-edges.");
         const Matrix& M = getEdgeCosts(EId);
-        OS << "\n" << N1Id << " " << N2Id << "\n"
-           << M.getRows() << " " << M.getCols() << "\n";
+        OS << "\nEdge between nodes (" << N1Id << ", " << N2Id << ")\n"
+           << "Rows: " << M.getRows() << ", Cols: " << M.getCols() << "\n";
         assert(M.getRows() != 0 && "No rows in matrix.");
         assert(M.getCols() != 0 && "No cols in matrix.");
         for (unsigned i = 0; i < M.getRows(); ++i) {
@@ -708,6 +727,31 @@ namespace PBQP {
       }
     }
 
+    void dumpNodeCosts(unsigned NId) {
+      const Vector& V = getNodeCosts(NId);
+      dbgs() << V[0];
+      for (unsigned i = 1; i < V.getLength(); ++i)
+        dbgs() << " " << V[i];
+    }
+
+    void dumpEdgeCosts(unsigned EId) {
+      NodeId N1Id = getEdgeNode1Id(EId);
+      NodeId N2Id = getEdgeNode2Id(EId);
+      assert(N1Id != N2Id && "PBQP graphs shound not have self-edges.");
+      const Matrix& M = getEdgeCosts(EId);
+      dbgs() << "\nEdge between nodes (" << N1Id << ", " << N2Id << ")\n"
+         << "Rows: " << M.getRows() << ", Cols: " << M.getCols() << "\n";
+      assert(M.getRows() != 0 && "No rows in matrix.");
+      assert(M.getCols() != 0 && "No cols in matrix.");
+      for (unsigned i = 0; i < M.getRows(); ++i) {
+        dbgs() << M[i][0];
+        for (unsigned j = 1; j < M.getCols(); ++j) {
+          dbgs() << " " << M[i][j];
+        }
+        dbgs() << "\n";
+      }
+    }
+
     /// @brief Dump this graph to dbgs().
     void dump() {
       dumpToStream(dbgs());
diff --git a/include/llvm/CodeGen/PBQP/ReductionRules.h b/include/llvm/CodeGen/PBQP/ReductionRules.h
index 3f78025..e860d59 100644
--- a/include/llvm/CodeGen/PBQP/ReductionRules.h
+++ b/include/llvm/CodeGen/PBQP/ReductionRules.h
@@ -43,6 +43,8 @@ namespace PBQP {
     const Vector &XCosts = G.getNodeCosts(NId);
     RawVector YCosts = G.getNodeCosts(MId);
 
+    DEBUG_WITH_TYPE("regalloc", dbgs() << "* Applied R1(NId " << NId << ")");
+
     // Duplicate a little to avoid transposing matrices.
     if (NId == G.getEdgeNode1Id(EId)) {
       for (unsigned j = 0; j < YCosts.getLength(); ++j) {
@@ -66,6 +68,11 @@ namespace PBQP {
       }
     }
     G.setNodeCosts(MId, YCosts);
+
+    DEBUG_WITH_TYPE("regalloc", dbgs() << ", new NodeCosts for MId " << MId
+                    << ":\n");
+    DEBUG_WITH_TYPE("regalloc", G.dumpNodeCosts(MId); dbgs() << "\n");
+
     G.disconnectEdge(EId, MId);
   }
 
@@ -127,6 +134,8 @@ namespace PBQP {
 
     EdgeId YZEId = G.findEdge(YNId, ZNId);
 
+    DEBUG_WITH_TYPE("regalloc", dbgs() << "* Applied R2(NId " << NId << ")");
+
     if (YZEId == G.invalidEdgeId()) {
       YZEId = G.addEdge(YNId, ZNId, Delta);
     } else {
@@ -138,6 +147,9 @@ namespace PBQP {
       }
     }
 
+    DEBUG_WITH_TYPE("regalloc", dbgs() << ", new Edge costs:");
+    DEBUG_WITH_TYPE("regalloc", G.dumpEdgeCosts(YZEId));
+
     G.disconnectEdge(YXEId, YNId);
     G.disconnectEdge(ZXEId, ZNId);
 
@@ -167,9 +179,13 @@ namespace PBQP {
 
     Solution s;
 
+    DEBUG_WITH_TYPE("regalloc", dbgs() << "\nBack propagation:\n";);
+
     while (!stack.empty()) {
       NodeId NId = stack.back();
       stack.pop_back();
+      DEBUG_WITH_TYPE("regalloc", dbgs() << "Popped NId " << NId;);
+      DEBUG_WITH_TYPE("regalloc", G.dumpVRegAndRC(NId));
 
       RawVector v = G.getNodeCosts(NId);
 
@@ -184,11 +200,19 @@ namespace PBQP {
         }
       }
 
+      DEBUG_WITH_TYPE("regalloc", dbgs() << ", all edge costs added:\n";
+            dbgs() << v[0];
+            for (unsigned idx = 1; idx < v.getLength(); ++ idx)
+              dbgs() << " " << v[idx];);
+
       s.setSelection(NId, v.minIndex());
+      DEBUG_WITH_TYPE("regalloc", dbgs() << " ** selection: "
+                      << s.getSelection(NId) << "\n");
       if (s.getSelection(NId) == 0)
         assert (PushedAsConservativelyAllocatableNodes.find(NId) ==
                 PushedAsConservativelyAllocatableNodes.end() &&
                 "Node in conservatively allocatable set spilled!");
+
     }
 
     return s;
diff --git a/include/llvm/CodeGen/RegAllocPBQP.h b/include/llvm/CodeGen/RegAllocPBQP.h
index 278a799..64b873d 100644
--- a/include/llvm/CodeGen/RegAllocPBQP.h
+++ b/include/llvm/CodeGen/RegAllocPBQP.h
@@ -21,6 +21,7 @@
 #include "llvm/CodeGen/PBQP/ReductionRules.h"
 #include "llvm/CodeGen/PBQPRAConstraint.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/Debug.h"
 
 namespace llvm {
 namespace PBQP {
@@ -269,6 +270,9 @@ public:
        &OptUnsafeEdges[NumOpts]);
   }
 
+  // for debugging output
+  unsigned getDeniedOpts(void) {return DeniedOpts;}
+
 private:
   ReductionState RS;
   unsigned NumOpts;
@@ -327,7 +331,18 @@ public:
   void handleDisconnectEdge(EdgeId EId, NodeId NId) {
     NodeMetadata& NMd = G.getNodeMetadata(NId);
     const MatrixMetadata& MMd = G.getEdgeCosts(EId).getMetadata();
+
+    NodeId MId = (NId == G.getEdgeNode1Id(EId) ? G.getEdgeNode2Id(EId) :
+                  G.getEdgeNode1Id(EId));
+    DEBUG_WITH_TYPE("regalloc", dbgs() << "handleDisconnectEdge(" << NId
+                    << ", " << MId << ") "
+                    << ": DeniedOpts " << NMd.getDeniedOpts());
+
     NMd.handleRemoveEdge(MMd, NId == G.getEdgeNode2Id(EId));
+
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " -> "
+                    << NMd.getDeniedOpts() << "\n");
+
     if (G.getNodeDegree(NId) == 3) {
       // This node is becoming optimally reducible.
       moveToOptimallyReducibleNodes(NId);
@@ -342,7 +357,16 @@ public:
   void handleReconnectEdge(EdgeId EId, NodeId NId) {
     NodeMetadata& NMd = G.getNodeMetadata(NId);
     const MatrixMetadata& MMd = G.getEdgeCosts(EId).getMetadata();
+
+    NodeId MId = (NId == G.getEdgeNode1Id(EId) ? G.getEdgeNode2Id(EId) :
+                  G.getEdgeNode1Id(EId));
+    DEBUG_WITH_TYPE("regalloc", dbgs() << "handleReconnectEdge(" << NId
+                    << ", " << MId << ") "
+                    << ": DeniedOpts " << NMd.getDeniedOpts());
+
     NMd.handleAddEdge(MMd, NId == G.getEdgeNode2Id(EId));
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " -> "
+                    << NMd.getDeniedOpts() << "\n");
   }
 
   void handleSetEdgeCosts(EdgeId EId, const Matrix& NewCosts) {
@@ -388,6 +412,9 @@ private:
     OptimallyReducibleNodes.insert(NId);
     G.getNodeMetadata(NId).setReductionState(
       NodeMetadata::OptimallyReducible);
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " NId " << NId;);
+    DEBUG_WITH_TYPE("regalloc", G.dumpVRegAndRC(NId));
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " moved to optimally-reducibles.\n";);
   }
 
   void moveToConservativelyAllocatableNodes(NodeId NId) {
@@ -395,6 +422,9 @@ private:
     ConservativelyAllocatableNodes.insert(NId);
     G.getNodeMetadata(NId).setReductionState(
       NodeMetadata::ConservativelyAllocatable);
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " NId " << NId;);
+    DEBUG_WITH_TYPE("regalloc", G.dumpVRegAndRC(NId));
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " moved to conservatively-allocatables.\n";);
   }
 
   void moveToNotProvablyAllocatableNodes(NodeId NId) {
@@ -402,6 +432,9 @@ private:
     NotProvablyAllocatableNodes.insert(NId);
     G.getNodeMetadata(NId).setReductionState(
       NodeMetadata::NotProvablyAllocatable);
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " NId " << NId;);
+    DEBUG_WITH_TYPE("regalloc", G.dumpVRegAndRC(NId));
+    DEBUG_WITH_TYPE("regalloc", dbgs() << " moved to not-provably-allocables.\n";);
   }
 
   void setup() {
@@ -437,6 +470,7 @@ private:
         NodeStack.push_back(NId);
         switch (G.getNodeDegree(NId)) {
         case 0:
+          DEBUG_WITH_TYPE("regalloc", dbgs() << "(Degree 0)\n";);
           break;
         case 1:
           applyR1(G, NId);
@@ -446,6 +480,11 @@ private:
           break;
         default: llvm_unreachable("Not an optimally reducible node.");
         }
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "From optimally reducibles: ");
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "NId " << NId);
+        DEBUG_WITH_TYPE("regalloc", G.dumpVRegAndRC(NId));
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "pushed on NodeStack. NodeCosts:\n";);
+        DEBUG_WITH_TYPE("regalloc", G.dumpNodeCosts(NId); dbgs() << "\n";);
       } else if (!ConservativelyAllocatableNodes.empty()) {
         // Conservatively allocatable nodes will never spill. For now just
         // take the first node in the set and push it on the stack. When we
@@ -457,6 +496,11 @@ private:
         NodeId NId = *NItr;
         ConservativelyAllocatableNodes.erase(NItr);
         NodeStack.push_back(NId);
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "From conservatively allocatable: ");
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "NId " << NId);
+        DEBUG_WITH_TYPE("regalloc", G.dumpVRegAndRC(NId));
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "pushed on NodeStack. NodeCosts:\n";);
+        DEBUG_WITH_TYPE("regalloc", G.dumpNodeCosts(NId); dbgs() << "\n";);
         G.disconnectAllNeighborsFromNode(NId);
 
         // Remember this, to assert that it is not spilled later.
@@ -469,6 +513,11 @@ private:
         NodeId NId = *NItr;
         NotProvablyAllocatableNodes.erase(NItr);
         NodeStack.push_back(NId);
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "From not provably allocatable: ");
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "NId " << NId);
+        DEBUG_WITH_TYPE("regalloc", G.dumpVRegAndRC(NId));
+        DEBUG_WITH_TYPE("regalloc", dbgs() << "pushed on NodeStack. NodeCosts:\n";);
+        DEBUG_WITH_TYPE("regalloc", G.dumpNodeCosts(NId); dbgs() << "\n";);
         G.disconnectAllNeighborsFromNode(NId);
       } else
         break;
-- 
1.8.4.2

