[IR] Add AttributeSet to hide AttributeSetNode* again, NFC
authorReid Kleckner <rnk@google.com>
Wed, 12 Apr 2017 00:38:00 +0000 (00:38 +0000)
committerReid Kleckner <rnk@google.com>
Wed, 12 Apr 2017 00:38:00 +0000 (00:38 +0000)
Summary:
For now, it just wraps AttributeSetNode*. Eventually, it will hold
AvailableAttrs as an inline bitset, and adding and removing enum
attributes will be super cheap.

This sinks AttributeSetNode back down to lib/IR/AttributeImpl.h.

Reviewers: pete, chandlerc

Subscribers: llvm-commits, jfb

Differential Revision: https://reviews.llvm.org/D31940

llvm-svn: 300014

14 files changed:
clang/lib/CodeGen/CodeGenModule.cpp
llvm/include/llvm/IR/AttributeSetNode.h [deleted file]
llvm/include/llvm/IR/Attributes.h
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/AsmParser/LLParser.h
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/AttributeImpl.h
llvm/lib/IR/Attributes.cpp
llvm/lib/IR/Core.cpp
llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
llvm/lib/Transforms/IPO/MergeFunctions.cpp
llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
llvm/lib/Transforms/Utils/CloneFunction.cpp

index 7fe8bf0..e083066 100644 (file)
@@ -2935,7 +2935,7 @@ static void replaceUsesOfNonProtoConstant(llvm::Constant *old,
       continue;
 
     // Get the call site's attribute list.
-    SmallVector<llvm::AttributeSetNode *, 8> newAttrs;
+    SmallVector<llvm::AttributeSet, 8> newAttrs;
     llvm::AttributeList oldAttrs = callSite.getAttributes();
 
     // Collect any return attributes from the call.
diff --git a/llvm/include/llvm/IR/AttributeSetNode.h b/llvm/include/llvm/IR/AttributeSetNode.h
deleted file mode 100644 (file)
index 7dcb9f6..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-//===-- AttributeSetNode.h - AttributeList Internal Node --------*- C++ -*-===//
-//
-//                     The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-///
-/// \file
-/// \brief This file defines the class that represents a group of attributes
-/// that apply to one element: function, return type, or parameter.
-///
-//===----------------------------------------------------------------------===//
-
-#ifndef LLVM_IR_ATTRIBUTESETNODE_H
-#define LLVM_IR_ATTRIBUTESETNODE_H
-
-#include "llvm/ADT/ArrayRef.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/Optional.h"
-#include "llvm/ADT/StringRef.h"
-#include "llvm/IR/Attributes.h"
-#include "llvm/Support/TrailingObjects.h"
-#include <algorithm>
-#include <climits>
-#include <cstdint>
-#include <string>
-#include <utility>
-
-namespace llvm {
-
-//===----------------------------------------------------------------------===//
-/// \class
-/// \brief This class represents a group of attributes that apply to one
-/// element: function, return type, or parameter.
-class AttributeSetNode final
-    : public FoldingSetNode,
-      private TrailingObjects<AttributeSetNode, Attribute> {
-  friend TrailingObjects;
-
-  unsigned NumAttrs; ///< Number of attributes in this node.
-  /// Bitset with a bit for each available attribute Attribute::AttrKind.
-  uint64_t AvailableAttrs;
-
-  AttributeSetNode(ArrayRef<Attribute> Attrs);
-
-public:
-  // AttributesSetNode is uniqued, these should not be available.
-  AttributeSetNode(const AttributeSetNode &) = delete;
-  AttributeSetNode &operator=(const AttributeSetNode &) = delete;
-
-  void operator delete(void *p) { ::operator delete(p); }
-
-  static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);
-
-  static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
-
-  /// \brief Return the number of attributes this AttributeList contains.
-  unsigned getNumAttributes() const { return NumAttrs; }
-
-  bool hasAttribute(Attribute::AttrKind Kind) const {
-    return AvailableAttrs & ((uint64_t)1) << Kind;
-  }
-  bool hasAttribute(StringRef Kind) const;
-  bool hasAttributes() const { return NumAttrs != 0; }
-
-  Attribute getAttribute(Attribute::AttrKind Kind) const;
-  Attribute getAttribute(StringRef Kind) const;
-
-  unsigned getAlignment() const;
-  unsigned getStackAlignment() const;
-  uint64_t getDereferenceableBytes() const;
-  uint64_t getDereferenceableOrNullBytes() const;
-  std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
-  std::string getAsString(bool InAttrGrp) const;
-
-  typedef const Attribute *iterator;
-  iterator begin() const { return getTrailingObjects<Attribute>(); }
-  iterator end() const { return begin() + NumAttrs; }
-
-  void Profile(FoldingSetNodeID &ID) const {
-    Profile(ID, makeArrayRef(begin(), end()));
-  }
-  static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
-    for (const auto &Attr : AttrList)
-      Attr.Profile(ID);
-  }
-};
-
-} // end namespace llvm
-
-#endif // LLVM_IR_ATTRIBUTESETNODE_H
index 6cc856d..457682b 100644 (file)
@@ -197,6 +197,84 @@ inline Attribute unwrap(LLVMAttributeRef Attr) {
 
 //===----------------------------------------------------------------------===//
 /// \class
+/// This class holds the attributes for a particular argument, parameter,
+/// function, or return value. It is an immutable value type that is cheap to
+/// copy. Adding and removing enum attributes is intended to be fast, but adding
+/// and removing string or integer attributes involves a FoldingSet lookup.
+class AttributeSet {
+  // TODO: Extract AvailableAttrs from AttributeSetNode and store them here.
+  // This will allow an efficient implementation of addAttribute and
+  // removeAttribute for enum attrs.
+
+  /// Private implementation pointer.
+  AttributeSetNode *SetNode = nullptr;
+
+  friend AttributeListImpl;
+  template <typename Ty> friend struct DenseMapInfo;
+
+private:
+  AttributeSet(AttributeSetNode *ASN) : SetNode(ASN) {}
+
+public:
+  /// AttributeSet is a trivially copyable value type.
+  AttributeSet() = default;
+  AttributeSet(const AttributeSet &) = default;
+  ~AttributeSet() = default;
+
+  static AttributeSet get(LLVMContext &C, const AttrBuilder &B);
+  static AttributeSet get(LLVMContext &C, ArrayRef<Attribute> Attrs);
+
+  bool operator==(const AttributeSet &O) { return SetNode == O.SetNode; }
+  bool operator!=(const AttributeSet &O) { return !(*this == O); }
+
+  unsigned getNumAttributes() const;
+
+  bool hasAttributes() const { return SetNode != nullptr; }
+
+  bool hasAttribute(Attribute::AttrKind Kind) const;
+  bool hasAttribute(StringRef Kind) const;
+
+  Attribute getAttribute(Attribute::AttrKind Kind) const;
+  Attribute getAttribute(StringRef Kind) const;
+
+  unsigned getAlignment() const;
+  unsigned getStackAlignment() const;
+  uint64_t getDereferenceableBytes() const;
+  uint64_t getDereferenceableOrNullBytes() const;
+  std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
+  std::string getAsString(bool InAttrGrp) const;
+
+  typedef const Attribute *iterator;
+  iterator begin() const;
+  iterator end() const;
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief Provide DenseMapInfo for AttributeSet.
+template <> struct DenseMapInfo<AttributeSet> {
+  static inline AttributeSet getEmptyKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-1);
+    Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
+    return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
+  }
+
+  static inline AttributeSet getTombstoneKey() {
+    uintptr_t Val = static_cast<uintptr_t>(-2);
+    Val <<= PointerLikeTypeTraits<void *>::NumLowBitsAvailable;
+    return AttributeSet(reinterpret_cast<AttributeSetNode *>(Val));
+  }
+
+  static unsigned getHashValue(AttributeSet AS) {
+    return (unsigned((uintptr_t)AS.SetNode) >> 4) ^
+           (unsigned((uintptr_t)AS.SetNode) >> 9);
+  }
+
+  static bool isEqual(AttributeSet LHS, AttributeSet RHS) { return LHS == RHS; }
+};
+
+//===----------------------------------------------------------------------===//
+/// \class
 /// \brief This class holds the attributes for a function, its return value, and
 /// its parameters. You access the attributes for each of them via an index into
 /// the AttributeList object. The function attributes are at index
