mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-02-04 11:17:31 +00: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:
parent
28b7b8c64d
commit
dc0d564687
@ -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;
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user