OSDN Git Service

For PR1146:
authorReid Spencer <rspencer@reidspencer.com>
Sun, 22 Apr 2007 05:46:44 +0000 (05:46 +0000)
committerReid Spencer <rspencer@reidspencer.com>
Sun, 22 Apr 2007 05:46:44 +0000 (05:46 +0000)
Make ParamAttrsList objects unique. You can no longer directly create or
destroy them but instead must go through the ParamAttrsList::get()
interface.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@36327 91177308-0d34-0410-b5e6-96231b3b80d8

12 files changed:
include/llvm/DerivedTypes.h
include/llvm/ParameterAttributes.h
lib/AsmParser/llvmAsmParser.y
lib/Bytecode/Reader/Reader.cpp
lib/VMCore/AsmWriter.cpp
lib/VMCore/Function.cpp
lib/VMCore/Instructions.cpp
lib/VMCore/Type.cpp
test/Assembler/2007-02-07-UpgradeCSRETCC.ll
test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll
tools/llvm-upgrade/UpgradeParser.y
tools/llvm2cpp/CppWriter.cpp

index d9cf6b7..6013c26 100644 (file)
@@ -148,7 +148,6 @@ class FunctionType : public DerivedType {
                bool IsVarArgs, ParamAttrsList *Attrs = 0);
 
 public:
-  virtual ~FunctionType();
   /// FunctionType::get - This static method is the primary way of constructing
   /// a FunctionType. 
   ///
