1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-10-20 19:42:54 +02:00

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:
Wan Xiaofei 2013-10-22 08:02:02 +00:00
parent 28b7b8c64d
commit dc0d564687
2 changed files with 100 additions and 56 deletions

View File

@ -38,6 +38,45 @@ class TargetLowering;
class TargetSelectionDAGInfo;
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> {
private:
mutable ilist_half_node<SDNode> Sentinel;
@ -1093,7 +1132,7 @@ private:
void allnodes_clear();
/// VTList - List of non-single value types.
std::vector<SDVTList> VTList;
FoldingSet<SDVTListNode> VTListMap;
/// CondCodeNodes - Maps to auto-CSE operations.
std::vector<CondCodeSDNode*> CondCodeNodes;

View File

@ -4891,76 +4891,81 @@ SDVTList SelectionDAG::getVTList(EVT VT) {
}
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;
FoldingSetNodeID ID;
ID.AddInteger(2U);
ID.AddInteger(VT1.getRawBits());
ID.AddInteger(VT2.getRawBits());
EVT *Array = Allocator.Allocate<EVT>(2);
Array[0] = VT1;
Array[1] = VT2;
SDVTList Result = makeVTList(Array, 2);
VTList.push_back(Result);
return Result;
void *IP = 0;
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
if (Result == NULL) {
EVT *Array = Allocator.Allocate<EVT>(2);
Array[0] = VT1;
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) {
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;
FoldingSetNodeID ID;
ID.AddInteger(3U);
ID.AddInteger(VT1.getRawBits());
ID.AddInteger(VT2.getRawBits());
ID.AddInteger(VT3.getRawBits());
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;
void *IP = 0;
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
if (Result == NULL) {
EVT *Array = Allocator.Allocate<EVT>(3);
Array[0] = VT1;
Array[1] = VT2;
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) {
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;
FoldingSetNodeID ID;
ID.AddInteger(4U);
ID.AddInteger(VT1.getRawBits());
ID.AddInteger(VT2.getRawBits());
ID.AddInteger(VT3.getRawBits());
ID.AddInteger(VT4.getRawBits());
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;
void *IP = 0;
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
if (Result == NULL) {
EVT *Array = Allocator.Allocate<EVT>(4);
Array[0] = VT1;
Array[1] = VT2;
Array[2] = VT3;
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) {
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;
FoldingSetNodeID ID;
ID.AddInteger(NumVTs);
for (unsigned index = 0; index < NumVTs; index++) {
ID.AddInteger(VTs[index].getRawBits());
}
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;
void *IP = 0;
SDVTListNode *Result = VTListMap.FindNodeOrInsertPos(ID, IP);
if (Result == NULL) {
EVT *Array = Allocator.Allocate<EVT>(NumVTs);
std::copy(VTs, VTs + NumVTs, Array);
Result = new (Allocator) SDVTListNode(ID.Intern(Allocator), Array, NumVTs);
VTListMap.InsertNode(Result, IP);
}
EVT *Array = Allocator.Allocate<EVT>(NumVTs);
std::copy(VTs, VTs+NumVTs, Array);
SDVTList Result = makeVTList(Array, NumVTs);
VTList.push_back(Result);
return Result;
return Result->getSDVTList();
}