@@ -213,6 +291,7 @@ public:
 private:
   friend class AttrBuilder;
   friend class AttributeListImpl;
+  friend class AttributeSet;
   friend class AttributeSetNode;
 
   template <typename Ty> friend struct DenseMapInfo;
@@ -226,7 +305,7 @@ public:
   static AttributeList get(LLVMContext &C,
                            ArrayRef<std::pair<unsigned, Attribute>> Attrs);
   static AttributeList
-  get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs);
+  get(LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
 
   /// \brief Create an AttributeList from a vector of AttributeSetNodes. The
   /// index of each set is implied by its position in the array \p Attrs:
@@ -234,11 +313,11 @@ public:
   /// 1 to n-1 : Argument attributes
   ///   n      : Function attributes
   /// Any element that has no entries should be left null.
-  static AttributeList get(LLVMContext &C, ArrayRef<AttributeSetNode *> Attrs);
+  static AttributeList get(LLVMContext &C, ArrayRef<AttributeSet> Attrs);
 
   static AttributeList
   getImpl(LLVMContext &C,
-          ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs);
+          ArrayRef<std::pair<unsigned, AttributeSet>> Attrs);
 
 private:
   explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {}
@@ -280,7 +359,7 @@ public:
                               AttributeList Attrs) const;
 
   AttributeList addAttributes(LLVMContext &C, unsigned Index,
-                              AttributeSetNode *AS) const;
+                              AttributeSet AS) const;
 
   AttributeList addAttributes(LLVMContext &C, unsigned Index,
                               const AttrBuilder &B) const;
@@ -339,16 +418,16 @@ public:
   LLVMContext &getContext() const;
 
   /// \brief The attributes for the specified index are returned.
-  AttributeSetNode *getAttributes(unsigned Index) const;
+  AttributeSet getAttributes(unsigned Index) const;
 
   /// \brief The attributes for the specified index are returned.
-  AttributeSetNode *getParamAttributes(unsigned Index) const;
+  AttributeSet getParamAttributes(unsigned Index) const;
 
   /// \brief The attributes for the ret value are returned.
-  AttributeSetNode *getRetAttributes() const;
+  AttributeSet getRetAttributes() const;
 
   /// \brief The function attributes are returned.
-  AttributeSetNode *getFnAttributes() const;
+  AttributeSet getFnAttributes() const;
 
   /// \brief Return true if the attribute exists at the given index.
   bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
@@ -483,7 +562,7 @@ public:
     addAttribute(A);
   }
   AttrBuilder(AttributeList AS, unsigned Idx);
-  AttrBuilder(AttributeSetNode *AS);
+  AttrBuilder(AttributeSet AS);
 
   void clear();
 
index ffe6203..68d448e 100644 (file)
@@ -19,7 +19,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/AsmParser/SlotMapping.h"
 #include "llvm/IR/Argument.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/AutoUpgrade.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CallingConv.h"
@@ -2155,7 +2154,7 @@ bool LLParser::ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
         return true;
     }
     ArgList.push_back(ParamInfo(
-        ArgLoc, V, AttributeSetNode::get(V->getContext(), ArgAttrs)));
+        ArgLoc, V, AttributeSet::get(V->getContext(), ArgAttrs)));
   }
 
   if (IsMustTailCall && InVarArgsFunc)
@@ -2261,7 +2260,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
       return Error(TypeLoc, "invalid type for function argument");
 
     ArgList.emplace_back(TypeLoc, ArgTy,
-                         AttributeSetNode::get(ArgTy->getContext(), Attrs),
+                         AttributeSet::get(ArgTy->getContext(), Attrs),
                          std::move(Name));
 
     while (EatIfPresent(lltok::comma)) {
@@ -2289,7 +2288,7 @@ bool LLParser::ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList,
         return Error(TypeLoc, "invalid type for function argument");
 
       ArgList.emplace_back(TypeLoc, ArgTy,
-                           AttributeSetNode::get(ArgTy->getContext(), Attrs),
+                           AttributeSet::get(ArgTy->getContext(), Attrs),
                            std::move(Name));
     }
   }
@@ -2314,7 +2313,7 @@ bool LLParser::ParseFunctionType(Type *&Result) {
   for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
     if (!ArgList[i].Name.empty())
       return Error(ArgList[i].Loc, "argument name invalid in function type");
-    if (ArgList[i].Attrs)
+    if (ArgList[i].Attrs.hasAttributes())
       return Error(ArgList[i].Loc,
                    "argument attributes invalid in function type");
   }
@@ -4763,16 +4762,16 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
   // Okay, if we got here, the function is syntactically valid.  Convert types
   // and do semantic checks.
   std::vector<Type*> ParamTypeList;
-  SmallVector<AttributeSetNode *, 8> Attrs;
+  SmallVector<AttributeSet, 8> Attrs;
 
-  Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
+  Attrs.push_back(AttributeSet::get(Context, RetAttrs));
 
   for (unsigned i = 0, e = ArgList.size(); i != e; ++i) {
     ParamTypeList.push_back(ArgList[i].Ty);
     Attrs.push_back(ArgList[i].Attrs);
   }
 
-  Attrs.push_back(AttributeSetNode::get(Context, FuncAttrs));
+  Attrs.push_back(AttributeSet::get(Context, FuncAttrs));
 
   AttributeList PAL = AttributeList::get(Context, Attrs);
 
@@ -5384,8 +5383,8 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
     return true;
 
   // Set up the Attribute for the function.
-  SmallVector<AttributeSetNode *, 8> Attrs;
-  Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
+  SmallVector<AttributeSet, 8> Attrs;
+  Attrs.push_back(AttributeSet::get(Context, RetAttrs));
 
   SmallVector<Value*, 8> Args;
 
@@ -5414,7 +5413,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
   if (FnAttrs.hasAlignmentAttr())
     return Error(CallLoc, "invoke instructions may not have an alignment");
 
