From 4f859aa532dbf061736f9c23e0d0882b5cdfe566 Mon Sep 17 00:00:00 2001 From: Reid Spencer Date: Sun, 22 Apr 2007 05:46:44 +0000 Subject: [PATCH] For PR1146: 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 --- include/llvm/DerivedTypes.h | 1 - include/llvm/ParameterAttributes.h | 74 +++++--------- lib/AsmParser/llvmAsmParser.y | 99 +++++++++++-------- lib/Bytecode/Reader/Reader.cpp | 14 +-- lib/VMCore/AsmWriter.cpp | 11 +++ lib/VMCore/Function.cpp | 47 ++++----- lib/VMCore/Instructions.cpp | 2 - lib/VMCore/Type.cpp | 44 +++------ test/Assembler/2007-02-07-UpgradeCSRETCC.ll | 2 + .../SimplifyCFG/2006-10-29-InvokeCrash.ll | 2 + tools/llvm-upgrade/UpgradeParser.y | 90 ++++++++++------- tools/llvm2cpp/CppWriter.cpp | 17 +++- 12 files changed, 211 insertions(+), 192 deletions(-) diff --git a/include/llvm/DerivedTypes.h b/include/llvm/DerivedTypes.h index d9cf6b77db2..6013c265f0b 100644 --- a/include/llvm/DerivedTypes.h +++ b/include/llvm/DerivedTypes.h @@ -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. /// diff --git a/include/llvm/ParameterAttributes.h b/include/llvm/ParameterAttributes.h index 48044b95914..4c4b0c75821 100644 --- a/include/llvm/ParameterAttributes.h +++ b/include/llvm/ParameterAttributes.h @@ -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 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 - /// @{ - 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 - }; - - /// @brief A vector of attribute/index pairs. - typedef SmallVector ParamAttrsVector; - - /// @} +class ParamAttrsList : public FoldingSetNode { /// @name Construction /// @{ - public: - /// @brief Construct an empty ParamAttrsList - ParamAttrsList() {} + 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 Construct an ParamAttrsList from a ParamAttrsVector + explicit ParamAttrsList(const ParamAttrsVector &attrVec) : attrs(attrVec) {} + + public: /// 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 diff --git a/lib/AsmParser/llvmAsmParser.y b/lib/AsmParser/llvmAsmParser.y index a0c2e25bc5b..9b5cc5abfd5 100644 --- a/lib/AsmParser/llvmAsmParser.y +++ b/lib/AsmParser/llvmAsmParser.y @@ -1299,24 +1299,28 @@ Types } | Types '(' ArgTypeListI ')' OptFuncAttrs { std::vector 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 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 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(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector 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(PFTy->getElementType()))) { // Pull out the types of all of the arguments... std::vector 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); } diff --git a/lib/Bytecode/Reader/Reader.cpp b/lib/Bytecode/Reader/Reader.cpp index 49792693dcc..4cb67c31565 100644 --- a/lib/Bytecode/Reader/Reader.cpp +++ b/lib/Bytecode/Reader/Reader.cpp @@ -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; } diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index da3b1d7769b..63ec8e423e5 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -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 //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index dbd21481c0c..b6ff70d6a33 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -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; - } +static ManagedStatic > ParamAttrsLists; - // The index wasn't found above - assert(0 && "Index not found for removeAttributes"); +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; } //===----------------------------------------------------------------------===// diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index bfda46d9831..3bb565d22a7 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -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, diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 01232c41baf..3e5b7eb4911 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -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 { diff --git a/test/Assembler/2007-02-07-UpgradeCSRETCC.ll b/test/Assembler/2007-02-07-UpgradeCSRETCC.ll index 062ee58c3fe..745c499d3f8 100644 --- a/test/Assembler/2007-02-07-UpgradeCSRETCC.ll +++ b/test/Assembler/2007-02-07-UpgradeCSRETCC.ll @@ -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 } diff --git a/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll b/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll index d067ac09944..48a1458508a 100644 --- a/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll +++ b/test/Transforms/SimplifyCFG/2006-10-29-InvokeCrash.ll @@ -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* } diff --git a/tools/llvm-upgrade/UpgradeParser.y b/tools/llvm-upgrade/UpgradeParser.y index 02f4cae685e..ed84267d08a 100644 --- a/tools/llvm-upgrade/UpgradeParser.y +++ b/tools/llvm-upgrade/UpgradeParser.y @@ -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& 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($$.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; diff --git a/tools/llvm2cpp/CppWriter.cpp b/tools/llvm2cpp/CppWriter.cpp index 42a8560215a..58c67b716e3 100644 --- a/tools/llvm2cpp/CppWriter.cpp +++ b/tools/llvm2cpp/CppWriter.cpp @@ -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()));