Create a new class: AttributeSetNode.
[oota-llvm.git] / lib / IR / Attributes.cpp
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
 //===----------------------------------------------------------------------===//