-  Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
+  Attrs.push_back(AttributeSet::get(Context, FnAttrs));
 
   // Finish off the Attribute and check them
   AttributeList PAL = AttributeList::get(Context, Attrs);
@@ -5978,8 +5977,8 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
     return true;
 
   // Set up the Attribute for the function.
-  SmallVector<AttributeSetNode *, 8> Attrs;
-  Attrs.push_back(AttributeSetNode::get(Context, RetAttrs));
+  SmallVector<AttributeSet, 8> Attrs;
+  Attrs.push_back(AttributeSet::get(Context, RetAttrs));
 
   SmallVector<Value*, 8> Args;
 
@@ -6008,7 +6007,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
   if (FnAttrs.hasAlignmentAttr())
     return Error(CallLoc, "call instructions may not have an alignment");
 
-  Attrs.push_back(AttributeSetNode::get(Context, FnAttrs));
+  Attrs.push_back(AttributeSet::get(Context, FnAttrs));
 
   // Finish off the Attribute and check them
   AttributeList PAL = AttributeList::get(Context, Attrs);
index 2b69333..4616c2e 100644 (file)
@@ -397,8 +397,8 @@ namespace llvm {
     struct ParamInfo {
       LocTy Loc;
       Value *V;
-      AttributeSetNode *Attrs;
-      ParamInfo(LocTy loc, Value *v, AttributeSetNode *attrs)
+      AttributeSet Attrs;
+      ParamInfo(LocTy loc, Value *v, AttributeSet attrs)
           : Loc(loc), V(v), Attrs(attrs) {}
     };
     bool ParseParameterList(SmallVectorImpl<ParamInfo> &ArgList,
@@ -450,9 +450,9 @@ namespace llvm {
     struct ArgInfo {
       LocTy Loc;
       Type *Ty;
-      AttributeSetNode *Attrs;
+      AttributeSet Attrs;
       std::string Name;
-      ArgInfo(LocTy L, Type *ty, AttributeSetNode *Attr, const std::string &N)
+      ArgInfo(LocTy L, Type *ty, AttributeSet Attr, const std::string &N)
           : Loc(L), Ty(ty), Attrs(Attr), Name(N) {}
     };
     bool ParseArgumentList(SmallVectorImpl<ArgInfo> &ArgList, bool &isVarArg);
index e995a58..50774a3 100644 (file)
@@ -21,7 +21,6 @@
 #include "llvm/ADT/SmallString.h"
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/IR/AssemblyAnnotationWriter.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallingConv.h"
@@ -606,7 +605,7 @@ private:
   unsigned mdnNext;
 
   /// asMap - The slot map for attribute sets.
-  DenseMap<AttributeSetNode *, unsigned> asMap;
+  DenseMap<AttributeSet, unsigned> asMap;
   unsigned asNext;
 public:
   /// Construct from a module.
@@ -629,7 +628,7 @@ public:
   int getLocalSlot(const Value *V);
   int getGlobalSlot(const GlobalValue *V);
   int getMetadataSlot(const MDNode *N);
-  int getAttributeGroupSlot(AttributeSetNode *AS);
+  int getAttributeGroupSlot(AttributeSet AS);
 
   /// If you'd like to deal with a function instead of just a module, use
   /// this method to get its data into the SlotTracker.
@@ -652,8 +651,8 @@ public:
   unsigned mdn_size() const { return mdnMap.size(); }
   bool mdn_empty() const { return mdnMap.empty(); }
 
-  /// AttributeSetNode map iterators.
-  typedef DenseMap<AttributeSetNode *, unsigned>::iterator as_iterator;
+  /// AttributeSet map iterators.
+  typedef DenseMap<AttributeSet, unsigned>::iterator as_iterator;
   as_iterator as_begin()   { return asMap.begin(); }
   as_iterator as_end()     { return asMap.end(); }
   unsigned as_size() const { return asMap.size(); }
@@ -673,8 +672,8 @@ private:
   /// CreateFunctionSlot - Insert the specified Value* into the slot table.
   void CreateFunctionSlot(const Value *V);
 
-  /// \brief Insert the specified AttributeSetNode into the slot table.
-  void CreateAttributeSetSlot(AttributeSetNode *AS);
+  /// \brief Insert the specified AttributeSet into the slot table.
+  void CreateAttributeSetSlot(AttributeSet AS);
 
   /// Add all of the module level global variables (and their initializers)
   /// and function declarations, but not the contents of those functions.
@@ -833,8 +832,8 @@ void SlotTracker::processModule() {
 
     // Add all the function attributes to the table.
     // FIXME: Add attributes of other objects?
-    AttributeSetNode *FnAttrs = F.getAttributes().getFnAttributes();
-    if (FnAttrs)
+    AttributeSet FnAttrs = F.getAttributes().getFnAttributes();
+    if (FnAttrs.hasAttributes())
       CreateAttributeSetSlot(FnAttrs);
   }
 
@@ -869,15 +868,10 @@ void SlotTracker::processFunction() {
 
       // We allow direct calls to any llvm.foo function here, because the
       // target may not be linked into the optimizer.
-      if (const CallInst *CI = dyn_cast<CallInst>(&I)) {
+      if (auto CS = ImmutableCallSite(&I)) {
         // Add all the call attributes to the table.
-        AttributeSetNode *Attrs = CI->getAttributes().getFnAttributes();
-        if (Attrs)
-          CreateAttributeSetSlot(Attrs);
-      } else if (const InvokeInst *II = dyn_cast<InvokeInst>(&I)) {
-        // Add all the call attributes to the table.
-        AttributeSetNode *Attrs = II->getAttributes().getFnAttributes();
-        if (Attrs)
+        AttributeSet Attrs = CS.getAttributes().getFnAttributes();
+        if (Attrs.hasAttributes())
           CreateAttributeSetSlot(Attrs);
       }
     }
@@ -963,11 +957,11 @@ int SlotTracker::getLocalSlot(const Value *V) {
   return FI == fMap.end() ? -1 : (int)FI->second;
 }
 
-int SlotTracker::getAttributeGroupSlot(AttributeSetNode *AS) {
+int SlotTracker::getAttributeGroupSlot(AttributeSet AS) {
   // Check for uninitialized state and do lazy initialization.
   initialize();
 
-  // Find the AttributeSetNode in the module map.
+  // Find the AttributeSet in the module map.
   as_iterator AI = asMap.find(AS);
   return AI == asMap.end() ? -1 : (int)AI->second;
 }
@@ -1017,8 +1011,8 @@ void SlotTracker::CreateMetadataSlot(const MDNode *N) {
       CreateMetadataSlot(Op);
 }
 
-void SlotTracker::CreateAttributeSetSlot(AttributeSetNode *AS) {
-  assert(AS && "Doesn't need a slot!");
+void SlotTracker::CreateAttributeSetSlot(AttributeSet AS) {
+  assert(AS.hasAttributes() && "Doesn't need a slot!");
 
   as_iterator I = asMap.find(AS);
   if (I != asMap.end())
@@ -2607,10 +2601,10 @@ void AssemblyWriter::printFunction(const Function *F) {
 
   const AttributeList &Attrs = F->getAttributes();
   if (Attrs.hasAttributes(AttributeList::FunctionIndex)) {
-    AttributeSetNode *AS = Attrs.getFnAttributes();
+    AttributeSet AS = Attrs.getFnAttributes();
     std::string AttrStr;
 
-    for (const Attribute &Attr : *AS) {
+    for (const Attribute &Attr : AS) {
       if (!Attr.isStringAttribute()) {
         if (!AttrStr.empty()) AttrStr += ' ';
         AttrStr += Attr.getAsString();
@@ -3250,7 +3244,7 @@ void AssemblyWriter::printMDNodeBody(const MDNode *Node) {
 }
 
 void AssemblyWriter::writeAllAttributeGroups() {
-  std::vector<std::pair<AttributeSetNode *, unsigned>> asVec;
+  std::vector<std::pair<AttributeSet, unsigned>> asVec;
   asVec.resize(Machine.as_size());
 
   for (SlotTracker::as_iterator I = Machine.as_begin(), E = Machine.as_end();
@@ -3259,7 +3253,7 @@ void AssemblyWriter::writeAllAttributeGroups() {
 
   for (const auto &I : asVec)
     Out << "attributes #" << I.second << " = { "
-        << I.first->getAsString(true) << " }\n";
+        << I.first.getAsString(true) << " }\n";
 }
 
 void AssemblyWriter::printUseListOrder(const UseListOrder &Order) {
index 0cd53f1..09f0373 100644 (file)
@@ -19,7 +19,6 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/StringRef.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/Support/TrailingObjects.h"
 #include <algorithm>
@@ -144,7 +143,65 @@ public:
   StringRef getStringValue() const { return Val; }
 };
 
-typedef std::pair<unsigned, AttributeSetNode *> IndexAttrPair;
+//===----------------------------------------------------------------------===//
+/// \class
+/// \brief This class represents a group of attributes that apply to one
+/// element: function, return type, or parameter.
+class AttributeSetNode final
+    : public FoldingSetNode,
+      private TrailingObjects<AttributeSetNode, Attribute> {
+  friend TrailingObjects;
+
+  /// Bitset with a bit for each available attribute Attribute::AttrKind.
+  uint64_t AvailableAttrs;
+  unsigned NumAttrs; ///< Number of attributes in this node.
+
+  AttributeSetNode(ArrayRef<Attribute> Attrs);
+
+public:
+  // AttributesSetNode is uniqued, these should not be available.
+  AttributeSetNode(const AttributeSetNode &) = delete;
+  AttributeSetNode &operator=(const AttributeSetNode &) = delete;
+
+  void operator delete(void *p) { ::operator delete(p); }
+
+  static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);
+
+  static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);
+
+  /// \brief Return the number of attributes this AttributeList contains.
+  unsigned getNumAttributes() const { return NumAttrs; }
+
+  bool hasAttribute(Attribute::AttrKind Kind) const {
+    return AvailableAttrs & ((uint64_t)1) << Kind;
+  }
+  bool hasAttribute(StringRef Kind) const;
+  bool hasAttributes() const { return NumAttrs != 0; }
+
+  Attribute getAttribute(Attribute::AttrKind Kind) const;
+  Attribute getAttribute(StringRef Kind) const;
+
+  unsigned getAlignment() const;
+  unsigned getStackAlignment() const;
+  uint64_t getDereferenceableBytes() const;
+  uint64_t getDereferenceableOrNullBytes() const;
+  std::pair<unsigned, Optional<unsigned>> getAllocSizeArgs() const;
+  std::string getAsString(bool InAttrGrp) const;
+
+  typedef const Attribute *iterator;
+  iterator begin() const { return getTrailingObjects<Attribute>(); }
+  iterator end() const { return begin() + NumAttrs; }
+
+  void Profile(FoldingSetNodeID &ID) const {
+    Profile(ID, makeArrayRef(begin(), end()));
+  }
+  static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {
+    for (const auto &Attr : AttrList)
+      Attr.Profile(ID);
+  }
+};
+
+typedef std::pair<unsigned, AttributeSet> IndexAttrPair;
 
 //===----------------------------------------------------------------------===//
 /// \class
@@ -166,13 +223,13 @@ private:
   size_t numTrailingObjects(OverloadToken<IndexAttrPair>) { return NumSlots; }
 
   /// \brief Return a pointer to the IndexAttrPair for the specified slot.
-  const IndexAttrPair *getNode(unsigned Slot) const {
+  const IndexAttrPair *getSlotPair(unsigned Slot) const {
     return getTrailingObjects<IndexAttrPair>() + Slot;
   }
 
 public:
   AttributeListImpl(LLVMContext &C,
-                    ArrayRef<std::pair<unsigned, AttributeSetNode *>> Slots);
+                    ArrayRef<std::pair<unsigned, AttributeSet>> Slots);
 
   // AttributesSetImpt is uniqued, these should not be available.
   AttributeListImpl(const AttributeListImpl &) = delete;
@@ -193,35 +250,35 @@ public:
   /// attributes are applied to, not the index into the AttrNodes list where the
   /// attributes reside.
   unsigned getSlotIndex(unsigned Slot) const {
-    return getNode(Slot)->first;
+    return getSlotPair(Slot)->first;
+  }
+
+  /// \brief Retrieve the attribute set node for the given "slot" in the
+  /// AttrNode list.
+  AttributeSet getSlotNode(unsigned Slot) const {
+    return getSlotPair(Slot)->second;
   }
 
   /// \brief Retrieve the attributes for the given "slot" in the AttrNode list.
   /// \p Slot is an index into the AttrNodes list, not the index of the return /
   /// parameter/ function which the attributes apply to.
   AttributeList getSlotAttributes(unsigned Slot) const {
-    return AttributeList::get(Context, *getNode(Slot));
-  }
-
-  /// \brief Retrieve the attribute set node for the given "slot" in the
-  /// AttrNode list.
-  AttributeSetNode *getSlotNode(unsigned Slot) const {
-    return getNode(Slot)->second;
+    return AttributeList::get(Context, *getSlotPair(Slot));
   }
 
-  /// \brief Return true if the AttributeSetNode for the FunctionIndex has an
+  /// \brief Return true if the AttributeSet or the FunctionIndex has an
   /// enum attribute of the given kind.
   bool hasFnAttribute(Attribute::AttrKind Kind) const {
     return AvailableFunctionAttrs & ((uint64_t)1) << Kind;
   }
 
-  typedef AttributeSetNode::iterator iterator;
-  iterator begin(unsigned Slot) const { return getSlotNode(Slot)->begin(); }
-  iterator end(unsigned Slot) const { return getSlotNode(Slot)->end(); }
+  typedef AttributeSet::iterator iterator;
+  iterator begin(unsigned Slot) const { return getSlotNode(Slot).begin(); }
+  iterator end(unsigned Slot) const { return getSlotNode(Slot).end(); }
 
   void Profile(FoldingSetNodeID &ID) const;
   static void Profile(FoldingSetNodeID &ID,
-                      ArrayRef<std::pair<unsigned, AttributeSetNode*>> Nodes);
+                      ArrayRef<std::pair<unsigned, AttributeSet>> Nodes);
 
   void dump() const;
 };
index 7077da1..4b840c3 100644 (file)
@@ -23,7 +23,6 @@
 #include "llvm/ADT/StringExtras.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/Twine.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/Attributes.h"
 #include "llvm/IR/Function.h"
 #include "llvm/IR/LLVMContext.h"
@@ -492,13 +491,75 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const {
 }
 
 //===----------------------------------------------------------------------===//
+// AttributeSet Definition
+//===----------------------------------------------------------------------===//
+
+AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
+  return AttributeSet(AttributeSetNode::get(C, B));
+}
+
+AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
+  return AttributeSet(AttributeSetNode::get(C, Attrs));
+}
+
+unsigned AttributeSet::getNumAttributes() const {
+  return SetNode ? SetNode->getNumAttributes() : 0;
+}
+
+bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
+  return SetNode ? SetNode->hasAttribute(Kind) : 0;
+}
+
+bool AttributeSet::hasAttribute(StringRef Kind) const {
+  return SetNode ? SetNode->hasAttribute(Kind) : 0;
+}
+
+Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
+  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
+}
+
+Attribute AttributeSet::getAttribute(StringRef Kind) const {
+  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
+}
+
+unsigned AttributeSet::getAlignment() const {
+  return SetNode ? SetNode->getAlignment() : 0;
+}
+
+unsigned AttributeSet::getStackAlignment() const {
+  return SetNode ? SetNode->getStackAlignment() : 0;
+}
+
+uint64_t AttributeSet::getDereferenceableBytes() const {
+  return SetNode ? SetNode->getDereferenceableBytes() : 0;
+}
+
+uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
+  return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
+}
+
+std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
+  return SetNode ? SetNode->getAllocSizeArgs() : std::make_pair(0, 0);
+}
+
+std::string AttributeSet::getAsString(bool InAttrGrp) const {
+  return SetNode ? SetNode->getAsString(InAttrGrp) : "";
+}
+
+AttributeSet::iterator AttributeSet::begin() const {
+  return SetNode ? SetNode->begin() : nullptr;
+}
+
+AttributeSet::iterator AttributeSet::end() const {
+  return SetNode ? SetNode->end() : nullptr;
+}
+
+//===----------------------------------------------------------------------===//
 // AttributeSetNode Definition
 //===----------------------------------------------------------------------===//
 
 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
-    : NumAttrs(Attrs.size()), AvailableAttrs(0) {
-  static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,
-                "Too many attributes for AvailableAttrs");
+    : AvailableAttrs(0), NumAttrs(Attrs.size()) {
   // There's memory after the node where we can store the entries in.
   std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
 
@@ -657,7 +718,7 @@ std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
 //===----------------------------------------------------------------------===//
 
 AttributeListImpl::AttributeListImpl(
-    LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>> Slots)
+    LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Slots)
     : Context(C), NumSlots(Slots.size()), AvailableFunctionAttrs(0) {
 #ifndef NDEBUG
   if (Slots.size() >= 2) {
@@ -678,10 +739,10 @@ AttributeListImpl::AttributeListImpl(
                   "Too many attributes");
     static_assert(AttributeList::FunctionIndex == ~0u,
                   "FunctionIndex should be biggest possible index");
-    const std::pair<unsigned, AttributeSetNode *> &Last = Slots.back();
+    const auto &Last = Slots.back();
     if (Last.first == AttributeList::FunctionIndex) {
-      const AttributeSetNode *Node = Last.second;
-      for (Attribute I : *Node) {
+      AttributeSet Node = Last.second;
+      for (Attribute I : Node) {
         if (!I.isStringAttribute())
           AvailableFunctionAttrs |= ((uint64_t)1) << I.getKindAsEnum();
       }
@@ -690,15 +751,14 @@ AttributeListImpl::AttributeListImpl(
 }
 
 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
-  Profile(ID, makeArrayRef(getNode(0), getNumSlots()));
+  Profile(ID, makeArrayRef(getSlotPair(0), getNumSlots()));
 }
 
 void AttributeListImpl::Profile(
-    FoldingSetNodeID &ID,
-    ArrayRef<std::pair<unsigned, AttributeSetNode *>> Nodes) {
+    FoldingSetNodeID &ID, ArrayRef<std::pair<unsigned, AttributeSet>> Nodes) {
   for (const auto &Node : Nodes) {
     ID.AddInteger(Node.first);
-    ID.AddPointer(Node.second);
+    ID.AddPointer(Node.second.SetNode);
   }
 }
 
@@ -713,7 +773,7 @@ LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
 //===----------------------------------------------------------------------===//
 
 AttributeList AttributeList::getImpl(
-    LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs) {
+    LLVMContext &C, ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
   assert(!Attrs.empty() && "creating pointless AttributeList");
 #ifndef NDEBUG
   unsigned LastIndex = 0;
@@ -721,7 +781,7 @@ AttributeList AttributeList::getImpl(
   for (const auto &AttrPair : Attrs) {
     assert((IsFirst || LastIndex < AttrPair.first) &&
            "unsorted or duplicate AttributeList indices");
-    assert(AttrPair.second && "pointless AttributeList slot");
+    assert(AttrPair.second.hasAttributes() && "pointless AttributeList slot");
     LastIndex = AttrPair.first;
     IsFirst = false;
   }
@@ -769,7 +829,7 @@ AttributeList::get(LLVMContext &C,
 
   // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
   // list.
-  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec;
+  SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
   for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
          E = Attrs.end(); I != E; ) {
     unsigned Index = I->first;
@@ -779,7 +839,7 @@ AttributeList::get(LLVMContext &C,
       ++I;
     }
 
-    AttrPairVec.emplace_back(Index, AttributeSetNode::get(C, AttrVec));
+    AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
   }
 
   return getImpl(C, AttrPairVec);
@@ -787,7 +847,7 @@ AttributeList::get(LLVMContext &C,
 
 AttributeList
 AttributeList::get(LLVMContext &C,
-                   ArrayRef<std::pair<unsigned, AttributeSetNode *>> Attrs) {
+                   ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
   // If there are no attributes then return a null AttributesList pointer.
   if (Attrs.empty())
     return AttributeList();
@@ -795,13 +855,13 @@ AttributeList::get(LLVMContext &C,
   return getImpl(C, Attrs);
 }
 
-AttributeList AttributeList::get(LLVMContext &C, ArrayRef<AttributeSetNode*> Attrs) {
+AttributeList AttributeList::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
   assert(Attrs.size() >= 2 &&
          "should always have function and return attr slots");
-  SmallVector<std::pair<unsigned, AttributeSetNode *>, 8> AttrPairs;
+  SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairs;
   size_t Index = 0;
-  for (AttributeSetNode *AS : Attrs) {
-    if (AS) {
+  for (AttributeSet AS : Attrs) {
+    if (AS.hasAttributes()) {
       // If this is the last AttributeSetNode, it's for the function.
       if (Index == Attrs.size() - 1)
         Index = AttributeList::FunctionIndex;
@@ -818,8 +878,8 @@ AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
                                  const AttrBuilder &B) {
   if (!B.hasAttributes())
     return AttributeList();
-  AttributeSetNode *ASN = AttributeSetNode::get(C, B);
-  std::pair<unsigned, AttributeSetNode *> Arr[1] = {{Index, ASN}};
+  AttributeSet AS = AttributeSet::get(C, B);
+  std::pair<unsigned, AttributeSet> Arr[1] = {{Index, AS}};
   return getImpl(C, Arr);
 }
 
@@ -845,21 +905,21 @@ AttributeList AttributeList::get(LLVMContext &C,
     return AttributeList();
   if (Attrs.size() == 1) return Attrs[0];
 
-  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec;
+  SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrNodeVec;
   AttributeListImpl *A0 = Attrs[0].pImpl;
   if (A0)
-    AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumSlots()));
+    AttrNodeVec.append(A0->getSlotPair(0), A0->getSlotPair(A0->getNumSlots()));
   // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
   // ordered by index.  Because we know that each list in Attrs is ordered by
   // index we only need to merge each successive list in rather than doing a
   // full sort.
   for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
-    AttributeListImpl *AS = Attrs[I].pImpl;
-    if (!AS) continue;
-    SmallVector<std::pair<unsigned, AttributeSetNode *>, 8>::iterator
+    AttributeListImpl *ALI = Attrs[I].pImpl;
+    if (!ALI) continue;
+    SmallVector<std::pair<unsigned, AttributeSet>, 8>::iterator
       ANVI = AttrNodeVec.begin(), ANVE;
-    for (const IndexAttrPair *AI = AS->getNode(0),
-                             *AE = AS->getNode(AS->getNumSlots());
+    for (const IndexAttrPair *AI = ALI->getSlotPair(0),
+                             *AE = ALI->getSlotPair(ALI->getNumSlots());
          AI != AE; ++AI) {
       ANVE = AttrNodeVec.end();
       while (ANVI != ANVE && ANVI->first <= AI->first)
@@ -905,7 +965,7 @@ AttributeList AttributeList::addAttribute(LLVMContext &C,
       ++I;
     }
     B.addAttribute(A);
-    AttrVec.emplace_back(Index, AttributeSetNode::get(C, B));
+    AttrVec.emplace_back(Index, AttributeSet::get(C, B));
   }
 
   // Add remaining attributes.
@@ -924,20 +984,20 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
 }
 
 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
-                                           AttributeSetNode *AS) const {
-  if (!AS)
+                                           AttributeSet AS) const {
+  if (!AS.hasAttributes())
     return *this;
 
 #ifndef NDEBUG
   // FIXME it is not obvious how this should work for alignment. For now, say
   // we can't change a known alignment.
   unsigned OldAlign = getParamAlignment(Index);
-  unsigned NewAlign = AS->getAlignment();
+  unsigned NewAlign = AS.getAlignment();
   assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
          "Attempt to change alignment!");
 #endif
 
-  SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet;
+  SmallVector<std::pair<unsigned, AttributeSet>, 4> AttrSet;
   uint64_t NumAttrs = pImpl->getNumSlots();
   unsigned I;
 
@@ -949,8 +1009,8 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
   }
 
   if (I < NumAttrs && getSlotIndex(I) == Index) {
-    // We need to merge two AttributeSetNodes.
-    AttributeSetNode *Merged = AttributeSetNode::get(
+    // We need to merge two AttributeSets.
+    AttributeSet Merged = AttributeSet::get(
         C, AttrBuilder(pImpl->getSlotNode(I)).merge(AttrBuilder(AS)));
     AttrSet.emplace_back(Index, Merged);
     ++I;
@@ -969,7 +1029,7 @@ AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
 
 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
                                            const AttrBuilder &B) const {
-  return get(C, Index, AttributeSetNode::get(C, B));
+  return get(C, Index, AttributeSet::get(C, B));
 }
 
 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
@@ -998,11 +1058,11 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
   // Add the attribute slots before the one we're trying to add.
   SmallVector<AttributeList, 4> AttrSet;
   uint64_t NumAttrs = pImpl->getNumSlots();
-  AttributeList AS;
+  AttributeList AL;
   uint64_t LastIndex = 0;
   for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
     if (getSlotIndex(I) >= Index) {
-      if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
+      if (getSlotIndex(I) == Index) AL = getSlotAttributes(LastIndex++);
       break;
     }
     LastIndex = I + 1;
@@ -1011,7 +1071,7 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
 
   // Now remove the attribute from the correct slot. There may already be an
   // AttributeList there.
-  AttrBuilder B(AS, Index);
+  AttrBuilder B(AL, Index);
 
   for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
     if (Attrs.getSlotIndex(I) == Index) {
@@ -1040,11 +1100,11 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
   // Add the attribute slots before the one we're trying to add.
   SmallVector<AttributeList, 4> AttrSet;
   uint64_t NumAttrs = pImpl->getNumSlots();
-  AttributeList AS;
+  AttributeList AL;
   uint64_t LastIndex = 0;
   for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
     if (getSlotIndex(I) >= Index) {
-      if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
+      if (getSlotIndex(I) == Index) AL = getSlotAttributes(LastIndex++);
       break;
     }
     LastIndex = I + 1;
@@ -1053,7 +1113,7 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
 
   // Now remove the attribute from the correct slot. There may already be an
   // AttributeList there.
-  AttrBuilder B(AS, Index);
+  AttrBuilder B(AL, Index);
   B.remove(Attrs);
 
   AttrSet.push_back(AttributeList::get(C, Index, B));
@@ -1070,7 +1130,7 @@ AttributeList AttributeList::removeAttributes(LLVMContext &C,
   if (!pImpl)
     return AttributeList();
 
-  SmallVector<std::pair<unsigned, AttributeSetNode *>, 4> AttrSet;
+  SmallVector<std::pair<unsigned, AttributeSet>, 4> AttrSet;
   for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
     unsigned Index = getSlotIndex(I);
     if (Index != WithoutIndex)
@@ -1110,32 +1170,29 @@ AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
 
 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
 
-AttributeSetNode *AttributeList::getParamAttributes(unsigned Index) const {
+AttributeSet AttributeList::getParamAttributes(unsigned Index) const {
   return getAttributes(Index);
 }
 
-AttributeSetNode *AttributeList::getRetAttributes() const {
+AttributeSet AttributeList::getRetAttributes() const {
   return getAttributes(ReturnIndex);
 }
 
-AttributeSetNode *AttributeList::getFnAttributes() const {
+AttributeSet AttributeList::getFnAttributes() const {
   return getAttributes(FunctionIndex);
 }
 
 bool AttributeList::hasAttribute(unsigned Index,
                                  Attribute::AttrKind Kind) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN && ASN->hasAttribute(Kind);
+  return getAttributes(Index).hasAttribute(Kind);
 }
 
 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN && ASN->hasAttribute(Kind);
+  return getAttributes(Index).hasAttribute(Kind);
 }
 
 bool AttributeList::hasAttributes(unsigned Index) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN && ASN->hasAttributes();
+  return getAttributes(Index).hasAttributes();
 }
 
 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
@@ -1163,55 +1220,47 @@ bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
 
 Attribute AttributeList::getAttribute(unsigned Index,
                                       Attribute::AttrKind Kind) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getAttribute(Kind) : Attribute();
+  return getAttributes(Index).getAttribute(Kind);
 }
 
 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getAttribute(Kind) : Attribute();
+  return getAttributes(Index).getAttribute(Kind);
 }
 
 unsigned AttributeList::getParamAlignment(unsigned Index) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getAlignment() : 0;
+  return getAttributes(Index).getAlignment();
 }
 
 unsigned AttributeList::getStackAlignment(unsigned Index) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getStackAlignment() : 0;
+  return getAttributes(Index).getStackAlignment();
 }
 
 uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getDereferenceableBytes() : 0;
+  return getAttributes(Index).getDereferenceableBytes();
 }
 
 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getDereferenceableOrNullBytes() : 0;
+  return getAttributes(Index).getDereferenceableOrNullBytes();
 }
 
 std::pair<unsigned, Optional<unsigned>>
 AttributeList::getAllocSizeArgs(unsigned Index) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getAllocSizeArgs() : std::make_pair(0u, Optional<unsigned>(0u));
+  return getAttributes(Index).getAllocSizeArgs();
 }
 
 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
-  AttributeSetNode *ASN = getAttributes(Index);
-  return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
+  return getAttributes(Index).getAsString(InAttrGrp);
 }
 
-AttributeSetNode *AttributeList::getAttributes(unsigned Index) const {
-  if (!pImpl) return nullptr;
+AttributeSet AttributeList::getAttributes(unsigned Index) const {
+  if (!pImpl) return AttributeSet();
 
   // Loop through to find the attribute node we want.
   for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
     if (pImpl->getSlotIndex(I) == Index)
       return pImpl->getSlotNode(I);
 
-  return nullptr;
+  return AttributeSet();
 }
 
 AttributeList::iterator AttributeList::begin(unsigned Slot) const {
@@ -1268,8 +1317,8 @@ LLVM_DUMP_METHOD void AttributeList::dump() const {
 // AttrBuilder Method Implementations
 //===----------------------------------------------------------------------===//
 
-AttrBuilder::AttrBuilder(AttributeList AS, unsigned Index) {
-  AttributeListImpl *pImpl = AS.pImpl;
+AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
+  AttributeListImpl *pImpl = AL.pImpl;
   if (!pImpl) return;
 
   for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
@@ -1283,9 +1332,9 @@ AttrBuilder::AttrBuilder(AttributeList AS, unsigned Index) {
   }
 }
 
-AttrBuilder::AttrBuilder(AttributeSetNode *AS) {
-  if (AS) {
-    for (const Attribute &A : *AS)
+AttrBuilder::AttrBuilder(AttributeSet AS) {
+  if (AS.hasAttributes()) {
+    for (const Attribute &A : AS)
       addAttribute(A);
   }
 }
index 2636ca1..b5ed30b 100644 (file)
@@ -16,7 +16,6 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Bitcode/BitcodeReader.h"
 #include "llvm/IR/Attributes.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
 #include "llvm/IR/DerivedTypes.h"
@@ -1847,18 +1846,14 @@ void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
 }
 
 unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) {
-  auto *ASN = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
-  if (!ASN)
-    return 0;
-  return ASN->getNumAttributes();
+  auto AS = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
+  return AS.getNumAttributes();
 }
 
 void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx,
                               LLVMAttributeRef *Attrs) {
-  auto *ASN = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
-  if (!ASN)
-    return;
-  for (auto A: make_range(ASN->begin(), ASN->end()))
+  auto AS = unwrap<Function>(F)->getAttributes().getAttributes(Idx);
+  for (auto A : AS)
     *Attrs++ = wrap(A);
 }
 
@@ -2178,19 +2173,15 @@ void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx,
 unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C,
                                        LLVMAttributeIndex Idx) {
   auto CS = CallSite(unwrap<Instruction>(C));
-  auto *ASN = CS.getAttributes().getAttributes(Idx);
-  if (!ASN)
-    return 0;
-  return ASN->getNumAttributes();
+  auto AS = CS.getAttributes().getAttributes(Idx);
+  return AS.getNumAttributes();
 }
 
 void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx,
                                LLVMAttributeRef *Attrs) {
   auto CS = CallSite(unwrap<Instruction>(C));
-  auto *ASN = CS.getAttributes().getAttributes(Idx);
-  if (!ASN)
-    return;
-  for (auto A: make_range(ASN->begin(), ASN->end()))
+  auto AS = CS.getAttributes().getAttributes(Idx);
+  for (auto A : AS)
     *Attrs++ = wrap(A);
 }
 
index 1646237..c43557b 100644 (file)
@@ -42,7 +42,6 @@
 #include "llvm/Analysis/LazyCallGraph.h"
 #include "llvm/Analysis/Loads.h"
 #include "llvm/Analysis/TargetLibraryInfo.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/CFG.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constants.h"
@@ -103,7 +102,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
   // Attribute - Keep track of the parameter attributes for the arguments
   // that we are *not* promoting. For the ones that we do promote, the parameter
   // attributes are lost
-  SmallVector<AttributeSetNode *, 8> AttributesVec;
+  SmallVector<AttributeSet, 8> AttributesVec;
   const AttributeList &PAL = F->getAttributes();
 
   // Add any return attributes.
@@ -118,7 +117,8 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
       Type *AgTy = cast<PointerType>(I->getType())->getElementType();
       StructType *STy = cast<StructType>(AgTy);
       Params.insert(Params.end(), STy->element_begin(), STy->element_end());
-      AttributesVec.insert(AttributesVec.end(), STy->getNumElements(), nullptr);
+      AttributesVec.insert(AttributesVec.end(), STy->getNumElements(),
+                           AttributeSet());
       ++NumByValArgsPromoted;
     } else if (!ArgsToPromote.count(&*I)) {
       // Unchanged argument
@@ -168,7 +168,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
         Params.push_back(GetElementPtrInst::getIndexedType(
             cast<PointerType>(I->getType()->getScalarType())->getElementType(),
             ArgIndex.second));
-        AttributesVec.push_back(nullptr);
+        AttributesVec.push_back(AttributeSet());
         assert(Params.back());
       }
 
@@ -240,7 +240,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
               STy, *AI, Idxs, (*AI)->getName() + "." + Twine(i), Call);
           // TODO: Tell AA about the new values?
           Args.push_back(new LoadInst(Idx, Idx->getName() + ".val", Call));
-          AttributesVec.push_back(nullptr);
+          AttributesVec.push_back(AttributeSet());
         }
       } else if (!I->use_empty()) {
         // Non-dead argument: insert GEPs and loads as appropriate.
@@ -283,7 +283,7 @@ doPromotion(Function *F, SmallPtrSetImpl<Argument *> &ArgsToPromote,
           newLoad->setAAMetadata(AAInfo);
 
           Args.push_back(newLoad);
-          AttributesVec.push_back(nullptr);
+          AttributesVec.push_back(AttributeSet());
         }
       }
 
index c7138bf..66eb33f 100644 (file)
@@ -21,7 +21,6 @@
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/ADT/Statistic.h"
 #include "llvm/ADT/StringExtras.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/CallingConv.h"
 #include "llvm/IR/Constant.h"
@@ -686,12 +685,12 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
   bool HasLiveReturnedArg = false;
 
   // Set up to build a new list of parameter attributes.
-  SmallVector<AttributeSetNode *, 8> AttributesVec;
+  SmallVector<AttributeSet, 8> AttributesVec;
   const AttributeList &PAL = F->getAttributes();
 
   // Reserve an empty slot for the return value attributes, which we will
   // compute last.
-  AttributesVec.push_back(nullptr);
+  AttributesVec.push_back(AttributeSet());
 
   // Remember which arguments are still alive.
   SmallVector<bool, 10> ArgAlive(FTy->getNumParams(), false);
@@ -792,7 +791,7 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
     assert(!RAttrs.overlaps(AttributeFuncs::typeIncompatible(NRetTy)) &&
            "Return attributes no longer compatible?");
 
-  AttributesVec[0] = AttributeSetNode::get(F->getContext(), RAttrs);
+  AttributesVec[0] = AttributeSet::get(F->getContext(), RAttrs);
 
   // Transfer the function attributes, if any.
   AttributesVec.push_back(PAL.getFnAttributes());
@@ -833,7 +832,7 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
     // return void.
     AttrBuilder RAttrs(CallPAL.getRetAttributes());
     RAttrs.remove(AttributeFuncs::typeIncompatible(NRetTy));
-    AttributesVec.push_back(AttributeSetNode::get(F->getContext(), RAttrs));
+    AttributesVec.push_back(AttributeSet::get(F->getContext(), RAttrs));
 
     // Declare these outside of the loops, so we can reuse them for the second
     // loop, which loops the varargs.
@@ -845,15 +844,14 @@ bool DeadArgumentEliminationPass::RemoveDeadStuffFromFunction(Function *F) {
       if (ArgAlive[i]) {
         Args.push_back(*I);
         // Get original parameter attributes, but skip return attributes.
-        AttributeSetNode *Attrs = CallPAL.getParamAttributes(i + 1);
-        if (NRetTy != RetTy && Attrs &&
-            Attrs->hasAttribute(Attribute::Returned)) {
+        AttributeSet Attrs = CallPAL.getParamAttributes(i + 1);
+        if (NRetTy != RetTy && Attrs.hasAttribute(Attribute::Returned)) {
           // If the return type has changed, then get rid of 'returned' on the
           // call site. The alternative is to make all 'returned' attributes on
           // call sites keep the return value alive just like 'returned'
           // attributes on function declaration but it's less clearly a win and
           // this is not an expected case anyway
-          AttributesVec.push_back(AttributeSetNode::get(
+          AttributesVec.push_back(AttributeSet::get(
               F->getContext(),
               AttrBuilder(Attrs).removeAttribute(Attribute::Returned)));
         } else {
index 5d41ca9..4ce4de1 100644 (file)
@@ -439,7 +439,8 @@ void MergeFunctions::replaceDirectCallers(Function *Old, Function *New) {
           Context, AttributeList::ReturnIndex, NewFuncAttrs.getRetAttributes());
 
       for (unsigned argIdx = 0; argIdx < CS.arg_size(); argIdx++) {
-        if (AttributeSetNode *Attrs = NewFuncAttrs.getParamAttributes(argIdx))
+        AttributeSet Attrs = NewFuncAttrs.getParamAttributes(argIdx);
+        if (Attrs.hasAttributes())
           CallSiteAttrs = CallSiteAttrs.addAttributes(Context, argIdx, Attrs);
       }
 
index c850e2e..cdae957 100644 (file)
@@ -23,7 +23,6 @@
 #include "llvm/Analysis/InstructionSimplify.h"
 #include "llvm/Analysis/MemoryBuiltins.h"
 #include "llvm/Analysis/ValueTracking.h"
-#include "llvm/IR/AttributeSetNode.h"
 #include "llvm/IR/BasicBlock.h"
 #include "llvm/IR/CallSite.h"
 #include "llvm/IR/Constant.h"
@@ -4119,7 +4118,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
     }
   }
 
-  AttributeSetNode *FnAttrs = CallerPAL.getFnAttributes();
+  AttributeSet FnAttrs = CallerPAL.getFnAttributes();
   if (CallerPAL.hasAttributes(AttributeList::FunctionIndex))
     attrVec.push_back(AttributeList::get(Callee->getContext(),
                                          AttributeList::FunctionIndex,
@@ -4218,7 +4217,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
   if (!NestAttrs.isEmpty()) {
     unsigned NestIdx = 1;
     Type *NestTy = nullptr;
-    AttributeSetNode *NestAttr;
+    AttributeSet NestAttr;
 
     // Look for a parameter marked with the 'nest' attribute.
     for (FunctionType::param_iterator I = NestFTy->param_begin(),
@@ -4233,7 +4232,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
     if (NestTy) {
       Instruction *Caller = CS.getInstruction();
       std::vector<Value*> NewArgs;
-      std::vector<AttributeSetNode *> NewAttrs;
+      std::vector<AttributeSet> NewAttrs;
       NewArgs.reserve(CS.arg_size() + 1);
       NewAttrs.reserve(CS.arg_size() + 2);
 
index f480302..3a78158 100644 (file)
@@ -103,23 +103,21 @@ void llvm::CloneFunctionInto(Function *NewFunc, const Function *OldFunc,
                  ModuleLevelChanges ? RF_None : RF_NoModuleLevelChanges,
                  TypeMapper, Materializer));
 
-  SmallVector<std::pair<unsigned, AttributeSetNode*>, 4> AttrVec;
+  SmallVector<AttributeSet, 4> AttrVec(NewFunc->arg_size() + 2);
   AttributeList OldAttrs = OldFunc->getAttributes();
 
   // Copy the return attributes.
-  if (auto *RetAttrs = OldAttrs.getRetAttributes())
-    AttrVec.emplace_back(AttributeList::ReturnIndex, RetAttrs);
+  AttrVec[0] = OldAttrs.getRetAttributes();
 
   // Clone any argument attributes that are present in the VMap.
   for (const Argument &OldArg : OldFunc->args())
     if (Argument *NewArg = dyn_cast<Argument>(VMap[&OldArg])) {
-      if (auto *ParmAttrs = OldAttrs.getParamAttributes(OldArg.getArgNo() + 1))
-        AttrVec.emplace_back(NewArg->getArgNo() + 1, ParmAttrs);
+      AttrVec[NewArg->getArgNo() + 1] =
+          OldAttrs.getParamAttributes(OldArg.getArgNo() + 1);
     }
 
   // Copy any function attributes.
-  if (auto *FnAttrs = OldAttrs.getFnAttributes())
-    AttrVec.emplace_back(AttributeList::FunctionIndex, FnAttrs);
+  AttrVec.back() = OldAttrs.getFnAttributes();
 
   NewFunc->setAttributes(AttributeList::get(NewFunc->getContext(), AttrVec));