mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-12-14 11:32:34 +00:00
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
This commit is contained in:
parent
b5677f933f
commit
213a16c637
@ -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*> {
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user