//===----------------------------------------------------------------------===//
//
// This file implements a hash set that can be used to remove duplication of
-// nodes in a graph. This code was originally created by Chris Lattner for use
-// with SelectionDAGCSEMap, but was isolated to provide use across the llvm code
-// set.
+// nodes in a graph.
//
//===----------------------------------------------------------------------===//
#include "llvm/ADT/Hashing.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/ErrorHandling.h"
-#include "llvm/Support/MathExtras.h"
#include "llvm/Support/Host.h"
+#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <cstring>
using namespace llvm;
return memcmp(Data, RHS.Data, Size*sizeof(*Data)) == 0;
}
+/// Used to compare the "ordering" of two nodes as defined by the
+/// profiled bits and their ordering defined by memcmp().
+bool FoldingSetNodeIDRef::operator<(FoldingSetNodeIDRef RHS) const {
+ if (Size != RHS.Size)
+ return Size < RHS.Size;
+ return memcmp(Data, RHS.Data, Size*sizeof(*Data)) < 0;
+}
+
//===----------------------------------------------------------------------===//
// FoldingSetNodeID Implementation
+/// Add* - Add various data types to Bit data.
+///
+void FoldingSetNodeID::AddPointer(const void *Ptr) {
+ // Note: this adds pointers to the hash using sizes and endianness that
+ // depend on the host. It doesn't matter however, because hashing on
+ // pointer values in inherently unstable. Nothing should depend on the
+ // ordering of nodes in the folding set.
+ Bits.append(reinterpret_cast<unsigned *>(&Ptr),
+ reinterpret_cast<unsigned *>(&Ptr+1));
+}
+void FoldingSetNodeID::AddInteger(signed I) {
+ Bits.push_back(I);
+}
+void FoldingSetNodeID::AddInteger(unsigned I) {
+ Bits.push_back(I);
+}
+void FoldingSetNodeID::AddInteger(long I) {
+ AddInteger((unsigned long)I);
+}
+void FoldingSetNodeID::AddInteger(unsigned long I) {
+ if (sizeof(long) == sizeof(int))
+ AddInteger(unsigned(I));
+ else if (sizeof(long) == sizeof(long long)) {
+ AddInteger((unsigned long long)I);
+ } else {
+ llvm_unreachable("unexpected sizeof(long)");
+ }
+}
+void FoldingSetNodeID::AddInteger(long long I) {
+ AddInteger((unsigned long long)I);
+}
+void FoldingSetNodeID::AddInteger(unsigned long long I) {
+ AddInteger(unsigned(I));
+ if ((uint64_t)(unsigned)I != I)
+ Bits.push_back(unsigned(I >> 32));
+}
+
void FoldingSetNodeID::AddString(StringRef String) {
unsigned Size = String.size();
Bits.push_back(Size);
Bits.push_back(V);
}
-/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used to
+// AddNodeID - Adds the Bit data of another ID to *this.
+void FoldingSetNodeID::AddNodeID(const FoldingSetNodeID &ID) {
+ Bits.append(ID.Bits.begin(), ID.Bits.end());
+}
+
+/// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used to
/// lookup the node in the FoldingSetImpl.
unsigned FoldingSetNodeID::ComputeHash() const {
return FoldingSetNodeIDRef(Bits.data(), Bits.size()).ComputeHash();
/// operator== - Used to compare two nodes to each other.
///
-bool FoldingSetNodeID::operator==(const FoldingSetNodeID &RHS)const{
+bool FoldingSetNodeID::operator==(const FoldingSetNodeID &RHS) const {
return *this == FoldingSetNodeIDRef(RHS.Bits.data(), RHS.Bits.size());
}
return FoldingSetNodeIDRef(Bits.data(), Bits.size()) == RHS;
}
+/// Used to compare the "ordering" of two nodes as defined by the
+/// profiled bits and their ordering defined by memcmp().
+bool FoldingSetNodeID::operator<(const FoldingSetNodeID &RHS) const {
+ return *this < FoldingSetNodeIDRef(RHS.Bits.data(), RHS.Bits.size());
+}
+
+bool FoldingSetNodeID::operator<(FoldingSetNodeIDRef RHS) const {
+ return FoldingSetNodeIDRef(Bits.data(), Bits.size()) < RHS;
+}
+
/// Intern - Copy this node's data to a memory region allocated from the
/// given allocator and return a FoldingSetNodeIDRef describing the
/// interned data.
FoldingSetImpl::Node
*FoldingSetImpl::FindNodeOrInsertPos(const FoldingSetNodeID &ID,
void *&InsertPos) {
-
- void **Bucket = GetBucketFor(ID.ComputeHash(), Buckets, NumBuckets);
+ unsigned IDHash = ID.ComputeHash();
+ void **Bucket = GetBucketFor(IDHash, Buckets, NumBuckets);
void *Probe = *Bucket;
InsertPos = 0;
FoldingSetNodeID TempID;
while (Node *NodeInBucket = GetNextPtr(Probe)) {
- if (NodeEquals(NodeInBucket, ID, TempID))
+ if (NodeEquals(NodeInBucket, ID, IDHash, TempID))
return NodeInBucket;
TempID.clear();