Now Attributes are divided in three groups
- return attributes - inreg, zext and sext
- parameter attributes
- function attributes - nounwind, readonly, readnone, noreturn

Return attributes use 0 as the index.
Function attributes use ~0U as the index.

This patch requires corresponding changes in llvm-gcc and clang.

llvm-svn: 56704
diff --git a/llvm/lib/Transforms/IPO/AddReadAttrs.cpp b/llvm/lib/Transforms/IPO/AddReadAttrs.cpp
index 4e0677b..897548b 100644
--- a/llvm/lib/Transforms/IPO/AddReadAttrs.cpp
+++ b/llvm/lib/Transforms/IPO/AddReadAttrs.cpp
@@ -105,10 +105,10 @@
     MadeChange = true;
 
     // Clear out any existing attributes.
-    F->removeAttribute(0, Attribute::ReadOnly | Attribute::ReadNone);
+    F->removeAttribute(~0, Attribute::ReadOnly | Attribute::ReadNone);
 
     // Add in the new attribute.
-    F->addAttribute(0, ReadsMemory ? Attribute::ReadOnly : Attribute::ReadNone);
+    F->addAttribute(~0, ReadsMemory ? Attribute::ReadOnly : Attribute::ReadNone);
 
     if (ReadsMemory)
       NumReadOnly++;
diff --git a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
index fe6583e..d66e2c4 100644
--- a/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -508,7 +508,7 @@
   const AttrListPtr &PAL = F->getAttributes();
 
   // Add any return attributes.
-  if (Attributes attrs = PAL.getAttributes(0))
+  if (Attributes attrs = PAL.getRetAttributes())
     AttributesVec.push_back(AttributeWithIndex::get(0, attrs));
 
   // First, determine the new argument list
@@ -525,7 +525,7 @@
     } else if (!ArgsToPromote.count(I)) {
       // Unchanged argument
       Params.push_back(I->getType());
-      if (Attributes attrs = PAL.getAttributes(ArgIndex))
+      if (Attributes attrs = PAL.getParamAttributes(ArgIndex))
         AttributesVec.push_back(AttributeWithIndex::get(Params.size(), attrs));
     } else if (I->use_empty()) {
       // Dead argument (which are always marked as promotable)
@@ -578,6 +578,10 @@
     }
   }
 
+  // Add any function attributes.
+  if (Attributes attrs = PAL.getFnAttributes())
+    AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
+
   const Type *RetTy = FTy->getReturnType();
 
   // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
@@ -621,7 +625,7 @@
     const AttrListPtr &CallPAL = CS.getAttributes();
 
     // Add any return attributes.
-    if (Attributes attrs = CallPAL.getAttributes(0))
+    if (Attributes attrs = CallPAL.getRetAttributes())
       AttributesVec.push_back(AttributeWithIndex::get(0, attrs));
 
     // Loop over the operands, inserting GEP and loads in the caller as
@@ -633,7 +637,7 @@
       if (!ArgsToPromote.count(I) && !ByValArgsToTransform.count(I)) {
         Args.push_back(*AI);          // Unmodified argument
 
-        if (Attributes Attrs = CallPAL.getAttributes(ArgIndex))
+        if (Attributes Attrs = CallPAL.getParamAttributes(ArgIndex))
           AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
 
       } else if (ByValArgsToTransform.count(I)) {
@@ -688,10 +692,14 @@
     // Push any varargs arguments on the list
     for (; AI != CS.arg_end(); ++AI, ++ArgIndex) {
       Args.push_back(*AI);
-      if (Attributes Attrs = CallPAL.getAttributes(ArgIndex))
+      if (Attributes Attrs = CallPAL.getParamAttributes(ArgIndex))
         AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
     }
 
+    // Add any function attributes.
+    if (Attributes attrs = CallPAL.getFnAttributes())
+      AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
+
     Instruction *New;
     if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
       New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
diff --git a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
index eef326b..8f0c4c4 100644
--- a/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
+++ b/llvm/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -229,6 +229,8 @@
       SmallVector<AttributeWithIndex, 8> AttributesVec;
       for (unsigned i = 0; PAL.getSlot(i).Index <= NumArgs; ++i)
         AttributesVec.push_back(PAL.getSlot(i));
+      if (Attributes FnAttrs = PAL.getFnAttributes()) 
+        AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
       PAL = AttrListPtr::get(AttributesVec.begin(), AttributesVec.end());
     }
 
@@ -593,8 +595,8 @@
   const AttrListPtr &PAL = F->getAttributes();
 
   // The existing function return attributes.
-  Attributes RAttrs = PAL.getAttributes(0);
-
+  Attributes RAttrs = PAL.getRetAttributes();
+  Attributes FnAttrs = PAL.getFnAttributes();
 
   // Find out the new return value.
 
@@ -678,7 +680,7 @@
 
       // Get the original parameter attributes (skipping the first one, that is
       // for the return value.
