[PATCH] [Review Request] Improve getVTList() in SelectionDAG
Wan, Xiaofei
xiaofei.wan at intel.com
Wed Oct 9 06:08:34 PDT 2013
Change to use the existing data structure SmallDenseMap.
Hi resistor,
http://llvm-reviews.chandlerc.com/D1127
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D1127?vs=2766&id=4756#toc
Files:
include/llvm/CodeGen/SelectionDAG.h
lib/CodeGen/SelectionDAG/SelectionDAG.cpp
Index: include/llvm/CodeGen/SelectionDAG.h
===================================================================
--- include/llvm/CodeGen/SelectionDAG.h
+++ include/llvm/CodeGen/SelectionDAG.h
@@ -58,6 +58,42 @@
static void createNode(const SDNode &);
};
+
+struct SDVTListInfo {
+ const EVT *pVTs;
+ unsigned int NumVTs;
+
+ friend struct DenseMapInfo<SDVTListInfo>;
+
+ /// getEmptyKey() - A private constructor that returns an unknown that is
+ /// not equal to the tombstone key or SDVTListInfo().
+ static SDVTListInfo getEmptyKey() {
+ SDVTListInfo SDVTInfo;
+ SDVTInfo.NumVTs = 0;
+ return SDVTInfo;
+ }
+
+ /// getTombstoneKey() - A private constructor that returns an unknown that
+ /// is not equal to the empty key or SDVTListInfo().
+ static SDVTListInfo getTombstoneKey() {
+ SDVTListInfo SDVTInfo;
+ SDVTInfo.NumVTs = 0;
+ return SDVTInfo;
+ }
+
+ unsigned getHashValue() const;
+ bool operator==(const SDVTListInfo &SDVTInfo) const;
+ bool operator!=(const SDVTListInfo &SDVTInfo) const { return !(*this == SDVTInfo); }
+};
+
+template <>
+struct DenseMapInfo<SDVTListInfo> {
+ static SDVTListInfo getEmptyKey() { return SDVTListInfo::getEmptyKey(); }
+ static SDVTListInfo getTombstoneKey() { return SDVTListInfo::getTombstoneKey(); }
+ static bool isEqual(SDVTListInfo LHS, SDVTListInfo RHS) { return LHS == RHS; }
+ static unsigned getHashValue(const SDVTListInfo &Key) { return Key.getHashValue(); }
+};
+
/// SDDbgInfo - Keeps track of dbg_value information through SDISel. We do
/// not build SDNodes for these so as not to perturb the generated code;
/// instead the info is kept off to the side in this structure. Each SDNode may
@@ -1093,7 +1129,7 @@
void allnodes_clear();
/// VTList - List of non-single value types.
- std::vector<SDVTList> VTList;
+ SmallDenseMap<SDVTListInfo, SDVTList, 256> VTListMap;
/// CondCodeNodes - Maps to auto-CSE operations.
std::vector<CondCodeSDNode*> CondCodeNodes;
Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp
===================================================================
--- lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -52,6 +52,23 @@
#include <cmath>
using namespace llvm;
+unsigned SDVTListInfo::getHashValue() const {
+ unsigned hash = 0;
+ for (unsigned index = 0; index < NumVTs; ++index) {
+ hash = hash ^ pVTs[index].getRawBits();
+ }
+ hash = (hash << 2) ^ NumVTs;
+ return hash;
+}
+
+bool SDVTListInfo::operator==(const SDVTListInfo &SDVTInfo) const {
+ if (NumVTs != SDVTInfo.NumVTs)
+ return false;
+ if (!std::equal(&pVTs[0], &pVTs[NumVTs], &SDVTInfo.pVTs[0]))
+ return false;
+ return true;
+}
+
/// makeVTList - Return an instance of the SDVTList struct initialized with the
/// specified members.
static SDVTList makeVTList(const EVT *VTs, unsigned NumVTs) {
@@ -4891,75 +4908,31 @@
}
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2) {
- for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
- E = VTList.rend(); I != E; ++I)
- if (I->NumVTs == 2 && I->VTs[0] == VT1 && I->VTs[1] == VT2)
- return *I;
-
- EVT *Array = Allocator.Allocate<EVT>(2);
- Array[0] = VT1;
- Array[1] = VT2;
- SDVTList Result = makeVTList(Array, 2);
- VTList.push_back(Result);
- return Result;
+ const EVT pVTs[2] = {VT1, VT2};
+ return getVTList(pVTs, 2);
}
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3) {
- for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
- E = VTList.rend(); I != E; ++I)
- if (I->NumVTs == 3 && I->VTs[0] == VT1 && I->VTs[1] == VT2 &&
- I->VTs[2] == VT3)
- return *I;
-
- EVT *Array = Allocator.Allocate<EVT>(3);
- Array[0] = VT1;
- Array[1] = VT2;
- Array[2] = VT3;
- SDVTList Result = makeVTList(Array, 3);
- VTList.push_back(Result);
- return Result;
+ const EVT pVTs[3] = {VT1, VT2, VT3};
+ return getVTList(pVTs, 3);
}
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)
- if (I->NumVTs == 4 && I->VTs[0] == VT1 && I->VTs[1] == VT2 &&
- I->VTs[2] == VT3 && I->VTs[3] == VT4)
- return *I;
-
- EVT *Array = Allocator.Allocate<EVT>(4);
- Array[0] = VT1;
- Array[1] = VT2;
- Array[2] = VT3;
- Array[3] = VT4;
- SDVTList Result = makeVTList(Array, 4);
- VTList.push_back(Result);
- return Result;
+ const EVT pVTs[4] = {VT1, VT2, VT3, VT4};
+ return getVTList(pVTs, 4);
}
SDVTList SelectionDAG::getVTList(const EVT *VTs, unsigned NumVTs) {
- switch (NumVTs) {
- case 0: llvm_unreachable("Cannot have nodes without results!");
- case 1: return getVTList(VTs[0]);
- case 2: return getVTList(VTs[0], VTs[1]);
- case 3: return getVTList(VTs[0], VTs[1], VTs[2]);
- 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) {
- if (I->NumVTs != NumVTs || VTs[0] != I->VTs[0] || VTs[1] != I->VTs[1])
- continue;
-
- if (std::equal(&VTs[2], &VTs[NumVTs], &I->VTs[2]))
- return *I;
- }
-
+ SDVTListInfo Key = {VTs, NumVTs};
+ if (VTListMap.count(Key))
+ return VTListMap[Key];
+
EVT *Array = Allocator.Allocate<EVT>(NumVTs);
std::copy(VTs, VTs+NumVTs, Array);
SDVTList Result = makeVTList(Array, NumVTs);
- VTList.push_back(Result);
+ Key.pVTs = Array;
+ VTListMap.insert(std::make_pair(Key, Result));
+
return Result;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D1127.3.patch
Type: text/x-patch
Size: 5629 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20131009/b555f1f2/attachment.bin>
More information about the llvm-commits
mailing list