index 48044b9..4c4b0c7 100644 (file)
@@ -18,6 +18,7 @@
 #define LLVM_PARAMETER_ATTRIBUTES_H
 
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/FoldingSet.h"
 
 namespace llvm {
 
@@ -39,6 +40,17 @@ enum Attributes {
 
 }
 
+/// This is just a pair of values to associate a set of parameter attributes
+/// with a parameter index.
+/// @brief ParameterAttributes with a parameter index.
+struct ParamAttrsWithIndex {
+  uint16_t attrs; ///< The attributes that are set, |'d together
+  uint16_t index; ///< Index of the parameter for which the attributes apply
+};
+
+/// @brief A vector of attribute/index pairs.
+typedef SmallVector<ParamAttrsWithIndex,4> ParamAttrsVector;
+
 typedef ParamAttr::Attributes ParameterAttributes;
 
 /// This class is used by Function and CallInst to represent the set of 
@@ -50,38 +62,27 @@ typedef ParamAttr::Attributes ParameterAttributes;
 /// a string of mnemonics suitable for LLVM Assembly output. Various accessors
 /// are provided to obtain information about the attributes.
 /// @brief A List of ParameterAttributes.
-class ParamAttrsList {
-  //void operator=(const ParamAttrsList &); // Do not implement
-  //ParamAttrsList(const ParamAttrsList &); // Do not implement
-
-  /// @name Types
+class ParamAttrsList : public FoldingSetNode {
+  /// @name Construction
   /// @{
-  public:
-    /// This is an internal structure used to associate the ParameterAttributes
-    /// with a parameter index. 
-    /// @brief ParameterAttributes with a parameter index.
-    struct ParamAttrsWithIndex {
-      uint16_t attrs; ///< The attributes that are set, |'d together
-      uint16_t index; ///< Index of the parameter for which the attributes apply
-    };
+  private:
+    // ParamAttrsList is uniqued, thes should not be publicly available
+    void operator=(const ParamAttrsList &); // Do not implement
+    ParamAttrsList(const ParamAttrsList &); // Do not implement
+    ParamAttrsList();                       // Do not implement
+    ~ParamAttrsList() {}                    // Not public!
 
-    /// @brief A vector of attribute/index pairs.
-    typedef SmallVector<ParamAttrsWithIndex,4> ParamAttrsVector;
+    /// @brief Construct an ParamAttrsList from a ParamAttrsVector
+    explicit ParamAttrsList(const ParamAttrsVector &attrVec) : attrs(attrVec) {}
 
-  /// @}
-  /// @name Construction
-  /// @{
   public:
-    /// @brief Construct an empty ParamAttrsList
-    ParamAttrsList() {}
-
     /// This method ensures the uniqueness of ParamAttrsList instances. The
     /// argument is a vector of attribute/index pairs as represented by the
     /// ParamAttrsWithIndex structure. The vector is used in the construction of
     /// the ParamAttrsList instance. If an instance with identical vector pairs
     /// exists, it will be returned instead of creating a new instance.
     /// @brief Get a ParamAttrsList instance.
-    ParamAttrsList *get(const ParamAttrsVector &attrVec);
+    static ParamAttrsList *get(const ParamAttrsVector &attrVec);
 
   /// @}
   /// @name Accessors
@@ -155,33 +156,12 @@ class ParamAttrsList {
     /// @brief Return the number of parameter attributes this type has.
     unsigned size() const { return attrs.size(); }
 
-    /// Clients generally should not use this method. It is used internally by
-    /// LLVM.
-    /// @returns true if this ParamAttrsList is empty.
-    /// @brief Determine emptiness of ParamAttrsList.
-    unsigned empty() const { return attrs.empty(); }
-
   /// @}
-  /// @name Mutators
+  /// @name Implementation Details
   /// @{
   public:
-    /// This method will add the \p attrs to the parameter with index
-    /// \p param_index. If the parameter index does not exist it will be created
-    /// and the \p attrs will be the only attributes set. Otherwise, any 
-    /// existing attributes for the specified parameter remain set and the 
-    /// attributes given by \p attrs are also set.
-    /// @brief Add ParameterAttributes.
-    void addAttributes(uint16_t param_index, uint16_t attrs);
-
-    /// This method will remove the \p attrs to the parameter with index
-    /// \p param_index. If the parameter index does not exist in the list,  
-    /// an assertion will occur. If the specified attributes are the last 
-    /// attributes set for the specified parameter index, the attributes for 
-    /// that index are removed completely from the list (size is decremented).
-    /// Otherwise, the specified attributes are removed from the set of 
-    /// attributes for the given index, retaining any others.
-    /// @brief Remove a single ParameterAttribute
-    void removeAttributes(uint16_t param_index, uint16_t attrs);
+    void Profile(FoldingSetNodeID &ID) const;
+    void dump() const;
 
   /// @}
   /// @name Data
index a0c2e25..9b5cc5a 100644 (file)
@@ -1299,24 +1299,28 @@ Types
   }
   | Types '(' ArgTypeListI ')' OptFuncAttrs {
     std::vector<const Type*> Params;
-    ParamAttrsList Attrs;
-    if ($5 != ParamAttr::None)
-      Attrs.addAttributes(0, $5);
+    ParamAttrsVector Attrs;
+    if ($5 != ParamAttr::None) {
+      ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
+      Attrs.push_back(X);
+    }
     unsigned index = 1;
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
     for (; I != E; ++I, ++index) {
       const Type *Ty = I->Ty->get();
       Params.push_back(Ty);
       if (Ty != Type::VoidTy)
-        if (I->Attrs != ParamAttr::None)
-          Attrs.addAttributes(index, I->Attrs);
+        if (I->Attrs != ParamAttr::None) {
+          ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
+          Attrs.push_back(X);
+        }
     }
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
     ParamAttrsList *ActualAttrs = 0;
     if (!Attrs.empty())
-      ActualAttrs = new ParamAttrsList(Attrs);
+      ActualAttrs = ParamAttrsList::get(Attrs);
     FunctionType *FT = FunctionType::get(*$1, Params, isVarArg, ActualAttrs);
     delete $3;   // Delete the argument list
     delete $1;   // Delete the return type handle
@@ -1325,24 +1329,28 @@ Types
   }
   | VOID '(' ArgTypeListI ')' OptFuncAttrs {
     std::vector<const Type*> Params;
-    ParamAttrsList Attrs;
-    if ($5 != ParamAttr::None)
-      Attrs.addAttributes(0, $5);
+    ParamAttrsVector Attrs;
+    if ($5 != ParamAttr::None) {
+      ParamAttrsWithIndex X; X.index = 0; X.attrs = $5;
+      Attrs.push_back(X);
+    }
     TypeWithAttrsList::iterator I = $3->begin(), E = $3->end();
     unsigned index = 1;
     for ( ; I != E; ++I, ++index) {
       const Type* Ty = I->Ty->get();
       Params.push_back(Ty);
       if (Ty != Type::VoidTy)
-        if (I->Attrs != ParamAttr::None)
-          Attrs.addAttributes(index, I->Attrs);
+        if (I->Attrs != ParamAttr::None) {
+          ParamAttrsWithIndex X; X.index = index; X.attrs = I->Attrs;
+          Attrs.push_back(X);
+        }
     }
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
     ParamAttrsList *ActualAttrs = 0;
     if (!Attrs.empty())
-      ActualAttrs = new ParamAttrsList(Attrs);
+      ActualAttrs = ParamAttrsList::get(Attrs);
 
     FunctionType *FT = FunctionType::get($1, Params, isVarArg, ActualAttrs);
     delete $3;      // Delete the argument list
@@ -2135,9 +2143,11 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
     GEN_ERROR("Reference to abstract result: "+ $2->get()->getDescription());
 
   std::vector<const Type*> ParamTypeList;
-  ParamAttrsList ParamAttrs;
-  if ($7 != ParamAttr::None)
-    ParamAttrs.addAttributes(0, $7);
+  ParamAttrsVector Attrs;
+  if ($7 != ParamAttr::None) {
+    ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $7;
+    Attrs.push_back(PAWI);
+  }
   if ($5) {   // If there are arguments...
     unsigned index = 1;
     for (ArgListType::iterator I = $5->begin(); I != $5->end(); ++I, ++index) {
@@ -2146,20 +2156,21 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
         GEN_ERROR("Reference to abstract argument: " + Ty->getDescription());
       ParamTypeList.push_back(Ty);
       if (Ty != Type::VoidTy)
-        if (I->Attrs != ParamAttr::None)
-          ParamAttrs.addAttributes(index, I->Attrs);
+        if (I->Attrs != ParamAttr::None) {
+          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
+          Attrs.push_back(PAWI);
+        }
     }
   }
 
   bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
   if (isVarArg) ParamTypeList.pop_back();
 
-  ParamAttrsList *ActualAttrs = 0;
-  if (!ParamAttrs.empty())
-    ActualAttrs = new ParamAttrsList(ParamAttrs);
+  ParamAttrsList *PAL = 0;
+  if (!Attrs.empty())
+    PAL = ParamAttrsList::get(Attrs);
 
-  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, 
-                                       ActualAttrs);
+  FunctionType *FT = FunctionType::get(*$2, ParamTypeList, isVarArg, PAL);
   const PointerType *PFT = PointerType::get(FT);
   delete $2;
 
@@ -2490,9 +2501,11 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamAttrsList ParamAttrs;
-      if ($8 != ParamAttr::None)
-        ParamAttrs.addAttributes(0, $8);
+      ParamAttrsVector Attrs;
+      if ($8 != ParamAttr::None) {
+        ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = 8;
+        Attrs.push_back(PAWI);
+      }
       ValueRefList::iterator I = $6->begin(), E = $6->end();
       unsigned index = 1;
       for (; I != E; ++I, ++index) {
@@ -2500,14 +2513,16 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
         if (Ty == Type::VoidTy)
           GEN_ERROR("Short call syntax cannot be used with varargs");
         ParamTypes.push_back(Ty);
-        if (I->Attrs != ParamAttr::None)
-          ParamAttrs.addAttributes(index, I->Attrs);
+        if (I->Attrs != ParamAttr::None) {
+          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
+          Attrs.push_back(PAWI);
+        }
       }
 
-      ParamAttrsList *Attrs = 0;
-      if (!ParamAttrs.empty())
-        Attrs = new ParamAttrsList(ParamAttrs);
-      Ty = FunctionType::get($3->get(), ParamTypes, false, Attrs);
+      ParamAttrsList *PAL = 0;
+      if (!Attrs.empty())
+        PAL = ParamAttrsList::get(Attrs);
+      Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
       PFTy = PointerType::get(Ty);
     }
 
@@ -2796,9 +2811,11 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
         !(Ty = dyn_cast<FunctionType>(PFTy->getElementType()))) {
       // Pull out the types of all of the arguments...
       std::vector<const Type*> ParamTypes;
-      ParamAttrsList ParamAttrs;
-      if ($8 != ParamAttr::None)
-        ParamAttrs.addAttributes(0, $8);
+      ParamAttrsVector Attrs;
+      if ($8 != ParamAttr::None) {
+        ParamAttrsWithIndex PAWI; PAWI.index = 0; PAWI.attrs = $8;
+        Attrs.push_back(PAWI);
+      }
       unsigned index = 1;
       ValueRefList::iterator I = $6->begin(), E = $6->end();
       for (; I != E; ++I, ++index) {
@@ -2806,15 +2823,17 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
         if (Ty == Type::VoidTy)
           GEN_ERROR("Short call syntax cannot be used with varargs");
         ParamTypes.push_back(Ty);
-        if (I->Attrs != ParamAttr::None)
-          ParamAttrs.addAttributes(index, I->Attrs);
+        if (I->Attrs != ParamAttr::None) {
+          ParamAttrsWithIndex PAWI; PAWI.index = index; PAWI.attrs = I->Attrs;
+          Attrs.push_back(PAWI);
+        }
       }
 
-      ParamAttrsList *Attrs = 0;
-      if (!ParamAttrs.empty())
-        Attrs = new ParamAttrsList(ParamAttrs);
+      ParamAttrsList *PAL = 0;
+      if (!Attrs.empty())
+        PAL = ParamAttrsList::get(Attrs);
 
-      Ty = FunctionType::get($3->get(), ParamTypes, false, Attrs);
+      Ty = FunctionType::get($3->get(), ParamTypes, false, PAL);
       PFTy = PointerType::get(Ty);
     }
 
index 4979269..4cb67c3 100644 (file)
@@ -1078,16 +1078,18 @@ const Type *BytecodeReader::ParseType() {
 
 ParamAttrsList *BytecodeReader::ParseParamAttrsList() {
   unsigned NumAttrs = read_vbr_uint();
-  ParamAttrsList *Attrs = 0;
+  ParamAttrsList *PAL = 0;
   if (NumAttrs) {
-    Attrs = new ParamAttrsList();
+    ParamAttrsVector Attrs;
+    ParamAttrsWithIndex PAWI;
     while (NumAttrs--) {
-      uint16_t index = read_vbr_uint();
-      uint16_t attrs = read_vbr_uint();
-      Attrs->addAttributes(index, attrs);
+      PAWI.index = read_vbr_uint();
+      PAWI.attrs = read_vbr_uint();
+      Attrs.push_back(PAWI);
     }
+    PAL = ParamAttrsList::get(Attrs);
   }
-  return Attrs;
+  return PAL;
 }
 
 
index da3b1d7..63ec8e4 100644 (file)
@@ -1383,6 +1383,17 @@ void Value::dump() const { print(*cerr.stream()); cerr << '\n'; }
 // Located here because so much of the needed functionality is here.
 void Type::dump() const { print(*cerr.stream()); cerr << '\n'; }
 
+void
+ParamAttrsList::dump() const {
+  cerr << "PAL[ ";
+  for (unsigned i = 0; i < attrs.size(); ++i) {
+    uint16_t index = getParamIndex(i);
+    uint16_t attrs = getParamAttrs(index);
+    cerr << "{" << index << "," << attrs << "} ";
+  }
+  cerr << "]\n";
+}
+
 //===----------------------------------------------------------------------===//
 //                         SlotMachine Implementation
 //===----------------------------------------------------------------------===//
index dbd2148..b6ff70d 100644 (file)
@@ -16,6 +16,7 @@
 #include "llvm/ParameterAttributes.h"
 #include "llvm/IntrinsicInst.h"
 #include "llvm/Support/LeakDetector.h"
+#include "llvm/Support/ManagedStatic.h"
 #include "SymbolTableListTraitsImpl.h"
 #include "llvm/ADT/StringExtras.h"
 using namespace llvm;
@@ -103,35 +104,29 @@ ParamAttrsList::getParamAttrsText(uint16_t Attrs) {
   return Result;
 }
 
-void
-ParamAttrsList::addAttributes(uint16_t Index, uint16_t Attrs) {
-  // First, try to replace an existing one
-  for (unsigned i = 0; i < attrs.size(); ++i)
-    if (attrs[i].index == Index) {
-      attrs[i].attrs |= Attrs;
-      return;
-    }
-
-  // If not found, add a new one
-  ParamAttrsWithIndex Val;
-  Val.attrs = Attrs;
-  Val.index = Index;
-  attrs.push_back(Val);
+void 
+ParamAttrsList::Profile(FoldingSetNodeID &ID) const {
+  for (unsigned i = 0; i < attrs.size(); ++i) {
+    unsigned val = attrs[i].attrs << 16 | attrs[i].index;
+    ID.AddInteger(val);
+  }
 }
 
-void
-ParamAttrsList::removeAttributes(uint16_t Index, uint16_t Attrs) {
-  // Find the index from which to remove the attributes
-  for (unsigned i = 0; i < attrs.size(); ++i)
-    if (attrs[i].index == Index) {
-      attrs[i].attrs &= ~Attrs;
-      if (attrs[i].attrs == ParamAttr::None)
-        attrs.erase(&attrs[i]);
-      return;
-    }
-
-  // The index wasn't found above
-  assert(0 && "Index not found for removeAttributes");
+static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists;
+
+ParamAttrsList *
+ParamAttrsList::get(const ParamAttrsVector &attrVec) {
+  assert(!attrVec.empty() && "Illegal to create empty ParamAttrsList");
+  ParamAttrsList key(attrVec);
+  FoldingSetNodeID ID;
+  key.Profile(ID);
+  void *InsertPos;
+  ParamAttrsList* PAL = ParamAttrsLists->FindNodeOrInsertPos(ID, InsertPos);
+  if (!PAL) {
+    PAL = new ParamAttrsList(attrVec);
+    ParamAttrsLists->InsertNode(PAL, InsertPos);
+  }
+  return PAL;
 }
 
 //===----------------------------------------------------------------------===//
index bfda46d..3bb565d 100644 (file)
@@ -186,7 +186,6 @@ Value *PHINode::hasConstantValue(bool AllowNonDominatingInstruction) const {
 
 CallInst::~CallInst() {
   delete [] OperandList;
-  delete ParamAttrs; // FIXME: ParamAttrsList should be uniqued!
 }
 
 void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) {
@@ -354,7 +353,6 @@ CallInst::CallInst(const CallInst &CI)
 
 InvokeInst::~InvokeInst() {
   delete [] OperandList;
-  delete ParamAttrs; // FIXME: ParamAttrsList should be uniqued!
 }
 
 void InvokeInst::init(Value *Fn, BasicBlock *IfNormal, BasicBlock *IfException,
index 01232c4..3e5b7eb 100644 (file)
@@ -643,20 +643,13 @@ static bool TypesEqual(const Type *Ty, const Type *Ty2,
       return false;
     const ParamAttrsList *Attrs1 = FTy->getParamAttrs();
     const ParamAttrsList *Attrs2 = FTy2->getParamAttrs();
-    if ((!Attrs1 && Attrs2 && !Attrs2->empty()) ||
-        (!Attrs2 && Attrs1 && !Attrs1->empty()) ||
+    if ((!Attrs1 && Attrs2) || (!Attrs2 && Attrs1) ||
         (Attrs1 && Attrs2 && (Attrs1->size() != Attrs2->size() ||
-         (Attrs1->size() > 0 && 
-          Attrs1->getParamAttrs(0) != Attrs2->getParamAttrs(0)))))
+         (Attrs1->getParamAttrs(0) != Attrs2->getParamAttrs(0)))))
       return false;
-    ParamAttrsList PAL1;
-    if (Attrs1)
-      PAL1 = *Attrs1;
-    ParamAttrsList PAL2;
-    if (Attrs2)
-      PAL2 = *Attrs2;
+
     for (unsigned i = 0, e = FTy2->getNumParams(); i != e; ++i) {
-      if (PAL1.getParamAttrs(i+1) != PAL2.getParamAttrs(i+1))
+      if (Attrs1 && Attrs1->getParamAttrs(i+1) != Attrs2->getParamAttrs(i+1))
         return false;
       if (!TypesEqual(FTy->getParamType(i), FTy2->getParamType(i), EqTypes))
         return false;
@@ -1065,15 +1058,10 @@ public:
     if (ParamAttrs)
       if (MTV.ParamAttrs)
         return *ParamAttrs < *MTV.ParamAttrs;
-      else if (ParamAttrs->empty())
-        return true;
       else
         return false;
     else if (MTV.ParamAttrs)
-      if (MTV.ParamAttrs->empty())
-        return false;
-      else
-        return true;
+      return true;
     return false;
   }
 };
@@ -1100,26 +1088,20 @@ FunctionType *FunctionType::get(const Type *ReturnType,
                                 ParamAttrsList *Attrs) {
 
   FunctionValType VT(ReturnType, Params, isVarArg, Attrs);
-  FunctionType *MT = FunctionTypes->get(VT);
-  if (MT) { 
-    delete Attrs; // not needed any more
-    return MT;
+  FunctionType *FT = FunctionTypes->get(VT);
+  if (FT) { 
+    return FT;
   }
 
-
-  MT = (FunctionType*) new char[sizeof(FunctionType) + 
+  FT = (FunctionType*) new char[sizeof(FunctionType) + 
                                 sizeof(PATypeHandle)*(Params.size()+1)];
-  new (MT) FunctionType(ReturnType, Params, isVarArg, Attrs);
-  FunctionTypes->add(VT, MT);
+  new (FT) FunctionType(ReturnType, Params, isVarArg, Attrs);
+  FunctionTypes->add(VT, FT);
 
 #ifdef DEBUG_MERGE_TYPES
-  DOUT << "Derived new type: " << MT << "\n";
+  DOUT << "Derived new type: " << FT << "\n";
 #endif
-  return MT;
-}
-
-FunctionType::~FunctionType() {
-  delete ParamAttrs;
+  return FT;
 }
 
 bool FunctionType::isStructReturn() const {
index 062ee58..745c499 100644 (file)
@@ -1,5 +1,7 @@
 ; For PR1187
 ; RUN: llvm-upgrade < %s > /dev/null
+; XFAIL: *
+; Un-XFAIL this when PR1146 is fixed.
 
 %mystruct = type { int, double }
 %glob = global %mystruct { int 3, double 42.0 }
index d067ac0..48a1458 100644 (file)
@@ -1,4 +1,6 @@
 ; RUN: llvm-upgrade < %s | llvm-as | opt -simplifycfg -disable-output
+; XFAIL: *
+; Un-XFAIL this when PR1146 is finished.
 
        %struct..4._102 = type { %struct.QVectorData* }
        %struct..5._125 = type { %struct.QMapData* }
index 02f4cae..ed84267 100644 (file)
@@ -62,6 +62,7 @@ static bool ObsoleteVarArgs;
 static bool NewVarArgs;
 static BasicBlock *CurBB;
 static GlobalVariable *CurGV;
+static unsigned lastCallingConv;
 
 // This contains info used when building the body of a function.  It is
 // destroyed when the function is completed.
@@ -380,19 +381,18 @@ static bool FuncTysDifferOnlyBySRet(const FunctionType *F1,
   if (F1->getReturnType() != F2->getReturnType() ||
       F1->getNumParams() != F2->getNumParams())
     return false;
-  ParamAttrsList PAL1;
-  if (F1->getParamAttrs())
-    PAL1 = *F1->getParamAttrs();
-  ParamAttrsList PAL2;
-  if (F2->getParamAttrs())
-    PAL2 = *F2->getParamAttrs();
-  if (PAL1.getParamAttrs(0) != PAL2.getParamAttrs(0))
+  const ParamAttrsList *PAL1 = F1->getParamAttrs();
+  const ParamAttrsList *PAL2 = F2->getParamAttrs();
+  if (PAL1 && !PAL2 || PAL2 && !PAL1)
+    return false;
+  if (PAL1 && PAL2 && ((PAL1->size() != PAL2->size()) ||
+      (PAL1->getParamAttrs(0) != PAL2->getParamAttrs(0)))) 
     return false;
   unsigned SRetMask = ~unsigned(ParamAttr::StructRet);
   for (unsigned i = 0; i < F1->getNumParams(); ++i) {
-    if (F1->getParamType(i) != F2->getParamType(i) ||
-        unsigned(PAL1.getParamAttrs(i+1)) & SRetMask !=
-        unsigned(PAL2.getParamAttrs(i+1)) & SRetMask)
+    if (F1->getParamType(i) != F2->getParamType(i) || (PAL1 && PAL2 &&
+        (unsigned(PAL1->getParamAttrs(i+1)) & SRetMask !=
+         unsigned(PAL2->getParamAttrs(i+1)) & SRetMask)))
       return false;
   }
   return true;
@@ -1460,6 +1460,10 @@ upgradeIntrinsicCall(const Type* RetTy, const ValID &ID,
                      std::vector<Value*>& Args) {
 
   std::string Name = ID.Type == ValID::NameVal ? ID.Name : "";
+  if (Name.length() <= 5 || Name[0] != 'l' || Name[1] != 'l' || 
+      Name[2] != 'v' || Name[3] != 'm' || Name[4] != '.')
+    return 0;
+
   switch (Name[5]) {
     case 'i':
       if (Name == "llvm.isunordered.f32" || Name == "llvm.isunordered.f64") {
@@ -2006,17 +2010,17 @@ OptLinkage
   ;
 
 OptCallingConv 
-  : /*empty*/          { $$ = OldCallingConv::C; } 
-  | CCC_TOK            { $$ = OldCallingConv::C; } 
-  | CSRETCC_TOK        { $$ = OldCallingConv::CSRet; } 
-  | FASTCC_TOK         { $$ = OldCallingConv::Fast; } 
-  | COLDCC_TOK         { $$ = OldCallingConv::Cold; } 
-  | X86_STDCALLCC_TOK  { $$ = OldCallingConv::X86_StdCall; } 
-  | X86_FASTCALLCC_TOK { $$ = OldCallingConv::X86_FastCall; } 
+  : /*empty*/          { $$ = lastCallingConv = OldCallingConv::C; } 
+  | CCC_TOK            { $$ = lastCallingConv = OldCallingConv::C; } 
+  | CSRETCC_TOK        { $$ = lastCallingConv = OldCallingConv::CSRet; } 
+  | FASTCC_TOK         { $$ = lastCallingConv = OldCallingConv::Fast; } 
+  | COLDCC_TOK         { $$ = lastCallingConv = OldCallingConv::Cold; } 
+  | X86_STDCALLCC_TOK  { $$ = lastCallingConv = OldCallingConv::X86_StdCall; } 
+  | X86_FASTCALLCC_TOK { $$ = lastCallingConv = OldCallingConv::X86_FastCall; } 
   | CC_TOK EUINT64VAL  {
     if ((unsigned)$2 != $2)
       error("Calling conv too large");
-    $$ = $2;
+    $$ = lastCallingConv = $2;
   }
   ;
 
@@ -2146,8 +2150,17 @@ UpRTypes
     bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
     if (isVarArg) Params.pop_back();
 
+    ParamAttrsList *PAL = 0;
+    if (lastCallingConv == OldCallingConv::CSRet) {
+      ParamAttrsVector Attrs;
+      ParamAttrsWithIndex PAWI;
+      PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+      Attrs.push_back(PAWI);
+      PAL = ParamAttrsList::get(Attrs);
+    }
+
     const FunctionType *FTy =
-      FunctionType::get($1.PAT->get(), Params, isVarArg, 0);
+      FunctionType::get($1.PAT->get(), Params, isVarArg, PAL);
 
     $$.PAT = new PATypeHolder( HandleUpRefs(FTy, $$.S) );
     delete $1.PAT;  // Delete the return type handle
@@ -2930,15 +2943,17 @@ FunctionHeaderH
 
     // Convert the CSRet calling convention into the corresponding parameter
     // attribute.
-    ParamAttrsList *ParamAttrs = 0;
+    ParamAttrsList *PAL = 0;
     if ($1 == OldCallingConv::CSRet) {
-      ParamAttrs = new ParamAttrsList();
-      ParamAttrs->addAttributes(0, ParamAttr::None);     // result
-      ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first arg
+      ParamAttrsVector Attrs;
+      ParamAttrsWithIndex PAWI;
+      PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+      Attrs.push_back(PAWI);
+      PAL = ParamAttrsList::get(Attrs);
     }
 
     const FunctionType *FT = 
-      FunctionType::get(RetTy, ParamTyList, isVarArg, ParamAttrs);
+      FunctionType::get(RetTy, ParamTyList, isVarArg, PAL);
     const PointerType *PFT = PointerType::get(FT);
     delete $2.PAT;
 
@@ -3076,6 +3091,7 @@ FunctionHeaderH
       }
       delete $5;                     // We're now done with the argument list
     }
+    lastCallingConv = OldCallingConv::C;
   }
   ;
 
@@ -3324,15 +3340,17 @@ BBTerminatorInst
           FTySign.add(I->S);
         }
       }
-      ParamAttrsList *ParamAttrs = 0;
+      ParamAttrsList *PAL = 0;
       if ($2 == OldCallingConv::CSRet) {
-        ParamAttrs = new ParamAttrsList();
-        ParamAttrs->addAttributes(0, ParamAttr::None);      // Function result
-        ParamAttrs->addAttributes(1, ParamAttr::StructRet);  // first param
+        ParamAttrsVector Attrs;
+        ParamAttrsWithIndex PAWI;
+        PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+        Attrs.push_back(PAWI);
+        PAL = ParamAttrsList::get(Attrs);
       }
       bool isVarArg = ParamTypes.size() && ParamTypes.back() == Type::VoidTy;
       if (isVarArg) ParamTypes.pop_back();
-      Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, ParamAttrs);
+      Ty = FunctionType::get($3.PAT->get(), ParamTypes, isVarArg, PAL);
       PFTy = PointerType::get(Ty);
       $$.S.copy($3.S);
     } else {
@@ -3375,6 +3393,7 @@ BBTerminatorInst
     cast<InvokeInst>($$.TI)->setCallingConv(upgradeCallingConv($2));
     delete $3.PAT;
     delete $6;
+    lastCallingConv = OldCallingConv::C;
   }
   | Unwind {
     $$.TI = new UnwindInst();
@@ -3729,14 +3748,16 @@ InstVal
         error("Functions cannot return aggregate types");
 
       // Deal with CSRetCC
-      ParamAttrsList *ParamAttrs = 0;
+      ParamAttrsList *PAL = 0;
       if ($2 == OldCallingConv::CSRet) {
-        ParamAttrs = new ParamAttrsList();
-        ParamAttrs->addAttributes(0, ParamAttr::None);     // function result
-        ParamAttrs->addAttributes(1, ParamAttr::StructRet); // first parameter
+        ParamAttrsVector Attrs;
+        ParamAttrsWithIndex PAWI;
+        PAWI.index = 1;  PAWI.attrs = ParamAttr::StructRet; // first arg
+        Attrs.push_back(PAWI);
+        PAL = ParamAttrsList::get(Attrs);
       }
 
-      FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, ParamAttrs);
+      FTy = FunctionType::get(RetTy, ParamTypes, isVarArg, PAL);
       PFTy = PointerType::get(FTy);
       $$.S.copy($3.S);
     } else {
@@ -3792,6 +3813,7 @@ InstVal
     }
     delete $3.PAT;
     delete $6;
+    lastCallingConv = OldCallingConv::C;
   }
   | MemoryInst {
     $$ = $1;
index 42a8560..58c67b7 100644 (file)
@@ -461,13 +461,14 @@ CppWriter::printTypeInternal(const Type* Ty) {
       const ParamAttrsList *PAL = FT->getParamAttrs();
       Out << "ParamAttrsList *" << typeName << "_PAL = 0;";
       nl(Out);
-      if (PAL && !PAL->empty()) {
-        Out << typeName << "_PAL = new ParamAttrsList();";
-        nl(Out);
+      if (PAL) {
+        Out << '{'; in(); nl(Out);
+        Out << "ParamAttrsVector Attrs;"; nl(Out);
+        Out << "ParamAttrsWithIndex PAWI;"; nl(Out);
         for (unsigned i = 0; i < PAL->size(); ++i) {
           uint16_t index = PAL->getParamIndex(i);
           uint16_t attrs = PAL->getParamAttrs(index);
-          Out << typeName << "_PAL->addAttributes(" << index << ", 0";
+          Out << "PAWI.index = " << index << "; PAWI.attrs = 0 ";
           if (attrs & ParamAttr::SExt)
             Out << " | ParamAttr::SExt";
           if (attrs & ParamAttr::ZExt)
@@ -480,9 +481,15 @@ CppWriter::printTypeInternal(const Type* Ty) {
             Out << " | ParamAttr::NoReturn";
           if (attrs & ParamAttr::NoUnwind)
             Out << " | ParamAttr::NoUnwind";
-          Out << ");";
+          Out << ";";
+          nl(Out);
+          Out << "Attrs.push_back(PAWI);";
           nl(Out);
         }
+        Out << typeName << "_PAL = ParamAttrsList::get(Attrs);";
+        nl(Out);
+        out(); nl(Out);
+        Out << '}'; nl(Out);
       }
       bool isForward = printTypeInternal(FT->getReturnType());
       std::string retTypeName(getCppName(FT->getReturnType()));