switch the value# in OPC_CompleteMatch and OPC_EmitNode to use a
authorChris Lattner <sabre@nondot.org>
Tue, 23 Feb 2010 00:59:59 +0000 (00:59 +0000)
committerChris Lattner <sabre@nondot.org>
Tue, 23 Feb 2010 00:59:59 +0000 (00:59 +0000)
VBR encoding for the insanity being perpetrated by the spu backend.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@96843 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/CodeGen/DAGISelHeader.h
utils/TableGen/DAGISelMatcherEmitter.cpp

index 29d66f5995496476ce6878d1cf902b7039343bab..d28f4dad044dc93462a5303a1e063a581274ed0e 100644 (file)
@@ -200,6 +200,24 @@ GetInt8(const unsigned char *MatcherTable, unsigned &Idx) {
   return Val;
 }
 
   return Val;
 }
 
+/// GetVBR - decode a vbr encoding whose top bit is set.
+ALWAYS_INLINE static unsigned
+GetVBR(unsigned Val, const unsigned char *MatcherTable, unsigned &Idx) {
+  assert(Val >= 128 && "Not a VBR");
+  Val &= 127;  // Remove first vbr bit.
+  
+  unsigned Shift = 7;
+  unsigned NextBits;
+  do {
+    NextBits = GetInt1(MatcherTable, Idx);
+    Val |= (NextBits&127) << Shift;
+    Shift += 7;
+  } while (NextBits & 128);
+  
+  return Val;
+}
+
+
 enum BuiltinOpcodes {
   OPC_Push, OPC_Push2,
   OPC_RecordNode,
 enum BuiltinOpcodes {
   OPC_Push, OPC_Push2,
   OPC_RecordNode,
@@ -691,6 +709,9 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
       SmallVector<SDValue, 8> Ops;
       for (unsigned i = 0; i != NumOps; ++i) {
         unsigned RecNo = MatcherTable[MatcherIndex++];
       SmallVector<SDValue, 8> Ops;
       for (unsigned i = 0; i != NumOps; ++i) {
         unsigned RecNo = MatcherTable[MatcherIndex++];
+        if (RecNo & 128)
+          RecNo = GetVBR(RecNo, MatcherTable, MatcherIndex);
+        
         assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
         Ops.push_back(RecordedNodes[RecNo]);
       }
         assert(RecNo < RecordedNodes.size() && "Invalid CheckSame");
         Ops.push_back(RecordedNodes[RecNo]);
       }
@@ -763,6 +784,9 @@ SDNode *SelectCodeCommon(SDNode *NodeToMatch, const unsigned char *MatcherTable,
 
       for (unsigned i = 0; i != NumResults; ++i) {
         unsigned ResSlot = MatcherTable[MatcherIndex++];
 
       for (unsigned i = 0; i != NumResults; ++i) {
         unsigned ResSlot = MatcherTable[MatcherIndex++];
+        if (ResSlot & 128)
+          ResSlot = GetVBR(ResSlot, MatcherTable, MatcherIndex);
+        
         assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame");
         SDValue Res = RecordedNodes[ResSlot];
         
         assert(ResSlot < RecordedNodes.size() && "Invalid CheckSame");
         SDValue Res = RecordedNodes[ResSlot];
         
index 33e37fae94957dca2b2501548e93cf3f721ea714..ed720df8081d5781b12eb736679dbdc7a5015837 100644 (file)
@@ -127,6 +127,25 @@ private:
 };
 } // end anonymous namespace.
 
 };
 } // end anonymous namespace.
 
+/// EmitVBRValue - Emit the specified value as a VBR, returning the number of
+/// bytes emitted.
+static unsigned EmitVBRValue(unsigned Val, raw_ostream &OS) {
+  if (Val <= 127) {
+    OS << Val << ", ";
+    return 1;
+  }
+  
+  unsigned InVal = Val;
+  unsigned NumBytes = 0;
+  while (Val > 128) {
+    OS << (Val&127) << "|128,";
+    Val >>= 7;
+    ++NumBytes;
+  }
+  OS << Val << "/*" << InVal << "*/, ";
+  return NumBytes+1;
+}
+
 /// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
 /// the number of bytes emitted.
 unsigned MatcherTableEmitter::
 /// EmitMatcherOpcodes - Emit bytes for the specified matcher and return
 /// the number of bytes emitted.
 unsigned MatcherTableEmitter::
@@ -309,22 +328,27 @@ EmitMatcher(const MatcherNode *N, unsigned Indent, formatted_raw_ostream &OS) {
       OS << getEnumName(EN->getVT(i)) << ", ";
 
     OS << EN->getNumOperands() << "/*#Ops*/, ";
       OS << getEnumName(EN->getVT(i)) << ", ";
 
     OS << EN->getNumOperands() << "/*#Ops*/, ";
-    for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i)
-      OS << EN->getOperand(i) << ", ";
+    unsigned NumOperandBytes = 0;
+    for (unsigned i = 0, e = EN->getNumOperands(); i != e; ++i) {
+      // We emit the operand numbers in VBR encoded format, in case the number
+      // is too large to represent with a byte.
+      NumOperandBytes += EmitVBRValue(EN->getOperand(i), OS);
+    }
     OS << '\n';
     OS << '\n';
-    return 6+EN->getNumVTs()+EN->getNumOperands();
+    return 6+EN->getNumVTs()+NumOperandBytes;
   }
   case MatcherNode::CompleteMatch: {
     const CompleteMatchMatcherNode *CM = cast<CompleteMatchMatcherNode>(N);
     OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
   }
   case MatcherNode::CompleteMatch: {
     const CompleteMatchMatcherNode *CM = cast<CompleteMatchMatcherNode>(N);
     OS << "OPC_CompleteMatch, " << CM->getNumResults() << ", ";
+    unsigned NumResultBytes = 0;
     for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
     for (unsigned i = 0, e = CM->getNumResults(); i != e; ++i)
-      OS << CM->getResult(i) << ", ";
+      NumResultBytes += EmitVBRValue(CM->getResult(i), OS);
     OS << '\n';
     OS.PadToColumn(Indent*2) << "// Src: "
       << *CM->getPattern().getSrcPattern() << '\n';
     OS.PadToColumn(Indent*2) << "// Dst: " 
       << *CM->getPattern().getDstPattern() << '\n';
     OS << '\n';
     OS.PadToColumn(Indent*2) << "// Src: "
       << *CM->getPattern().getSrcPattern() << '\n';
     OS.PadToColumn(Indent*2) << "// Dst: " 
       << *CM->getPattern().getDstPattern() << '\n';
-    return 2+CM->getNumResults();
+    return 2 + NumResultBytes;
   }
   }
   assert(0 && "Unreachable");
   }
   }
   assert(0 && "Unreachable");