-      if (Attributes Attrs = PAL.getAttributes(i + 1))
+      if (Attributes Attrs = PAL.getParamAttributes(i + 1))
         AttributesVec.push_back(AttributeWithIndex::get(Params.size(), Attrs));
     } else {
       ++NumArgumentsEliminated;
@@ -687,6 +689,9 @@
     }
   }
 
+  if (FnAttrs != Attribute::None) 
+    AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
+
   // Reconstruct the AttributesList based on the vector we constructed.
   AttrListPtr NewPAL = AttrListPtr::get(AttributesVec.begin(), AttributesVec.end());
 
@@ -730,7 +735,8 @@
     const AttrListPtr &CallPAL = CS.getAttributes();
 
     // The call return attributes.
-    Attributes RAttrs = CallPAL.getAttributes(0);
+    Attributes RAttrs = CallPAL.getRetAttributes();
+    Attributes FnAttrs = CallPAL.getFnAttributes();
     // Adjust in case the function was changed to return void.
     RAttrs &= ~Attribute::typeIncompatible(NF->getReturnType());
     if (RAttrs)
@@ -746,7 +752,7 @@
       if (ArgAlive[i]) {
         Args.push_back(*I);
         // Get original parameter attributes, but skip return attributes.
-        if (Attributes Attrs = CallPAL.getAttributes(i + 1))
+        if (Attributes Attrs = CallPAL.getParamAttributes(i + 1))
           AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
       }
 
@@ -756,13 +762,16 @@
     // Push any varargs arguments on the list. Don't forget their attributes.
     for (CallSite::arg_iterator E = CS.arg_end(); I != E; ++I, ++i) {
       Args.push_back(*I);
-      if (Attributes Attrs = CallPAL.getAttributes(i + 1))
+      if (Attributes Attrs = CallPAL.getParamAttributes(i + 1))
         AttributesVec.push_back(AttributeWithIndex::get(Args.size(), Attrs));
     }
 
+    if (FnAttrs != Attribute::None)
+      AttributesVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
+
     // Reconstruct the AttributesList based on the vector we constructed.
     AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec.begin(),
-                                          AttributesVec.end());
+                                              AttributesVec.end());
 
     Instruction *New;
     if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
diff --git a/llvm/lib/Transforms/IPO/PruneEH.cpp b/llvm/lib/Transforms/IPO/PruneEH.cpp
index 821e7d5..6221844 100644
--- a/llvm/lib/Transforms/IPO/PruneEH.cpp
+++ b/llvm/lib/Transforms/IPO/PruneEH.cpp
@@ -133,7 +133,7 @@
         NewAttributes |= Attribute::NoReturn;
 
       const AttrListPtr &PAL = SCC[i]->getFunction()->getAttributes();
