Index: llvm/include/llvm/IR/Attributes.h =================================================================== --- llvm/include/llvm/IR/Attributes.h +++ llvm/include/llvm/IR/Attributes.h @@ -285,9 +285,9 @@ class AttributeList { public: enum AttrIndex : unsigned { - ReturnIndex = 0U, - FunctionIndex = ~0U, - FirstArgIndex = 1, + FunctionIndex = 0, + ReturnIndex = 1, + FirstArgIndex = 2, }; private: @@ -306,8 +306,8 @@ /// \brief Create an AttributeList with the specified parameters in it. static AttributeList get(LLVMContext &C, ArrayRef> Attrs); - static AttributeList - get(LLVMContext &C, ArrayRef> Attrs); + static AttributeList get(LLVMContext &C, + ArrayRef> Attrs); /// \brief Create an AttributeList from attribute sets for a function, its /// return value, and all of its arguments. @@ -315,13 +315,11 @@ AttributeSet RetAttrs, ArrayRef ArgAttrs); - static AttributeList - getImpl(LLVMContext &C, - ArrayRef> Attrs); - private: explicit AttributeList(AttributeListImpl *LI) : pImpl(LI) {} + static AttributeList getImpl(LLVMContext &C, ArrayRef AttrSets); + public: AttributeList() = default; @@ -480,10 +478,13 @@ /// \brief Return the attributes at the index as a string. std::string getAsString(unsigned Index, bool InAttrGrp = false) const; - using iterator = ArrayRef::iterator; + typedef const AttributeSet *iterator; + iterator begin() const; + iterator end() const; + bool empty() const { return pImpl == nullptr; } + bool size() const; - iterator begin(unsigned Slot) const; - iterator end(unsigned Slot) const; + unsigned getNumAttrSets() const; /// operator==/!= - Provide equality predicates. bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } @@ -499,20 +500,7 @@ } /// \brief Return true if there are no attributes. - bool isEmpty() const { - return getNumSlots() == 0; - } - - /// \brief Return the number of slots used in this attribute list. This is - /// the number of arguments that have an attribute set on them (including the - /// function itself). - unsigned getNumSlots() const; - - /// \brief Return the index for the given slot. - unsigned getSlotIndex(unsigned Slot) const; - - /// \brief Return the attributes at the given slot. - AttributeSet getSlotAttributes(unsigned Slot) const; + bool isEmpty() const { return pImpl == nullptr; } void dump() const; }; Index: llvm/include/llvm/IR/Instructions.h =================================================================== --- llvm/include/llvm/IR/Instructions.h +++ llvm/include/llvm/IR/Instructions.h @@ -1714,7 +1714,7 @@ /// /// The index \p i is interpreted as /// - /// \p i == Attribute::ReturnIndex -> the return value + /// \p i == 0 -> the return value /// \p i in [1, arg_size + 1) -> argument number (\p i - 1) /// \p i in [arg_size + 1, data_operand_size + 1) -> bundle operand at index /// (\p i - 1) in the operand list. Index: llvm/lib/Bitcode/Reader/BitcodeReader.cpp =================================================================== --- llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1234,8 +1234,10 @@ for (unsigned i = 0, e = Record.size(); i != e; i += 2) { AttrBuilder B; + // Map from old to new AttributeList indices. + unsigned ParamIdx = Record[i] + 1; decodeLLVMAttributesForBitcode(B, Record[i+1]); - Attrs.push_back(AttributeList::get(Context, Record[i], B)); + Attrs.push_back(AttributeList::get(Context, ParamIdx, B)); } MAttributes.push_back(AttributeList::get(Context, Attrs)); @@ -1420,6 +1422,7 @@ uint64_t GrpID = Record[0]; uint64_t Idx = Record[1]; // Index of the object this attribute refers to. + ++Idx; // Map from old to new AttributeList indices. AttrBuilder B; for (unsigned i = 2, e = Record.size(); i != e; ++i) { Index: llvm/lib/Bitcode/Writer/BitcodeWriter.cpp =================================================================== --- llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -618,7 +618,9 @@ SmallVector Record; for (ValueEnumerator::IndexAndAttrSet Pair : AttrGrps) { - unsigned AttrListIndex = Pair.first; + // Translate from current AttributeList indices to old indices to preserve + // bitcode compatibility. + unsigned AttrListIndex = Pair.first - 1; AttributeSet AS = Pair.second; Record.push_back(VE.getAttributeGroupID(Pair)); Record.push_back(AttrListIndex); @@ -660,10 +662,12 @@ SmallVector Record; for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { - const AttributeList &A = Attrs[i]; - for (unsigned i = 0, e = A.getNumSlots(); i != e; ++i) - Record.push_back( - VE.getAttributeGroupID({A.getSlotIndex(i), A.getSlotAttributes(i)})); + AttributeList AL = Attrs[i]; + for (unsigned i = 0, e = AL.getNumAttrSets(); i != e; ++i) { + AttributeSet AS = AL.getAttributes(i); + if (AS.hasAttributes()) + Record.push_back(VE.getAttributeGroupID({i, AS})); + } Stream.EmitRecord(bitc::PARAMATTR_CODE_ENTRY, Record); Record.clear(); Index: llvm/lib/Bitcode/Writer/ValueEnumerator.cpp =================================================================== --- llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -899,8 +899,11 @@ } // Do lookups for all attribute groups. - for (unsigned i = 0, e = PAL.getNumSlots(); i != e; ++i) { - IndexAndAttrSet Pair = {PAL.getSlotIndex(i), PAL.getSlotAttributes(i)}; + for (unsigned i = 0, e = PAL.getNumAttrSets(); i != e; ++i) { + AttributeSet AS = PAL.getAttributes(i); + if (!AS.hasAttributes()) + continue; + IndexAndAttrSet Pair = {i, AS}; unsigned &Entry = AttributeGroupMap[Pair]; if (Entry == 0) { AttributeGroups.push_back(Pair); Index: llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp =================================================================== --- llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp +++ llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp @@ -4957,20 +4957,6 @@ // virtual register info from the FuncInfo.ValueMap. if (!EmitFuncArgumentDbgValue(Address, Variable, Expression, dl, 0, true, N)) { - // If variable is pinned by a alloca in dominating bb then - // use StaticAllocaMap. - if (const AllocaInst *AI = dyn_cast(Address)) { - if (AI->getParent() != DI.getParent()) { - DenseMap::iterator SI = - FuncInfo.StaticAllocaMap.find(AI); - if (SI != FuncInfo.StaticAllocaMap.end()) { - SDV = DAG.getFrameIndexDbgValue(Variable, Expression, SI->second, - 0, dl, SDNodeOrder); - DAG.AddDbgValue(SDV, nullptr, false); - return nullptr; - } - } - } DEBUG(dbgs() << "Dropping debug info for " << DI << "\n"); } } Index: llvm/lib/IR/AttributeImpl.h =================================================================== --- llvm/lib/IR/AttributeImpl.h +++ llvm/lib/IR/AttributeImpl.h @@ -209,27 +209,21 @@ /// return type, and parameters. class AttributeListImpl final : public FoldingSetNode, - private TrailingObjects { + private TrailingObjects { friend class AttributeList; friend TrailingObjects; private: - LLVMContext &Context; - unsigned NumSlots; ///< Number of entries in this set. /// Bitset with a bit for each available attribute Attribute::AttrKind. uint64_t AvailableFunctionAttrs; + LLVMContext &Context; + unsigned NumAttrSets; ///< Number of entries in this set. // Helper fn for TrailingObjects class. - size_t numTrailingObjects(OverloadToken) { return NumSlots; } - - /// \brief Return a pointer to the IndexAttrPair for the specified slot. - const IndexAttrPair *getSlotPair(unsigned Slot) const { - return getTrailingObjects() + Slot; - } + size_t numTrailingObjects(OverloadToken) { return NumAttrSets; } public: - AttributeListImpl(LLVMContext &C, - ArrayRef> Slots); + AttributeListImpl(LLVMContext &C, ArrayRef Sets); // AttributesSetImpt is uniqued, these should not be available. AttributeListImpl(const AttributeListImpl &) = delete; @@ -240,40 +234,18 @@ /// \brief Get the context that created this AttributeListImpl. LLVMContext &getContext() { return Context; } - /// \brief Return the number of slots used in this attribute list. This is - /// the number of arguments that have an attribute set on them (including the - /// function itself). - unsigned getNumSlots() const { return NumSlots; } - - /// \brief Get the index of the given "slot" in the AttrNodes list. This index - /// is the index of the return, parameter, or function object that the - /// attributes are applied to, not the index into the AttrNodes list where the - /// attributes reside. - unsigned getSlotIndex(unsigned Slot) const { - return getSlotPair(Slot)->first; - } - - /// \brief Retrieve the attribute set node for the given "slot" in the - /// AttrNode list. - AttributeSet getSlotAttributes(unsigned Slot) const { - return getSlotPair(Slot)->second; - } - /// \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 AttributeSet::iterator iterator; - iterator begin(unsigned Slot) const { - return getSlotAttributes(Slot).begin(); - } - iterator end(unsigned Slot) const { return getSlotAttributes(Slot).end(); } + typedef const AttributeSet* iterator; + iterator begin() const { return getTrailingObjects(); } + iterator end() const { return begin() + NumAttrSets; } void Profile(FoldingSetNodeID &ID) const; - static void Profile(FoldingSetNodeID &ID, - ArrayRef> Nodes); + static void Profile(FoldingSetNodeID &ID, ArrayRef Nodes); void dump() const; }; Index: llvm/lib/IR/Attributes.cpp =================================================================== --- llvm/lib/IR/Attributes.cpp +++ llvm/lib/IR/Attributes.cpp @@ -720,48 +720,35 @@ // AttributeListImpl Definition //===----------------------------------------------------------------------===// -AttributeListImpl::AttributeListImpl( - LLVMContext &C, ArrayRef> Slots) - : Context(C), NumSlots(Slots.size()), AvailableFunctionAttrs(0) { -#ifndef NDEBUG - assert(!Slots.empty() && "pointless AttributeListImpl"); - if (Slots.size() >= 2) { - auto &PrevPair = Slots.front(); - for (auto &CurPair : Slots.drop_front()) { - assert(PrevPair.first <= CurPair.first && "Attribute set not ordered!"); - } - } -#endif +AttributeListImpl::AttributeListImpl(LLVMContext &C, + ArrayRef Sets) + : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) { + assert(!Sets.empty() && "pointless AttributeListImpl"); // There's memory after the node where we can store the entries in. - std::copy(Slots.begin(), Slots.end(), getTrailingObjects()); + std::copy(Sets.begin(), Sets.end(), getTrailingObjects()); // Initialize AvailableFunctionAttrs summary bitset. static_assert(Attribute::EndAttrKinds <= sizeof(AvailableFunctionAttrs) * CHAR_BIT, "Too many attributes"); - static_assert(AttributeList::FunctionIndex == ~0u, - "FunctionIndex should be biggest possible index"); - const auto &Last = Slots.back(); - if (Last.first == AttributeList::FunctionIndex) { - AttributeSet Node = Last.second; - for (Attribute I : Node) { - if (!I.isStringAttribute()) - AvailableFunctionAttrs |= ((uint64_t)1) << I.getKindAsEnum(); - } + static_assert(AttributeList::FunctionIndex == 0U, + "FunctionIndex should be lowest possible index"); + const auto &FnAttrs = Sets.front(); + for (Attribute I : FnAttrs) { + if (!I.isStringAttribute()) + AvailableFunctionAttrs |= ((uint64_t)1) << I.getKindAsEnum(); } } void AttributeListImpl::Profile(FoldingSetNodeID &ID) const { - Profile(ID, makeArrayRef(getSlotPair(0), getNumSlots())); + Profile(ID, makeArrayRef(begin(), end())); } -void AttributeListImpl::Profile( - FoldingSetNodeID &ID, ArrayRef> Nodes) { - for (const auto &Node : Nodes) { - ID.AddInteger(Node.first); - ID.AddPointer(Node.second.SetNode); - } +void AttributeListImpl::Profile(FoldingSetNodeID &ID, + ArrayRef Sets) { + for (const auto &Set : Sets) + ID.AddPointer(Set.SetNode); } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) @@ -774,24 +761,11 @@ // AttributeList Construction and Mutation Methods //===----------------------------------------------------------------------===// -AttributeList AttributeList::getImpl( - LLVMContext &C, ArrayRef> Attrs) { - assert(!Attrs.empty() && "creating pointless AttributeList"); -#ifndef NDEBUG - unsigned LastIndex = 0; - bool IsFirst = true; - for (auto &&AttrPair : Attrs) { - assert((IsFirst || LastIndex < AttrPair.first) && - "unsorted or duplicate AttributeList indices"); - assert(AttrPair.second.hasAttributes() && "pointless AttributeList slot"); - LastIndex = AttrPair.first; - IsFirst = false; - } -#endif - +AttributeList AttributeList::getImpl(LLVMContext &C, + ArrayRef AttrSets) { LLVMContextImpl *pImpl = C.pImpl; FoldingSetNodeID ID; - AttributeListImpl::Profile(ID, Attrs); + AttributeListImpl::Profile(ID, AttrSets); void *InsertPoint; AttributeListImpl *PA = @@ -802,8 +776,8 @@ if (!PA) { // Coallocate entries after the AttributeListImpl itself. void *Mem = ::operator new( - AttributeListImpl::totalSizeToAlloc(Attrs.size())); - PA = new (Mem) AttributeListImpl(C, Attrs); + AttributeListImpl::totalSizeToAlloc(AttrSets.size())); + PA = new (Mem) AttributeListImpl(C, AttrSets); pImpl->AttrsLists.InsertNode(PA, InsertPoint); } @@ -844,7 +818,7 @@ AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec)); } - return getImpl(C, AttrPairVec); + return get(C, AttrPairVec); } AttributeList @@ -854,35 +828,73 @@ if (Attrs.empty()) return AttributeList(); - return getImpl(C, Attrs); + assert(std::is_sorted(Attrs.begin(), Attrs.end(), + [](const std::pair &LHS, + const std::pair &RHS) { + return LHS.first < RHS.first; + }) && + "Misordered Attributes list!"); + assert(none_of(Attrs, + [](const std::pair &Pair) { + return !Pair.second.hasAttributes(); + }) && + "Pointless attribute!"); + + unsigned MaxIndex = 0; + for (auto Pair : Attrs) + MaxIndex = std::max(MaxIndex, Pair.first); + + SmallVector AttrVec(MaxIndex + 1); + for (auto Pair : Attrs) + AttrVec[Pair.first] = Pair.second; + + return getImpl(C, AttrVec); } AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs, AttributeSet RetAttrs, ArrayRef ArgAttrs) { - SmallVector, 8> AttrPairs; + // Find the last position with attributes. Most arguments don't have + // attributes, so it's nice if we can have fewer unique AttributeListImpls by + // dropping empty attribute sets at the end of the list. + unsigned LastAttrPos = ~0U; + if (FnAttrs.hasAttributes()) + LastAttrPos = 0; if (RetAttrs.hasAttributes()) - AttrPairs.emplace_back(ReturnIndex, RetAttrs); - size_t Index = 1; + LastAttrPos = 1; + unsigned Pos = 2; for (AttributeSet AS : ArgAttrs) { if (AS.hasAttributes()) - AttrPairs.emplace_back(Index, AS); - ++Index; + LastAttrPos = Pos; + ++Pos; } - if (FnAttrs.hasAttributes()) - AttrPairs.emplace_back(FunctionIndex, FnAttrs); - if (AttrPairs.empty()) + + // If we don't have any attributes, we're done. + if (LastAttrPos == ~0U) return AttributeList(); - return getImpl(C, AttrPairs); + + SmallVector AttrSets; + AttrSets.reserve(LastAttrPos + 1); + // If we have any attributes, we always have function attributes. + AttrSets.push_back(FnAttrs); + if (LastAttrPos >= 1) + AttrSets.push_back(RetAttrs); + if (LastAttrPos >= 2) { + // Drop the empty argument attribute sets at the end. + ArgAttrs = ArgAttrs.take_front(LastAttrPos - 1); + AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end()); + } + + return getImpl(C, AttrSets); } AttributeList AttributeList::get(LLVMContext &C, unsigned Index, const AttrBuilder &B) { if (!B.hasAttributes()) return AttributeList(); - AttributeSet AS = AttributeSet::get(C, B); - std::pair Arr[1] = {{Index, AS}}; - return getImpl(C, Arr); + SmallVector AttrSets(Index+1); + AttrSets[Index] = AttributeSet::get(C, B); + return getImpl(C, AttrSets); } AttributeList AttributeList::get(LLVMContext &C, unsigned Index, @@ -905,32 +917,22 @@ ArrayRef Attrs) { if (Attrs.empty()) return AttributeList(); - if (Attrs.size() == 1) return Attrs[0]; - - SmallVector, 8> AttrNodeVec; - AttributeListImpl *A0 = Attrs[0].pImpl; - if (A0) - 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 *ALI = Attrs[I].pImpl; - if (!ALI) continue; - SmallVector, 8>::iterator - ANVI = AttrNodeVec.begin(), ANVE; - 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) - ++ANVI; - ANVI = AttrNodeVec.insert(ANVI, *AI) + 1; - } + if (Attrs.size() == 1) + return Attrs[0]; + + unsigned MaxSize = 0; + for (auto &List : Attrs) + MaxSize = std::max(MaxSize, List.getNumAttrSets()); + + SmallVector NewAttrSets(MaxSize); + for (unsigned I = 0; I < MaxSize; ++I) { + AttrBuilder CurBuilder; + for (AttributeList List : Attrs) + CurBuilder.merge(List.getAttributes(I)); + NewAttrSets[I] = AttributeSet::get(C, CurBuilder); } - return getImpl(C, AttrNodeVec); + return getImpl(C, NewAttrSets); } AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index, @@ -954,29 +956,20 @@ Attribute A) const { assert(std::is_sorted(Indices.begin(), Indices.end())); - unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0; - SmallVector AttrVec; + SmallVector AttrSets(this->begin(), this->end()); + unsigned MaxIndex = 0; + for (unsigned Index : Indices) + MaxIndex = std::max(MaxIndex, Index); + if (MaxIndex >= AttrSets.size()) + AttrSets.resize(MaxIndex + 1); + for (unsigned Index : Indices) { - // Add all attribute slots before the current index. - for (; I < E && getSlotIndex(I) < Index; ++I) - AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I)); - - // Add the attribute at this index. If we already have attributes at this - // index, merge them into a new set. - AttrBuilder B; - if (I < E && getSlotIndex(I) == Index) { - B.merge(AttrBuilder(pImpl->getSlotAttributes(I))); - ++I; - } + AttrBuilder B(AttrSets[Index]); B.addAttribute(A); - AttrVec.emplace_back(Index, AttributeSet::get(C, B)); + AttrSets[Index] = AttributeSet::get(C, B); } - // Add remaining attributes. - for (; I < E; ++I) - AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I)); - - return get(C, AttrVec); + return getImpl(C, AttrSets); } AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index, @@ -996,33 +989,15 @@ "Attempt to change alignment!"); #endif - SmallVector AttrVec; - uint64_t NumAttrs = pImpl->getNumSlots(); - unsigned I; + SmallVector AttrSets(this->begin(), this->end()); + if (Index >= AttrSets.size()) + AttrSets.resize(Index + 1); - // Add all the attribute slots before the one we need to merge. - for (I = 0; I < NumAttrs; ++I) { - if (getSlotIndex(I) >= Index) - break; - AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I)); - } + AttrBuilder Merged(AttrSets[Index]); + Merged.merge(B); + AttrSets[Index] = AttributeSet::get(C, Merged); - AttrBuilder NewAttrs; - if (I < NumAttrs && getSlotIndex(I) == Index) { - // We need to merge the attribute sets. - NewAttrs.merge(pImpl->getSlotAttributes(I)); - ++I; - } - NewAttrs.merge(B); - - // Add the new or merged attribute set at this index. - AttrVec.emplace_back(Index, AttributeSet::get(C, NewAttrs)); - - // Add the remaining entries. - for (; I < NumAttrs; ++I) - AttrVec.emplace_back(getSlotIndex(I), pImpl->getSlotAttributes(I)); - - return get(C, AttrVec); + return getImpl(C, AttrSets); } AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index, @@ -1041,54 +1016,36 @@ return removeAttributes(C, Index, B); } -AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned Index, - const AttrBuilder &Attrs) const { +AttributeList +AttributeList::removeAttributes(LLVMContext &C, unsigned Index, + const AttrBuilder &AttrsToRemove) const { if (!pImpl) return AttributeList(); // FIXME it is not obvious how this should work for alignment. // For now, say we can't pass in alignment, which no current use does. - assert(!Attrs.hasAlignmentAttr() && "Attempt to change alignment!"); - - // Add the attribute slots before the one we're trying to add. - SmallVector AttrSets; - uint64_t NumAttrs = pImpl->getNumSlots(); - AttrBuilder B; - uint64_t LastIndex = 0; - for (unsigned I = 0, E = NumAttrs; I != E; ++I) { - if (getSlotIndex(I) >= Index) { - if (getSlotIndex(I) == Index) - B = AttrBuilder(getSlotAttributes(LastIndex++)); - break; - } - LastIndex = I + 1; - AttrSets.push_back({getSlotIndex(I), getSlotAttributes(I)}); - } + assert(!AttrsToRemove.hasAlignmentAttr() && "Attempt to change alignment!"); - // Remove the attributes from the existing set and add them. - B.remove(Attrs); - if (B.hasAttributes()) - AttrSets.push_back({Index, AttributeSet::get(C, B)}); + SmallVector AttrSets(this->begin(), this->end()); + if (Index >= AttrSets.size()) + AttrSets.resize(Index + 1); - // Add the remaining attribute slots. - for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) - AttrSets.push_back({getSlotIndex(I), getSlotAttributes(I)}); + AttrBuilder B(AttrSets[Index]); + B.remove(AttrsToRemove); + AttrSets[Index] = AttributeSet::get(C, B); - return get(C, AttrSets); + return getImpl(C, AttrSets); } AttributeList AttributeList::removeAttributes(LLVMContext &C, unsigned WithoutIndex) const { if (!pImpl) return AttributeList(); - - SmallVector, 4> AttrSet; - for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) { - unsigned Index = getSlotIndex(I); - if (Index != WithoutIndex) - AttrSet.push_back({Index, pImpl->getSlotAttributes(I)}); - } - return get(C, AttrSet); + if (WithoutIndex >= getNumAttrSets()) + return *this; + SmallVector AttrSets(this->begin(), this->end()); + AttrSets[WithoutIndex] = AttributeSet(); + return getImpl(C, AttrSets); } AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C, @@ -1157,20 +1114,22 @@ bool AttributeList::hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const { - return hasAttribute(ArgNo + 1, Kind); + return hasAttribute(ArgNo + FirstArgIndex, Kind); } bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr, unsigned *Index) const { if (!pImpl) return false; - for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) - for (AttributeListImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I); - II != IE; ++II) - if (II->hasAttribute(Attr)) { - if (Index) *Index = pImpl->getSlotIndex(I); - return true; - } + unsigned I = 0; + for (AttributeSet Set : *this) { + if (Set.hasAttribute(Attr)) { + if (Index) + *Index = I; + return true; + } + ++I; + } return false; } @@ -1214,60 +1173,34 @@ } 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->getSlotAttributes(I); - - return AttributeSet(); + if (!pImpl || Index >= getNumAttrSets()) + return AttributeSet(); + return pImpl->begin()[Index]; } -AttributeList::iterator AttributeList::begin(unsigned Slot) const { - if (!pImpl) - return ArrayRef().begin(); - return pImpl->begin(Slot); +AttributeList::iterator AttributeList::begin() const { + return pImpl ? pImpl->begin() : nullptr; } -AttributeList::iterator AttributeList::end(unsigned Slot) const { - if (!pImpl) - return ArrayRef().end(); - return pImpl->end(Slot); +AttributeList::iterator AttributeList::end() const { + return pImpl ? pImpl->end() : nullptr; } //===----------------------------------------------------------------------===// // AttributeList Introspection Methods //===----------------------------------------------------------------------===// -unsigned AttributeList::getNumSlots() const { - return pImpl ? pImpl->getNumSlots() : 0; -} - -unsigned AttributeList::getSlotIndex(unsigned Slot) const { - assert(pImpl && Slot < pImpl->getNumSlots() && - "Slot # out of range!"); - return pImpl->getSlotIndex(Slot); -} - -AttributeSet AttributeList::getSlotAttributes(unsigned Slot) const { - assert(pImpl && Slot < pImpl->getNumSlots() && - "Slot # out of range!"); - return pImpl->getSlotAttributes(Slot); +unsigned AttributeList::getNumAttrSets() const { + return pImpl ? pImpl->NumAttrSets : 0; } #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) LLVM_DUMP_METHOD void AttributeList::dump() const { dbgs() << "PAL[\n"; - for (unsigned i = 0, e = getNumSlots(); i < e; ++i) { - uint64_t Index = getSlotIndex(i); - dbgs() << " { "; - if (Index == ~0U) - dbgs() << "~0U"; - else - dbgs() << Index; - dbgs() << " => " << getAsString(Index) << " }\n"; + for (unsigned i = 0, e = getNumAttrSets(); i < e; ++i) { + if (getAttributes(i).hasAttributes()) + dbgs() << " { " << i << " => " << getAsString(i) << " }\n"; } dbgs() << "]\n"; @@ -1278,26 +1211,16 @@ // AttrBuilder Method Implementations //===----------------------------------------------------------------------===// +// FIXME: Remove this ctor, use AttributeSet. AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) { - AttributeListImpl *pImpl = AL.pImpl; - if (!pImpl) return; - - for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) { - if (pImpl->getSlotIndex(I) != Index) continue; - - for (AttributeListImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I); - II != IE; ++II) - addAttribute(*II); - - break; - } + AttributeSet AS = AL.getAttributes(Index); + for (const Attribute &A : AS) + addAttribute(A); } AttrBuilder::AttrBuilder(AttributeSet AS) { - if (AS.hasAttributes()) { - for (const Attribute &A : AS) - addAttribute(A); - } + for (const Attribute &A : AS) + addAttribute(A); } void AttrBuilder::clear() { Index: llvm/lib/IR/Core.cpp =================================================================== --- llvm/lib/IR/Core.cpp +++ llvm/lib/IR/Core.cpp @@ -1853,18 +1853,32 @@ F->clearGC(); } +/// Adjust an LLVMAttributeIndex from the C API indices to the internal C++ +/// indices used by the AttributeList interface. +static void adjustAttrListIndex(LLVMAttributeIndex &Idx) { + // Adding one works: + // type | C API | C++ API + // func | -1 | 0 + // ret | 0 | 1 + // arg | 1... | 2... + ++Idx; +} + void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef A) { + adjustAttrListIndex(Idx); unwrap(F)->addAttribute(Idx, unwrap(A)); } unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) { + adjustAttrListIndex(Idx); auto AS = unwrap(F)->getAttributes().getAttributes(Idx); return AS.getNumAttributes(); } void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs) { + adjustAttrListIndex(Idx); auto AS = unwrap(F)->getAttributes().getAttributes(Idx); for (auto A : AS) *Attrs++ = wrap(A); @@ -1873,6 +1887,7 @@ LLVMAttributeRef LLVMGetEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID) { + adjustAttrListIndex(Idx); return wrap(unwrap(F)->getAttribute(Idx, (Attribute::AttrKind)KindID)); } @@ -1880,16 +1895,19 @@ LLVMAttributeRef LLVMGetStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { + adjustAttrListIndex(Idx); return wrap(unwrap(F)->getAttribute(Idx, StringRef(K, KLen))); } void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID) { + adjustAttrListIndex(Idx); unwrap(F)->removeAttribute(Idx, (Attribute::AttrKind)KindID); } void LLVMRemoveStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { + adjustAttrListIndex(Idx); unwrap(F)->removeAttribute(Idx, StringRef(K, KLen)); } @@ -2170,11 +2188,13 @@ void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef A) { + adjustAttrListIndex(Idx); CallSite(unwrap(C)).addAttribute(Idx, unwrap(A)); } unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, LLVMAttributeIndex Idx) { + adjustAttrListIndex(Idx); auto CS = CallSite(unwrap(C)); auto AS = CS.getAttributes().getAttributes(Idx); return AS.getNumAttributes(); @@ -2182,6 +2202,7 @@ void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs) { + adjustAttrListIndex(Idx); auto CS = CallSite(unwrap(C)); auto AS = CS.getAttributes().getAttributes(Idx); for (auto A : AS) @@ -2191,6 +2212,7 @@ LLVMAttributeRef LLVMGetCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID) { + adjustAttrListIndex(Idx); return wrap(CallSite(unwrap(C)) .getAttribute(Idx, (Attribute::AttrKind)KindID)); } @@ -2198,18 +2220,21 @@ LLVMAttributeRef LLVMGetCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { + adjustAttrListIndex(Idx); return wrap(CallSite(unwrap(C)) .getAttribute(Idx, StringRef(K, KLen))); } void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID) { + adjustAttrListIndex(Idx); CallSite(unwrap(C)) .removeAttribute(Idx, (Attribute::AttrKind)KindID); } void LLVMRemoveCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { + adjustAttrListIndex(Idx); CallSite(unwrap(C)).removeAttribute(Idx, StringRef(K, KLen)); } Index: llvm/lib/IR/Instructions.cpp =================================================================== --- llvm/lib/IR/Instructions.cpp +++ llvm/lib/IR/Instructions.cpp @@ -418,6 +418,9 @@ // question is a call argument; or be indirectly implied by the kind of its // containing operand bundle, if the operand is a bundle operand. + if (i == 0) + return hasRetAttr(Kind); + // FIXME: Avoid these i - 1 calculations and update the API to use zero-based // indices. if (i < (getNumArgOperands() + 1)) Index: llvm/lib/IR/Verifier.cpp =================================================================== --- llvm/lib/IR/Verifier.cpp +++ llvm/lib/IR/Verifier.cpp @@ -1720,17 +1720,9 @@ } bool Verifier::verifyAttributeCount(AttributeList Attrs, unsigned Params) { - if (Attrs.getNumSlots() == 0) - return true; - - unsigned LastSlot = Attrs.getNumSlots() - 1; - unsigned LastIndex = Attrs.getSlotIndex(LastSlot); - if (LastIndex <= Params || - (LastIndex == AttributeList::FunctionIndex && - (LastSlot == 0 || Attrs.getSlotIndex(LastSlot - 1) <= Params))) - return true; - - return false; + // There shouldn't be more attribute sets than there are parameters plus the + // function and return value. + return Attrs.getNumAttrSets() <= Params + 2; } /// Verify that statepoint intrinsic is well formed. Index: llvm/lib/Transforms/Utils/FunctionComparator.cpp =================================================================== --- llvm/lib/Transforms/Utils/FunctionComparator.cpp +++ llvm/lib/Transforms/Utils/FunctionComparator.cpp @@ -76,12 +76,14 @@ int FunctionComparator::cmpAttrs(const AttributeList L, const AttributeList R) const { - if (int Res = cmpNumbers(L.getNumSlots(), R.getNumSlots())) + if (int Res = cmpNumbers(L.getNumAttrSets(), R.getNumAttrSets())) return Res; - for (unsigned i = 0, e = L.getNumSlots(); i != e; ++i) { - AttributeList::iterator LI = L.begin(i), LE = L.end(i), RI = R.begin(i), - RE = R.end(i); + for (unsigned i = 0, e = L.getNumAttrSets(); i != e; ++i) { + AttributeSet LAS = L.getAttributes(i); + AttributeSet RAS = R.getAttributes(i); + AttributeSet::iterator LI = LAS.begin(), LE = LAS.end(); + AttributeSet::iterator RI = RAS.begin(), RE = RAS.end(); for (; LI != LE && RI != RE; ++LI, ++RI) { Attribute LA = *LI; Attribute RA = *RI; Index: llvm/test/CodeGen/X86/2012-11-30-misched-dbg.ll =================================================================== --- llvm/test/CodeGen/X86/2012-11-30-misched-dbg.ll +++ /dev/null @@ -1,142 +0,0 @@ -; RUN: llc < %s -mtriple=x86_64-apple-macosx -enable-misched \ -; RUN: -verify-machineinstrs | FileCheck %s -; -; Test MachineScheduler handling of DBG_VALUE. -; rdar://12776937. -; -; CHECK: %if.else581 -; CHECK: DEBUG_VALUE: num1 -; CHECK: call - -%union.rec = type {} - -@.str15 = external hidden unnamed_addr constant [6 x i8], align 1 - -declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone - -define i32 @AttachGalley(%union.rec** nocapture %suspend_pt) nounwind uwtable ssp !dbg !21 { -entry: - %num14075 = alloca [20 x i8], align 16 - br label %if.end33 - -if.end33: ; preds = %entry - %cmp1733 = icmp eq i32 undef, 0 - br label %if.else581 - -if.else581: ; preds = %if.end33 - %cmp586 = icmp eq i8 undef, -123 - br i1 %cmp586, label %if.then588, label %if.else594 - -if.then588: ; preds = %if.else581 - br label %for.cond1710.preheader - -if.else594: ; preds = %if.else581 - unreachable - -for.cond1710.preheader: ; preds = %if.then588 - br label %for.cond1710 - -for.cond1710: ; preds = %for.cond1710, %for.cond1710.preheader - br i1 undef, label %for.cond1710, label %if.then3344 - -if.then3344: - br label %if.then4073 - -if.then4073: ; preds = %if.then3344 - call void @llvm.dbg.declare(metadata [20 x i8]* %num14075, metadata !4, metadata !DIExpression()), !dbg !DILocation(scope: !5) - %arraydecay4078 = getelementptr inbounds [20 x i8], [20 x i8]* %num14075, i64 0, i64 0 - %0 = load i32, i32* undef, align 4 - %add4093 = add nsw i32 %0, 0 - %conv4094 = sitofp i32 %add4093 to float - %div4095 = fdiv float %conv4094, 5.670000e+02 - %conv4096 = fpext float %div4095 to double - %call4097 = call i32 (i8*, i32, i64, i8*, ...) @__sprintf_chk(i8* %arraydecay4078, i32 0, i64 20, i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str15, i64 0, i64 0), double %conv4096) nounwind - br i1 %cmp1733, label %if.then4107, label %if.else4114 - -if.then4107: ; preds = %if.then4073 - unreachable - -if.else4114: ; preds = %if.then4073 - unreachable -} - -declare i32 @__sprintf_chk(i8*, i32, i64, i8*, ...) - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!35} - -!0 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang version 3.3 (trunk 168918) (llvm/trunk 168920)", isOptimized: true, emissionKind: FullDebug, file: !19, enums: !2, retainedTypes: !2, globals: !2) -!1 = !{!2} -!2 = !{} -!4 = !DILocalVariable(name: "num1", line: 815, scope: !5, file: !14, type: !15) -!5 = distinct !DILexicalBlock(line: 815, column: 0, file: !14, scope: !6) -!6 = distinct !DILexicalBlock(line: 812, column: 0, file: !14, scope: !7) -!7 = distinct !DILexicalBlock(line: 807, column: 0, file: !14, scope: !8) -!8 = distinct !DILexicalBlock(line: 440, column: 0, file: !14, scope: !9) -!9 = distinct !DILexicalBlock(line: 435, column: 0, file: !14, scope: !10) -!10 = distinct !DILexicalBlock(line: 434, column: 0, file: !14, scope: !11) -!11 = distinct !DILexicalBlock(line: 250, column: 0, file: !14, scope: !12) -!12 = distinct !DILexicalBlock(line: 249, column: 0, file: !14, scope: !13) -!13 = distinct !DILexicalBlock(line: 221, column: 0, file: !14, scope: !21) -!14 = !DIFile(filename: "MultiSource/Benchmarks/MiBench/consumer-typeset/z19.c", directory: "MultiSource/Benchmarks/MiBench/consumer-typeset") -!15 = !DICompositeType(tag: DW_TAG_array_type, size: 160, align: 8, baseType: !16, elements: !17) -!16 = !DIBasicType(tag: DW_TAG_base_type, name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) -!17 = !{!18} -!18 = !DISubrange(count: 20) -!19 = !DIFile(filename: "MultiSource/Benchmarks/MiBench/consumer-typeset/z19.c", directory: "MultiSource/Benchmarks/MiBench/consumer-typeset") - -!21 = distinct !DISubprogram(name: "AttachGalley", isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 1, file: !19, scope: !14, type: !22) -!22 = !DISubroutineType(types: !23) -!23 = !{null} - -; Test DebugValue uses visited by RegisterPressureTracker findUseBetween(). -; -; CHECK: @main -; CHECK: DEBUG_VALUE: main:X -; CHECK: call - -%"class.__gnu_cxx::hash_map" = type { %"class.__gnu_cxx::hashtable" } -%"class.__gnu_cxx::hashtable" = type { i64, i64, i64, i64, i64, i64 } - -define void @main() uwtable ssp personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) !dbg !37 { -entry: - %X = alloca %"class.__gnu_cxx::hash_map", align 8 - br i1 undef, label %cond.true, label %cond.end - -cond.true: ; preds = %entry - unreachable - -cond.end: ; preds = %entry - call void @llvm.dbg.declare(metadata %"class.__gnu_cxx::hash_map"* %X, metadata !31, metadata !DIExpression()), !dbg !DILocation(scope: !37) - %_M_num_elements.i.i.i.i = getelementptr inbounds %"class.__gnu_cxx::hash_map", %"class.__gnu_cxx::hash_map"* %X, i64 0, i32 0, i32 5 - invoke void @_Znwm() - to label %exit.i unwind label %lpad2.i.i.i.i - -exit.i: ; preds = %cond.end - unreachable - -lpad2.i.i.i.i: ; preds = %cond.end - %0 = landingpad { i8*, i32 } - cleanup - br i1 undef, label %lpad.body.i.i, label %if.then.i.i.i.i.i.i.i.i - -if.then.i.i.i.i.i.i.i.i: ; preds = %lpad2.i.i.i.i - unreachable - -lpad.body.i.i: ; preds = %lpad2.i.i.i.i - resume { i8*, i32 } %0 -} - -declare i32 @__gxx_personality_v0(...) - -declare void @_Znwm() - -!llvm.dbg.cu = !{!30} - -!30 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (trunk 169129) (llvm/trunk 169135)", isOptimized: true, emissionKind: FullDebug, file: !34, enums: !2, retainedTypes: !2) -!31 = !DILocalVariable(name: "X", line: 29, scope: !37, type: !32) -!32 = !DIDerivedType(tag: DW_TAG_typedef, name: "HM", line: 28, file: !34, baseType: null) -!33 = !DIFile(filename: "SingleSource/Benchmarks/Shootout-C++/hash.cpp", directory: "SingleSource/Benchmarks/Shootout-C++") -!34 = !DIFile(filename: "SingleSource/Benchmarks/Shootout-C++/hash.cpp", directory: "SingleSource/Benchmarks/Shootout-C++") -!35 = !{i32 1, !"Debug Info Version", i32 3} -!37 = distinct !DISubprogram(name: "main", isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !30, scopeLine: 1, file: !19, scope: !14, type: !22) Index: llvm/test/CodeGen/X86/2012-11-30-regpres-dbg.ll =================================================================== --- llvm/test/CodeGen/X86/2012-11-30-regpres-dbg.ll +++ /dev/null @@ -1,47 +0,0 @@ -; RUN: llc < %s -mtriple=x86_64-apple-macosx -enable-misched \ -; RUN: -verify-machineinstrs | FileCheck %s -; -; Test RegisterPressure handling of DBG_VALUE. -; -; CHECK: %entry -; CHECK: DEBUG_VALUE: test:callback -; CHECK: ret - -%struct.btCompoundLeafCallback = type { i32, i32 } - -declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone - -define void @test() unnamed_addr uwtable ssp align 2 !dbg !2 { -entry: - %callback = alloca %struct.btCompoundLeafCallback, align 8 - br i1 undef, label %if.end, label %if.then - -if.then: ; preds = %entry - unreachable - -if.end: ; preds = %entry - call void @llvm.dbg.declare(metadata %struct.btCompoundLeafCallback* %callback, metadata !3, metadata !DIExpression()), !dbg !DILocation(scope: !2) - %m = getelementptr inbounds %struct.btCompoundLeafCallback, %struct.btCompoundLeafCallback* %callback, i64 0, i32 1 - store i32 0, i32* undef, align 8 - %cmp12447 = icmp sgt i32 undef, 0 - br i1 %cmp12447, label %for.body.lr.ph, label %invoke.cont44 - -for.body.lr.ph: ; preds = %if.end - unreachable - -invoke.cont44: ; preds = %if.end - ret void -} - -!llvm.dbg.cu = !{!0} -!llvm.module.flags = !{!8} - -!0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.3 (trunk 168984) (llvm/trunk 168983)", isOptimized: true, emissionKind: FullDebug, file: !6) -!2 = distinct !DISubprogram(name: "test", isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 1, file: !6, scope: !5, type: !7) -!3 = !DILocalVariable(name: "callback", line: 214, scope: !2, type: !4) -!4 = !DICompositeType(tag: DW_TAG_structure_type, name: "btCompoundLeafCallback", line: 90, size: 64, align: 64, file: !6) -!5 = !DIFile(filename: "MultiSource/Benchmarks/Bullet/btCompoundCollisionAlgorithm.cpp", directory: "MultiSource/Benchmarks/Bullet") -!6 = !DIFile(filename: "MultiSource/Benchmarks/Bullet/btCompoundCollisionAlgorithm.cpp", directory: "MultiSource/Benchmarks/Bullet") -!7 = !DISubroutineType(types: !9) -!8 = !{i32 1, !"Debug Info Version", i32 3} -!9 = !{null} Index: llvm/test/DebugInfo/COFF/local-variables.ll =================================================================== --- llvm/test/DebugInfo/COFF/local-variables.ll +++ llvm/test/DebugInfo/COFF/local-variables.ll @@ -28,7 +28,6 @@ ; ASM: .seh_proc f ; ASM: # BB#0: # %entry ; ASM: subq $56, %rsp -; ASM: #DEBUG_VALUE: f:param <- [%RSP+52] ; ASM: movl %ecx, 52(%rsp) ; ASM: [[prologue_end:\.Ltmp.*]]: ; ASM: .cv_loc 0 1 8 7 # t.cpp:8:7 @@ -36,8 +35,6 @@ ; ASM: je .LBB0_2 ; ASM: [[if_start:\.Ltmp.*]]: ; ASM: # BB#1: # %if.then -; ASM: #DEBUG_VALUE: f:param <- [%RSP+52] -; ASM: #DEBUG_VALUE: a <- [%RSP+40] ; ASM: .cv_loc 0 1 9 9 # t.cpp:9:9 ; ASM: movl $42, 40(%rsp) ; ASM: [[inline_site1:\.Ltmp.*]]: @@ -51,8 +48,6 @@ ; ASM: jmp .LBB0_3 ; ASM: [[else_start:\.Ltmp.*]]: ; ASM: .LBB0_2: # %if.else -; ASM: #DEBUG_VALUE: f:param <- [%RSP+52] -; ASM: #DEBUG_VALUE: b <- [%RSP+36] ; ASM: .cv_loc 0 1 13 9 # t.cpp:13:9 ; ASM: movl $42, 36(%rsp) ; ASM: [[inline_site2:\.Ltmp.*]]: Index: llvm/utils/TableGen/IntrinsicEmitter.cpp =================================================================== --- llvm/utils/TableGen/IntrinsicEmitter.cpp +++ llvm/utils/TableGen/IntrinsicEmitter.cpp @@ -563,7 +563,7 @@ if (ae) { while (ai != ae) { unsigned argNo = intrinsic.ArgumentAttributes[ai].first; - unsigned attrIdx = argNo + 1; // Must match AttributeList::FirstArgIndex + unsigned attrIdx = argNo + 2; // Must match AttributeList::FirstArgIndex OS << " const Attribute::AttrKind AttrParam" << attrIdx << "[]= {"; bool addComma = false;