aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Lattner <sabre@nondot.org>2006-08-14 22:19:25 +0000
committerChris Lattner <sabre@nondot.org>2006-08-14 22:19:25 +0000
commit213a16c637926bfc38ba373d3aba6778e181e3ec (patch)
tree39713a4bf0f41e3a51063fa70f3aacaa8029abab
parentb5677f933f918acd8b8525635510d22dfb26285e (diff)
downloadexternal_llvm-213a16c637926bfc38ba373d3aba6778e181e3ec.zip
external_llvm-213a16c637926bfc38ba373d3aba6778e181e3ec.tar.gz
external_llvm-213a16c637926bfc38ba373d3aba6778e181e3ec.tar.bz2
Add code to resize the CSEMap hash table. This doesn't speedup codegen of
kimwitu, but seems like a good idea from a "avoid performance cliffs" standpoint :) git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@29675 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/llvm/CodeGen/SelectionDAG.h9
-rw-r--r--include/llvm/CodeGen/SelectionDAGCSEMap.h2
-rw-r--r--include/llvm/CodeGen/SelectionDAGNodes.h1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAG.cpp1
-rw-r--r--lib/CodeGen/SelectionDAG/SelectionDAGCSEMap.cpp49
5 files changed, 56 insertions, 6 deletions
diff --git a/include/llvm/CodeGen/SelectionDAG.h b/include/llvm/CodeGen/SelectionDAG.h
index 2cc6ba7..a8af4a3 100644
--- a/include/llvm/CodeGen/SelectionDAG.h
+++ b/include/llvm/CodeGen/SelectionDAG.h
@@ -46,12 +46,16 @@ class SelectionDAG {
MachineFunction &MF;
MachineDebugInfo *DI;
- // Root - The root of the entire DAG. EntryNode - The starting token.
+ /// Root - The root of the entire DAG. EntryNode - The starting token.
SDOperand Root, EntryNode;
- // AllNodes - A linked list of nodes in the current DAG.
+ /// AllNodes - A linked list of nodes in the current DAG.
ilist<SDNode> AllNodes;
+ /// CSEMap - This structure is used to memoize nodes, automatically performing
+ /// CSE with existing nodes with a duplicate is requested.
+ SelectionDAGCSEMap CSEMap;
+
public:
SelectionDAG(TargetLowering &tli, MachineFunction &mf, MachineDebugInfo *di)
: TLI(tli), MF(mf), DI(di) {
@@ -464,7 +468,6 @@ private:
std::map<std::string, SDNode*> ExternalSymbols;
std::map<std::string, SDNode*> TargetExternalSymbols;
std::map<std::string, StringSDNode*> StringNodes;
- SelectionDAGCSEMap CSEMap;
};
template <> struct GraphTraits<SelectionDAG*> : public GraphTraits<SDNode*> {
diff --git a/include/llvm/CodeGen/SelectionDAGCSEMap.h b/include/llvm/CodeGen/SelectionDAGCSEMap.h
index dd1071a..e3771c9 100644
--- a/include/llvm/CodeGen/SelectionDAGCSEMap.h
+++ b/include/llvm/CodeGen/SelectionDAGCSEMap.h
@@ -117,8 +117,10 @@ namespace llvm {
private:
SDNode *GetNextPtr(void *NextInBucketPtr);
+ SDNode *GetNextPtr(void *NextInBucketPtr, void **Buckets, unsigned NumBuck);
void **GetBucketPtr(void *NextInBucketPtr);
void **GetBucketFor(const NodeID &ID) const;
+ void GrowHashTable();
};
} // end namespace llvm
diff --git a/include/llvm/CodeGen/SelectionDAGNodes.h b/include/llvm/CodeGen/SelectionDAGNodes.h
index fe6975b..dc58bd9 100644
--- a/include/llvm/CodeGen/SelectionDAGNodes.h
+++ b/include/llvm/CodeGen/SelectionDAGNodes.h
@@ -719,6 +719,7 @@ class SDNode {
public:
virtual ~SDNode() {
assert(NumOperands == 0 && "Operand list not cleared before deletion");
+ assert(NextInBucket == 0 && "Still in CSEMap?");
NodeType = ISD::DELETED_NODE;
}
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index 6fd8ba2..1c17dfb 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -469,6 +469,7 @@ SDNode *SelectionDAG::FindModifiedNodeSlot(SDNode *N,
SelectionDAG::~SelectionDAG() {
while (!AllNodes.empty()) {
SDNode *N = AllNodes.begin();
+ N->SetNextInBucket(0);
delete [] N->OperandList;
N->OperandList = 0;
N->NumOperands = 0;
diff --git a/lib/CodeGen/SelectionDAG/SelectionDAGCSEMap.cpp b/lib/CodeGen/SelectionDAG/SelectionDAGCSEMap.cpp
index b42c70b..cd255ba 100644
--- a/lib/CodeGen/SelectionDAG/SelectionDAGCSEMap.cpp
+++ b/lib/CodeGen/SelectionDAG/SelectionDAGCSEMap.cpp
@@ -157,7 +157,7 @@ bool SelectionDAGCSEMap::NodeID::operator==(const NodeID &RHS) const {
// SelectionDAGCSEMap Implementation
SelectionDAGCSEMap::SelectionDAGCSEMap() : NumNodes(0) {
- NumBuckets = 256;
+ NumBuckets = 64;
Buckets = new void*[NumBuckets];
memset(Buckets, 0, NumBuckets*sizeof(void*));
}
@@ -176,6 +176,15 @@ SDNode *SelectionDAGCSEMap::GetNextPtr(void *NextInBucketPtr) {
return static_cast<SDNode*>(NextInBucketPtr);
}
+/// GetNextPtr - This is just like the previous GetNextPtr implementation, but
+/// allows a bucket array to be specified.
+SDNode *SelectionDAGCSEMap::GetNextPtr(void *NextInBucketPtr, void **Bucks,
+ unsigned NumBuck) {
+ if (NextInBucketPtr >= Bucks && NextInBucketPtr < Bucks+NumBuck)
+ return 0;
+ return static_cast<SDNode*>(NextInBucketPtr);
+}
+
void **SelectionDAGCSEMap::GetBucketPtr(void *NextInBucketPtr) {
//assert(NextInBucketPtr >= Buckets && NextInBucketPtr < Buckets+NumBuckets &&
// "NextInBucketPtr is not a bucket ptr");
@@ -185,13 +194,42 @@ void **SelectionDAGCSEMap::GetBucketPtr(void *NextInBucketPtr) {
/// GetBucketFor - Hash the specified node ID and return the hash bucket for the
/// specified ID.
void **SelectionDAGCSEMap::GetBucketFor(const NodeID &ID) const {
- // TODO: if load is high, resize hash table.
-
// NumBuckets is always a power of 2.
unsigned BucketNum = ID.ComputeHash() & (NumBuckets-1);
return Buckets+BucketNum;
}
+/// GrowHashTable - Double the size of the hash table and rehash everything.
+///
+void SelectionDAGCSEMap::GrowHashTable() {
+ void **OldBuckets = Buckets;
+ unsigned OldNumBuckets = NumBuckets;
+ NumBuckets <<= 1;
+
+ // Reset the node count to zero: we're going to reinsert everything.
+ NumNodes = 0;
+
+ // Clear out new buckets.
+ Buckets = new void*[NumBuckets];
+ memset(Buckets, 0, NumBuckets*sizeof(void*));
+
+ // Walk the old buckets, rehashing nodes into their new place.
+ for (unsigned i = 0; i != OldNumBuckets; ++i) {
+ void *Probe = OldBuckets[i];
+ if (!Probe) continue;
+ while (SDNode *NodeInBucket = GetNextPtr(Probe, OldBuckets, OldNumBuckets)){
+ // Figure out the next link, remove NodeInBucket from the old link.
+ Probe = NodeInBucket->getNextInBucket();
+ NodeInBucket->SetNextInBucket(0);
+
+ // Insert the node into the new bucket, after recomputing the hash.
+ InsertNode(NodeInBucket, GetBucketFor(NodeID(NodeInBucket)));
+ }
+ }
+
+ delete[] OldBuckets;
+}
+
/// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
/// return it. If not, return the insertion token that will make insertion
/// faster.
@@ -226,6 +264,11 @@ SDNode *SelectionDAGCSEMap::FindNodeOrInsertPos(const NodeID &ID,
/// FindNodeOrInsertPos.
void SelectionDAGCSEMap::InsertNode(SDNode *N, void *InsertPos) {
++NumNodes;
+ // Do we need to grow the hashtable?
+ if (NumNodes > NumBuckets*2) {
+ GrowHashTable();
+ InsertPos = GetBucketFor(NodeID(N));
+ }
/// The insert position is actually a bucket pointer.
void **Bucket = static_cast<void**>(InsertPos);