[PATCH] [Review Request] Improve getVTList() in SelectionDAG

Wan, Xiaofei xiaofei.wan at intel.com
Thu Jul 11 01:10:20 PDT 2013


In current SelectionDAG::getVTList(), linear search used which is not efficient, especially for BC file with many types. This patch use a simple hashing to accelerate the type searching.

http://llvm-reviews.chandlerc.com/D1127

Files:
  lib/CodeGen/SelectionDAG/SelectionDAG.cpp
  include/llvm/CodeGen/ValueTypes.h
  include/llvm/CodeGen/SelectionDAG.h

Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -4851,8 +4851,10 @@
 }
 
 SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2) {
-  for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
-       E = VTList.rend(); I != E; ++I)
+  unsigned slot = (unsigned)(VT1.getRawBits() + VT2.getRawBits());  
+ slot %= VTSlotSize;  for (VTListType::reverse_iterator I = 
+ VTListSlots[slot].rbegin(),
+       E = VTListSlots[slot].rend(); I != E; ++I)
     if (I->NumVTs == 2 && I->VTs[0] == VT1 && I->VTs[1] == VT2)
       return *I;
 
@@ -4860,13 +4862,15 @@
   Array[0] = VT1;
   Array[1] = VT2;
   SDVTList Result = makeVTList(Array, 2);
-  VTList.push_back(Result);
+  VTListSlots[slot].push_back(Result);
   return Result;
 }
 
 SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3) {
-  for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
-       E = VTList.rend(); I != E; ++I)
+  unsigned slot = (unsigned)(VT1.getRawBits() ^ VT2.getRawBits() ^ 
+ VT3.getRawBits());  slot %= VTSlotSize;  for 
+ (VTListType::reverse_iterator I = VTListSlots[slot].rbegin(),
+       E = VTListSlots[slot].rend(); I != E; ++I)
     if (I->NumVTs == 3 && I->VTs[0] == VT1 && I->VTs[1] == VT2 &&
                           I->VTs[2] == VT3)
       return *I;
@@ -4876,13 +4880,15 @@
   Array[1] = VT2;
   Array[2] = VT3;
   SDVTList Result = makeVTList(Array, 3);
-  VTList.push_back(Result);
+  VTListSlots[slot].push_back(Result);
   return Result;
 }
 
 SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4) {
-  for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
-       E = VTList.rend(); I != E; ++I)
+  unsigned slot = (unsigned)((VT1.getRawBits() + VT3.getRawBits()) ^ 
+ (VT2.getRawBits() ^ VT4.getRawBits()));  slot %= VTSlotSize;  for 
+ (VTListType::reverse_iterator I = VTListSlots[slot].rbegin(),
+       E = VTListSlots[slot].rend(); I != E; ++I)
     if (I->NumVTs == 4 && I->VTs[0] == VT1 && I->VTs[1] == VT2 &&
                           I->VTs[2] == VT3 && I->VTs[3] == VT4)
       return *I;
@@ -4893,7 +4899,7 @@
   Array[2] = VT3;
   Array[3] = VT4;
   SDVTList Result = makeVTList(Array, 4);
-  VTList.push_back(Result);
+  VTListSlots[slot].push_back(Result);
   return Result;
 }
 
@@ -4906,9 +4912,12 @@
     case 4: return getVTList(VTs[0], VTs[1], VTs[2], VTs[3]);
     default: break;
   }
-
-  for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
-       E = VTList.rend(); I != E; ++I) {
+  
+  unsigned slot = (unsigned)((VTs[0].getRawBits() ^ VTs[2].getRawBits()) + 
+                             (VTs[1].getRawBits() ^ 
+ VTs[3].getRawBits()) ^ VTs[4].getRawBits());  slot %= VTSlotSize;  for 
+ (VTListType::reverse_iterator I = VTListSlots[slot].rbegin(),
+       E = VTListSlots[slot].rend(); I != E; ++I) {
     if (I->NumVTs != NumVTs || VTs[0] != I->VTs[0] || VTs[1] != I->VTs[1])
       continue;
 
@@ -4919,7 +4928,7 @@
   EVT *Array = Allocator.Allocate<EVT>(NumVTs);
   std::copy(VTs, VTs+NumVTs, Array);
   SDVTList Result = makeVTList(Array, NumVTs);
-  VTList.push_back(Result);
+  VTListSlots[slot].push_back(Result);
   return Result;
 }
 
Index: include/llvm/CodeGen/ValueTypes.h ===================================================================
--- include/llvm/CodeGen/ValueTypes.h
+++ include/llvm/CodeGen/ValueTypes.h
@@ -829,7 +829,7 @@
     /// types are returned as Other, otherwise they are invalid.
     static EVT getEVT(Type *Ty, bool HandleUnknown = false);
 
-    intptr_t getRawBits() const {
+    inline intptr_t getRawBits() const {
       if (isSimple())
         return V.SimpleTy;
       else
Index: include/llvm/CodeGen/SelectionDAG.h
===================================================================
--- include/llvm/CodeGen/SelectionDAG.h
+++ include/llvm/CodeGen/SelectionDAG.h
@@ -1086,7 +1086,9 @@
   void allnodes_clear();
 
   /// VTList - List of non-single value types.
-  std::vector<SDVTList> VTList;
+  const static int VTSlotSize = 64;
+  typedef SmallVector<SDVTList, 4> VTListType;  VTListType 
+ VTListSlots[VTSlotSize];
 
   /// CondCodeNodes - Maps to auto-CSE operations.
   std::vector<CondCodeSDNode*> CondCodeNodes;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1127.1.patch
Type: text/x-patch
Size: 4316 bytes
Desc: D1127.1.patch
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20130711/e1f7de8a/attachment.bin>


More information about the llvm-commits mailing list