-      const AttrListPtr &NPAL = PAL.addAttr(0, NewAttributes);
+      const AttrListPtr &NPAL = PAL.addAttr(~0, NewAttributes);
       if (PAL != NPAL) {
         MadeChange = true;
         SCC[i]->getFunction()->setAttributes(NPAL);
diff --git a/llvm/lib/Transforms/IPO/StructRetPromotion.cpp b/llvm/lib/Transforms/IPO/StructRetPromotion.cpp
index 07b9e50..96ef66c 100644
--- a/llvm/lib/Transforms/IPO/StructRetPromotion.cpp
+++ b/llvm/lib/Transforms/IPO/StructRetPromotion.cpp
@@ -210,7 +210,7 @@
   const AttrListPtr &PAL = F->getAttributes();
 
   // Add any return attributes.
-  if (Attributes attrs = PAL.getAttributes(0))
+  if (Attributes attrs = PAL.getRetAttributes())
     AttributesVec.push_back(AttributeWithIndex::get(0, attrs));
 
   // Skip first argument.
@@ -221,12 +221,17 @@
   unsigned ParamIndex = 2; 
   while (I != E) {
     Params.push_back(I->getType());
-    if (Attributes Attrs = PAL.getAttributes(ParamIndex))
+    if (Attributes Attrs = PAL.getParamAttributes(ParamIndex))
       AttributesVec.push_back(AttributeWithIndex::get(ParamIndex - 1, Attrs));
     ++I;
     ++ParamIndex;
   }
 
+  // Add any fn attributes.
+  if (Attributes attrs = PAL.getFnAttributes())
+    AttributesVec.push_back(AttributeWithIndex::get(~0, attrs));
+
+
   FunctionType *NFTy = FunctionType::get(STy, Params, FTy->isVarArg());
   Function *NF = Function::Create(NFTy, F->getLinkage());
   NF->takeName(F);
@@ -264,7 +269,7 @@
 
     const AttrListPtr &PAL = F->getAttributes();
     // Add any return attributes.
-    if (Attributes attrs = PAL.getAttributes(0))
+    if (Attributes attrs = PAL.getRetAttributes())
       ArgAttrsVec.push_back(AttributeWithIndex::get(0, attrs));
 
     // Copy arguments, however skip first one.
@@ -276,12 +281,15 @@
     unsigned ParamIndex = 2; 
     while (AI != AE) {
       Args.push_back(*AI); 
-      if (Attributes Attrs = PAL.getAttributes(ParamIndex))
+      if (Attributes Attrs = PAL.getParamAttributes(ParamIndex))
         ArgAttrsVec.push_back(AttributeWithIndex::get(ParamIndex - 1, Attrs));
       ++ParamIndex;
       ++AI;
     }
 
+    // Add any function attributes.
+    if (Attributes attrs = PAL.getFnAttributes())
+      ArgAttrsVec.push_back(AttributeWithIndex::get(~0, attrs));
     
     AttrListPtr NewPAL = AttrListPtr::get(ArgAttrsVec.begin(), ArgAttrsVec.end());
     
diff --git a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
index 1decf2d..9023db7 100644
--- a/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/Scalar/InstructionCombining.cpp
@@ -9127,7 +9127,7 @@
       return false;   // Cannot transform this return value.
 
     if (!CallerPAL.isEmpty() && !Caller->use_empty()) {
-      Attributes RAttrs = CallerPAL.getAttributes(0);
+      Attributes RAttrs = CallerPAL.getRetAttributes();
       if (RAttrs & Attribute::typeIncompatible(NewRetTy))
         return false;   // Attribute not compatible with transformed value.
     }
@@ -9157,7 +9157,8 @@
     if (!CastInst::isCastable(ActTy, ParamTy))
       return false;   // Cannot transform this parameter value.
 
-    if (CallerPAL.getAttributes(i + 1) & Attribute::typeIncompatible(ParamTy))
+    if (CallerPAL.getParamAttributes(i + 1) 
+        & Attribute::typeIncompatible(ParamTy))
       return false;   // Attribute not compatible with transformed value.
 
     // Converting from one pointer type to another or between a pointer and an
@@ -9193,7 +9194,7 @@
   attrVec.reserve(NumCommonArgs);
 
   // Get any return attributes.
-  Attributes RAttrs = CallerPAL.getAttributes(0);
+  Attributes RAttrs = CallerPAL.getRetAttributes();
 
   // If the return value is not being used, the type may not be compatible
   // with the existing attributes.  Wipe out any problematic attributes.
@@ -9216,7 +9217,7 @@
     }
 
     // Add any parameter attributes.
-    if (Attributes PAttrs = CallerPAL.getAttributes(i + 1))
+    if (Attributes PAttrs = CallerPAL.getParamAttributes(i + 1))
       attrVec.push_back(AttributeWithIndex::get(i + 1, PAttrs));
   }
 
@@ -9246,12 +9247,15 @@
         }
 
         // Add any parameter attributes.
-        if (Attributes PAttrs = CallerPAL.getAttributes(i + 1))
+        if (Attributes PAttrs = CallerPAL.getParamAttributes(i + 1))
           attrVec.push_back(AttributeWithIndex::get(i + 1, PAttrs));
       }
     }
   }
 
+  if (Attributes FnAttrs =  CallerPAL.getFnAttributes())
+    attrVec.push_back(AttributeWithIndex::get(~0, FnAttrs));
+
   if (NewRetTy == Type::VoidTy)
     Caller->setName("");   // Void type should not have a name.
 
@@ -9337,7 +9341,7 @@
       if (NestAttrs.paramHasAttr(NestIdx, Attribute::Nest)) {
         // Record the parameter type and any other attributes.
         NestTy = *I;
-        NestAttr = NestAttrs.getAttributes(NestIdx);
+        NestAttr = NestAttrs.getParamAttributes(NestIdx);
         break;
       }
 
@@ -9352,8 +9356,8 @@
       // Insert the nest argument into the call argument list, which may
       // mean appending it.  Likewise for attributes.
 
-      // Add any function result attributes.
-      if (Attributes Attr = Attrs.getAttributes(0))
+      // Add any result attributes.
+      if (Attributes Attr = Attrs.getRetAttributes())
         NewAttrs.push_back(AttributeWithIndex::get(0, Attr));
 
       {
@@ -9374,7 +9378,7 @@
 
           // Add the original argument and attributes.
           NewArgs.push_back(*I);
-          if (Attributes Attr = Attrs.getAttributes(Idx))
+          if (Attributes Attr = Attrs.getParamAttributes(Idx))
             NewAttrs.push_back
               (AttributeWithIndex::get(Idx + (Idx >= NestIdx), Attr));
 
@@ -9382,6 +9386,10 @@
         } while (1);
       }
 
+      // Add any function attributes.
+      if (Attributes Attr = Attrs.getFnAttributes())
+        NewAttrs.push_back(AttributeWithIndex::get(~0, Attr));
+
       // The trampoline may have been bitcast to a bogus type (FTy).
       // Handle this by synthesizing a new function type, equal to FTy
       // with the chain parameter inserted.