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; + + /// 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 { + 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 VTList; + SmallDenseMap VTListMap; /// CondCodeNodes - Maps to auto-CSE operations. std::vector CondCodeNodes; Index: lib/CodeGen/SelectionDAG/SelectionDAG.cpp =================================================================== --- lib/CodeGen/SelectionDAG/SelectionDAG.cpp +++ lib/CodeGen/SelectionDAG/SelectionDAG.cpp @@ -52,6 +52,23 @@ #include 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::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(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::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(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::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(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::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(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; }