forked from OSchip/llvm-project
Using FoldingSet in SelectionDAG::getVTList.
VTList has a long life cycle through the module and getVTList is frequently called. In current getVTList, sequential search over a std::vector is used, this is inefficient in big module. This patch use FoldingSet to implement hashing mechanism when searching. Reviewer: Nadav Rotem Test : Pass unit tests & LNT test suite llvm-svn: 193150
This commit is contained in:
parent
47b3bd3fbb
commit
2f8dc08b8c
|
|
@ -38,6 +38,45 @@ class TargetLowering;
|
||||||
class TargetSelectionDAGInfo;
|
class TargetSelectionDAGInfo;
|
||||||
class TargetTransformInfo;
|
class TargetTransformInfo;
|
||||||
|
|
||||||
|
class SDVTListNode : public FoldingSetNode {
|
||||||
|
friend struct FoldingSetTrait<SDVTListNode>;
|
||||||
|
/// FastID - A reference to an Interned FoldingSetNodeID for this node.
|
||||||
|
/// The Allocator in SelectionDAG holds the data.
|
||||||
|
/// SDVTList contains all types which are frequently accessed in SelectionDAG.
|
||||||
|
/// The size of this list is not expected big so it won't introduce memory penalty.
|
||||||
|
FoldingSetNodeIDRef FastID;
|
||||||
|
const EVT *VTs;
|
||||||
|
unsigned int NumVTs;
|
||||||
|
/// The hash value for SDVTList is fixed so cache it to avoid hash calculation
|
||||||
|
unsigned HashValue;
|
||||||
|
public:
|
||||||
|
SDVTListNode(const FoldingSetNodeIDRef ID, const EVT *VT, unsigned int Num) :
|
||||||
|
FastID(ID), VTs(VT), NumVTs(Num) {
|
||||||
|
HashValue = ID.ComputeHash();
|
||||||
|
}
|
||||||
|
SDVTList getSDVTList() {
|
||||||
|
SDVTList result = {VTs, NumVTs};
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Specialize FoldingSetTrait for SDVTListNode
|
||||||
|
// To avoid computing temp FoldingSetNodeID and hash value.
|
||||||
|
template<> struct FoldingSetTrait<SDVTListNode> : DefaultFoldingSetTrait<SDVTListNode> {
|
||||||
|
static void Profile(const SDVTListNode &X, FoldingSetNodeID& ID) {
|
||||||
|
ID = X.FastID;
|
||||||
|
}
|
||||||
|
static bool Equals(const SDVTListNode &X, const FoldingSetNodeID &ID,
|
||||||
|
unsigned IDHash, FoldingSetNodeID &TempID) {
|
||||||
|
if (X.HashValue != IDHash)
|
||||||
|
return false;
|
||||||
|
return ID == X.FastID;
|
||||||
|
}
|
||||||
|
static unsigned ComputeHash(const SDVTListNode &X, FoldingSetNodeID &TempID) {
|
||||||
|
return X.HashValue;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
|
template<> struct ilist_traits<SDNode> : public ilist_default_traits<SDNode> {
|
||||||
private:
|
private:
|
||||||
mutable ilist_half_node<SDNode> Sentinel;
|
mutable ilist_half_node<SDNode> Sentinel;
|
||||||
|
|
@ -1093,7 +1132,7 @@ private:
|
||||||
void allnodes_clear();
|
void allnodes_clear();
|
||||||
|
|
||||||
/// VTList - List of non-single value types.
|
/// VTList - List of non-single value types.
|
||||||
std::vector<SDVTList> VTList;
|
FoldingSet<SDVTListNode> VTListMap;
|
||||||
|
|
||||||
/// CondCodeNodes - Maps to auto-CSE operations.
|
/// CondCodeNodes - Maps to auto-CSE operations.
|
||||||
std::vector<CondCodeSDNode*> CondCodeNodes;
|
std::vector<CondCodeSDNode*> CondCodeNodes;
|
||||||
|
|
|
||||||
|
|
@ -4891,76 +4891,81 @@ SDVTList SelectionDAG::getVTList(EVT VT) {
|
||||||
}
|
}
|
||||||
|
|
||||||
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2) {
|
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2) {
|
||||||
for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
|
FoldingSetNodeID ID;
|
||||||
E = VTList.rend(); I != E; ++I)
|
ID.AddInteger(2U);
|
||||||
if (I->NumVTs == 2 && I->VTs[0] == VT1 && I->VTs[1] == VT2)
|
ID.AddInteger(VT1.getRawBits());
|
||||||
return *I;
|
ID.AddInteger(VT2.getRawBits());
|
||||||
|
|
||||||
EVT *Array = Allocator.Allocate<EVT>(2);
|
void *IP = 0;
|
||||||
Array[0] = VT1;
|
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
|
||||||
Array[1] = VT2;
|
if (Result == NULL) {
|
||||||
SDVTList Result = makeVTList(Array, 2);
|
EVT *Array = Allocator.Allocate<EVT>(2);
|
||||||
VTList.push_back(Result);
|
Array[0] = VT1;
|
||||||
return Result;
|
Array[1] = VT2;
|
||||||
|
Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, 2);
|
||||||
|
VTListMap.InsertNode(Result, IP);
|
||||||
|
}
|
||||||
|
return Result->getSDVTList();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3) {
|
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3) {
|
||||||
for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
|
FoldingSetNodeID ID;
|
||||||
E = VTList.rend(); I != E; ++I)
|
ID.AddInteger(3U);
|
||||||
if (I->NumVTs == 3 && I->VTs[0] == VT1 && I->VTs[1] == VT2 &&
|
ID.AddInteger(VT1.getRawBits());
|
||||||
I->VTs[2] == VT3)
|
ID.AddInteger(VT2.getRawBits());
|
||||||
return *I;
|
ID.AddInteger(VT3.getRawBits());
|
||||||
|
|
||||||
EVT *Array = Allocator.Allocate<EVT>(3);
|
void *IP = 0;
|
||||||
Array[0] = VT1;
|
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
|
||||||
Array[1] = VT2;
|
if (Result == NULL) {
|
||||||
Array[2] = VT3;
|
EVT *Array = Allocator.Allocate<EVT>(3);
|
||||||
SDVTList Result = makeVTList(Array, 3);
|
Array[0] = VT1;
|
||||||
VTList.push_back(Result);
|
Array[1] = VT2;
|
||||||
return Result;
|
Array[2] = VT3;
|
||||||
|
Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, 3);
|
||||||
|
VTListMap.InsertNode(Result, IP);
|
||||||
|
}
|
||||||
|
return Result->getSDVTList();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4) {
|
SDVTList SelectionDAG::getVTList(EVT VT1, EVT VT2, EVT VT3, EVT VT4) {
|
||||||
for (std::vector<SDVTList>::reverse_iterator I = VTList.rbegin(),
|
FoldingSetNodeID ID;
|
||||||
E = VTList.rend(); I != E; ++I)
|
ID.AddInteger(4U);
|
||||||
if (I->NumVTs == 4 && I->VTs[0] == VT1 && I->VTs[1] == VT2 &&
|
ID.AddInteger(VT1.getRawBits());
|
||||||
I->VTs[2] == VT3 && I->VTs[3] == VT4)
|
ID.AddInteger(VT2.getRawBits());
|
||||||
return *I;
|
ID.AddInteger(VT3.getRawBits());
|
||||||
|
ID.AddInteger(VT4.getRawBits());
|
||||||
|
|
||||||
EVT *Array = Allocator.Allocate<EVT>(4);
|
void *IP = 0;
|
||||||
Array[0] = VT1;
|
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
|
||||||
Array[1] = VT2;
|
if (Result == NULL) {
|
||||||
Array[2] = VT3;
|
EVT *Array = Allocator.Allocate<EVT>(4);
|
||||||
Array[3] = VT4;
|
Array[0] = VT1;
|
||||||
SDVTList Result = makeVTList(Array, 4);
|
Array[1] = VT2;
|
||||||
VTList.push_back(Result);
|
Array[2] = VT3;
|
||||||
return Result;
|
Array[3] = VT4;
|
||||||
|
Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, 4);
|
||||||
|
VTListMap.InsertNode(Result, IP);
|
||||||
|
}
|
||||||
|
return Result->getSDVTList();
|
||||||
}
|
}
|
||||||
|
|
||||||
SDVTList SelectionDAG::getVTList(const EVT *VTs, unsigned NumVTs) {
|
SDVTList SelectionDAG::getVTList(const EVT *VTs, unsigned NumVTs) {
|
||||||
switch (NumVTs) {
|
FoldingSetNodeID ID;
|
||||||
case 0: llvm_unreachable("Cannot have nodes without results!");
|
ID.AddInteger(NumVTs);
|
||||||
case 1: return getVTList(VTs[0]);
|
for (unsigned index = 0; index < NumVTs; index++) {
|
||||||
case 2: return getVTList(VTs[0], VTs[1]);
|
ID.AddInteger(VTs[index].getRawBits());
|
||||||
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(),
|
void *IP = 0;
|
||||||
E = VTList.rend(); I != E; ++I) {
|
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
|
||||||
if (I->NumVTs != NumVTs || VTs[0] != I->VTs[0] || VTs[1] != I->VTs[1])
|
if (Result == NULL) {
|
||||||
continue;
|
EVT *Array = Allocator.Allocate<EVT>(NumVTs);
|
||||||
|
std::copy(VTs, VTs + NumVTs, Array);
|
||||||
if (std::equal(&VTs[2], &VTs[NumVTs], &I->VTs[2]))
|
Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, NumVTs);
|
||||||
return *I;
|
VTListMap.InsertNode(Result, IP);
|
||||||
}
|
}
|
||||||
|
return Result->getSDVTList();
|
||||||
EVT *Array = Allocator.Allocate<EVT>(NumVTs);
|
|
||||||
std::copy(VTs, VTs+NumVTs, Array);
|
|
||||||
SDVTList Result = makeVTList(Array, NumVTs);
|
|
||||||
VTList.push_back(Result);
|
|
||||||
return Result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue