Create a new class: AttributeSetNode.
authorBill Wendling <isanbard@gmail.com>
Thu, 24 Jan 2013 00:06:56 +0000 (00:06 +0000)
committerBill Wendling <isanbard@gmail.com>
Thu, 24 Jan 2013 00:06:56 +0000 (00:06 +0000)
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

include/llvm/IR/Attributes.h
lib/IR/AttributeImpl.h
lib/IR/Attributes.cpp
lib/IR/LLVMContextImpl.h

index 886384adff5d2ba7432f4bfea2a67ac677fa72e7..6ff033715dba959c83a06a568bc456e9c4cd8989 100644 (file)
@@ -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 @@ public:
   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;
index 0843fd8ac88dd2b86117c762a5717d4180d1c2f1..b02cc8bdefeefad14b621bd155227b1990b63a2e 100644 (file)
@@ -56,6 +56,8 @@ public:
   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 @@ public:
 
 //===----------------------------------------------------------------------===//
 /// \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;
index 94615da6d055066eed52bb4b5e2d123ffedbe9d1..8623b98b9f6c032faec9e9cb25bbdb3ba77f8673 100644 (file)
@@ -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 @@ bool Attribute::operator!=(AttrKind K) const {
   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 @@ bool AttributeImpl::operator==(StringRef Kind) const {
       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();
@@ -522,6 +559,41 @@ AttributeWithIndex AttributeWithIndex::get(LLVMContext &C, unsigned Idx,
   return get(Idx, Attribute::get(C, B));
 }
 
+//===----------------------------------------------------------------------===//
+// 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
 //===----------------------------------------------------------------------===//
index 30fd6666fda742f4f2fa786b352b9aedd50da774..cc7ca5e12884f9651279760685abe39daecb0bb9 100644 (file)
@@ -249,6 +249,7 @@ public:
 
   FoldingSet<AttributeImpl> AttrsSet;
   FoldingSet<AttributeSetImpl> AttrsLists;
+  FoldingSet<AttributeSetNode> AttrsSetNodes;
 
   StringMap<Value*> MDStringCache;