Create a new class: AttributeSetNode.
This is a helper class for the AttributeSetImpl class. It holds a set of
attributes that apply to a single element: function, return type, or
parameter.
These are uniqued.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@173310 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h
index 886384a..6ff0337 100644
--- a/include/llvm/IR/Attributes.h
+++ b/include/llvm/IR/Attributes.h
@@ -18,6 +18,7 @@
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseSet.h"
+#include "llvm/ADT/FoldingSet.h"
#include "llvm/Support/MathExtras.h"
#include <cassert>
#include <string>
@@ -129,6 +130,10 @@
bool operator==(AttrKind K) const;
bool operator!=(AttrKind K) const;
+ bool operator<(Attribute A) const;
+
+ void Profile(FoldingSetNodeID &ID) const;
+
// FIXME: Remove these 'operator' methods.
bool operator==(const Attribute &A) const {
return pImpl == A.pImpl;
diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h
index 0843fd8..b02cc8b 100644
--- a/lib/IR/AttributeImpl.h
+++ b/lib/IR/AttributeImpl.h
@@ -56,6 +56,8 @@
bool operator==(StringRef Kind) const;
bool operator!=(StringRef Kind) const;
+ bool operator<(const AttributeImpl &AI) const;
+
uint64_t Raw() const; // FIXME: Remove.
static uint64_t getAttrMask(Attribute::AttrKind Val);
@@ -69,7 +71,38 @@
//===----------------------------------------------------------------------===//
/// \class
-/// \brief This class represents a set of attributes.
+/// \brief This class represents a group of attributes that apply to one
+/// element: function, return type, or parameter.
+class AttributeSetNode : public FoldingSetNode {
+ SmallVector<Attribute, 4> AttrList;
+
+ AttributeSetNode(ArrayRef<Attribute> Attrs)
+ : AttrList(Attrs.begin(), Attrs.end()) {}
+public:
+ static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
+
+ typedef SmallVectorImpl<Attribute>::iterator iterator;
+ typedef SmallVectorImpl<Attribute>::const_iterator const_iterator;
+
+ iterator begin() { return AttrList.begin(); }
+ iterator end() { return AttrList.end(); }
+
+ const_iterator begin() const { return AttrList.begin(); }
+ const_iterator end() const { return AttrList.end(); }
+
+ void Profile(FoldingSetNodeID &ID) const {
+ Profile(ID, AttrList);
+ }
+ static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
+ for (unsigned I = 0, E = AttrList.size(); I != E; ++I)
+ AttrList[I].Profile(ID);
+ }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class represents a set of attributes that apply to the function,
+/// return type, and parameters.
class AttributeSetImpl : public FoldingSetNode {
LLVMContext &Context;
SmallVector<AttributeWithIndex, 4> AttrList;
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp
index 94615da..8623b98 100644
--- a/lib/IR/Attributes.cpp
+++ b/lib/IR/Attributes.cpp
@@ -23,6 +23,7 @@
#include "llvm/Support/ManagedStatic.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/raw_ostream.h"
+#include <algorithm>
using namespace llvm;
//===----------------------------------------------------------------------===//
@@ -91,6 +92,18 @@
return !(*this == K);
}
+bool Attribute::operator<(Attribute A) const {
+ if (!pImpl && !A.pImpl) return false;
+ if (!pImpl) return true;
+ if (!A.pImpl) return false;
+ return *pImpl < *A.pImpl;
+}
+
+
+void Attribute::Profile(FoldingSetNodeID &ID) const {
+ ID.AddPointer(pImpl);
+}
+
uint64_t Attribute::Raw() const {
return pImpl ? pImpl->Raw() : 0;
}
@@ -431,10 +444,34 @@
return CDA->getAsString() == Kind;
return false;
}
+
bool AttributeImpl::operator!=(StringRef Kind) const {
return !(*this == Kind);
}
+bool AttributeImpl::operator<(const AttributeImpl &AI) const {
+ if (!Data && !AI.Data) return false;
+ if (!Data && AI.Data) return true;
+ if (Data && !AI.Data) return false;
+
+ ConstantInt *ThisCI = dyn_cast<ConstantInt>(Data);
+ ConstantInt *ThatCI = dyn_cast<ConstantInt>(AI.Data);
+
+ ConstantDataArray *ThisCDA = dyn_cast<ConstantDataArray>(Data);
+ ConstantDataArray *ThatCDA = dyn_cast<ConstantDataArray>(AI.Data);
+
+ if (ThisCI && ThatCI)
+ return ThisCI->getZExtValue() < ThatCI->getZExtValue();
+
+ if (ThisCI && ThatCDA)
+ return true;
+
+ if (ThisCDA && ThatCI)
+ return false;
+
+ return ThisCDA->getAsString() < ThatCDA->getAsString();
+}
+
uint64_t AttributeImpl::Raw() const {
// FIXME: Remove this.
return cast<ConstantInt>(Data)->getZExtValue();
@@ -523,6 +560,41 @@
}
//===----------------------------------------------------------------------===//
+// AttributeSetNode Definition
+//===----------------------------------------------------------------------===//
+
+AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
+ ArrayRef<Attribute> Attrs) {
+ if (Attrs.empty())
+ return 0;
+
+ // Otherwise, build a key to look up the existing attributes.
+ LLVMContextImpl *pImpl = C.pImpl;
+ FoldingSetNodeID ID;
+
+ SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
+ std::sort(SortedAttrs.begin(), SortedAttrs.end());
+
+ for (SmallVectorImpl<Attribute>::iterator I = SortedAttrs.begin(),
+ E = SortedAttrs.end(); I != E; ++I)
+ I->Profile(ID);
+
+ void *InsertPoint;
+ AttributeSetNode *PA =
+ pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
+
+ // If we didn't find any existing attributes of the same shape then create a
+ // new one and insert it.
+ if (!PA) {
+ PA = new AttributeSetNode(SortedAttrs);
+ pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
+ }
+
+ // Return the AttributesListNode that we found or created.
+ return PA;
+}
+
+//===----------------------------------------------------------------------===//
// AttributeSetImpl Definition
//===----------------------------------------------------------------------===//
diff --git a/lib/IR/LLVMContextImpl.h b/lib/IR/LLVMContextImpl.h
index 30fd666..cc7ca5e 100644
--- a/lib/IR/LLVMContextImpl.h
+++ b/lib/IR/LLVMContextImpl.h
@@ -249,6 +249,7 @@
FoldingSet<AttributeImpl> AttrsSet;
FoldingSet<AttributeSetImpl> AttrsLists;
+ FoldingSet<AttributeSetNode> AttrsSetNodes;
StringMap<Value*> MDStringCache;