diff --git a/llvm/docs/ReleaseNotes.rst b/llvm/docs/ReleaseNotes.rst --- a/llvm/docs/ReleaseNotes.rst +++ b/llvm/docs/ReleaseNotes.rst @@ -60,6 +60,9 @@ will be removed after LLVM 14. In the meantime, only minimal effort will be made to maintain the legacy pass manager for the optimization pipeline. * Max allowed integer type was reduced from 2^24-1 bits to 2^23 bits. +* Indexes to the AttributeList API have been shifted by one to be more + reasonable. The indexes exposed via the C API and written to bitcode have not + been changed to preserve backward compatibility. Changes to building LLVM ------------------------ diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -398,9 +398,9 @@ class AttributeList { public: enum AttrIndex : unsigned { - ReturnIndex = 0U, - FunctionIndex = ~0U, - FirstArgIndex = 1, + FunctionIndex = 0U, + ReturnIndex = 1U, + FirstArgIndex = 2U, }; private: @@ -853,7 +853,7 @@ /// Use these to iterate over the valid attribute indices. unsigned index_begin() const { return AttributeList::FunctionIndex; } - unsigned index_end() const { return getNumAttrSets() - 1; } + unsigned index_end() const { return getNumAttrSets(); } /// operator==/!= - Provide equality predicates. bool operator==(const AttributeList &RHS) const { return pImpl == RHS.pImpl; } diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td --- a/llvm/include/llvm/IR/Intrinsics.td +++ b/llvm/include/llvm/IR/Intrinsics.td @@ -64,9 +64,9 @@ class AttrIndex { int Value = idx; } -def FuncIndex : AttrIndex<-1>; -def RetIndex : AttrIndex<0>; -class ArgIndex : AttrIndex; +def FuncIndex : AttrIndex<0>; +def RetIndex : AttrIndex<1>; +class ArgIndex : AttrIndex; // NoCapture - The specified argument pointer is not captured by the intrinsic. class NoCapture : IntrinsicProperty { diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -1355,7 +1355,8 @@ for (unsigned i = 0, e = Record.size(); i != e; i += 2) { AttrBuilder B; decodeLLVMAttributesForBitcode(B, Record[i+1]); - Attrs.push_back(AttributeList::get(Context, Record[i], B)); + // For historical reasons, the attribute index is off by one. + Attrs.push_back(AttributeList::get(Context, Record[i] + 1, B)); } MAttributes.push_back(AttributeList::get(Context, Attrs)); @@ -1593,7 +1594,9 @@ return error("Invalid record"); uint64_t GrpID = Record[0]; - uint64_t Idx = Record[1]; // Index of the object this attribute refers to. + // Index of the object this attribute refers to. + // For historical reasons, the attribute index is off by one. + uint64_t Idx = static_cast(Record[1]) + 1; AttrBuilder B; for (unsigned i = 2, e = Record.size(); i != e; ++i) { diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -788,7 +788,8 @@ unsigned AttrListIndex = Pair.first; AttributeSet AS = Pair.second; Record.push_back(VE.getAttributeGroupID(Pair)); - Record.push_back(AttrListIndex); + // For historical reasons, the attribute index is off by one. + Record.push_back(AttrListIndex - 1); for (Attribute Attr : AS) { if (Attr.isEnumAttribute()) { diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -946,12 +946,6 @@ // AttributeListImpl Definition //===----------------------------------------------------------------------===// -/// Map from AttributeList index to the internal array index. Adding one happens -/// to work, because -1 wraps around to 0. -static unsigned attrIdxToArrayIdx(unsigned Index) { - return Index + 1; -} - AttributeListImpl::AttributeListImpl(ArrayRef Sets) : NumAttrSets(Sets.size()) { assert(!Sets.empty() && "pointless AttributeListImpl"); @@ -961,7 +955,7 @@ // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs // summary bitsets. - for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)]) + for (const auto &I : Sets[AttributeList::FunctionIndex]) if (!I.isStringAttribute()) AvailableFunctionAttrs.addAttribute(I.getKindAsEnum()); @@ -987,9 +981,10 @@ return false; if (Index) { - for (unsigned I = 0, E = NumAttrSets; I != E; ++I) { + for (unsigned I = AttributeList::ReturnIndex, E = NumAttrSets; I != E; + ++I) { if (begin()[I].hasAttribute(Kind)) { - *Index = I - 1; + *Index = I; break; } } @@ -1098,9 +1093,9 @@ if (MaxIndex == FunctionIndex && Attrs.size() > 1) MaxIndex = Attrs[Attrs.size() - 2].first; - SmallVector AttrVec(attrIdxToArrayIdx(MaxIndex) + 1); + SmallVector AttrVec(MaxIndex + 1); for (const auto &Pair : Attrs) - AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second; + AttrVec[Pair.first] = Pair.second; return getImpl(C, AttrVec); } @@ -1150,7 +1145,6 @@ const AttrBuilder &B) { if (!B.hasAttributes()) return {}; - Index = attrIdxToArrayIdx(Index); SmallVector AttrSets(Index + 1); AttrSets[Index] = AttributeSet::get(C, B); return getImpl(C, AttrSets); @@ -1202,7 +1196,7 @@ for (unsigned I = 0; I < MaxSize; ++I) { AttrBuilder CurBuilder; for (const auto &List : Attrs) - CurBuilder.merge(List.getAttributes(I - 1)); + CurBuilder.merge(List.getAttributes(I)); NewAttrSets[I] = AttributeSet::get(C, CurBuilder); } @@ -1239,7 +1233,6 @@ AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C, unsigned Index, AttributeSet Attrs) const { - Index = attrIdxToArrayIdx(Index); SmallVector AttrSets(this->begin(), this->end()); if (Index >= AttrSets.size()) AttrSets.resize(Index + 1); @@ -1276,12 +1269,12 @@ assert(llvm::is_sorted(ArgNos)); SmallVector AttrSets(this->begin(), this->end()); - unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex); + unsigned MaxIndex = ArgNos.back() + FirstArgIndex; if (MaxIndex >= AttrSets.size()) AttrSets.resize(MaxIndex + 1); for (unsigned ArgNo : ArgNos) { - unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex); + unsigned Index = ArgNo + FirstArgIndex; AttrBuilder B(AttrSets[Index]); B.addAttribute(A); AttrSets[Index] = AttributeSet::get(C, B); @@ -1296,7 +1289,6 @@ if (!hasAttributeAtIndex(Index, Kind)) return *this; - Index = attrIdxToArrayIdx(Index); SmallVector AttrSets(this->begin(), this->end()); assert(Index < AttrSets.size()); @@ -1311,7 +1303,6 @@ if (!hasAttributeAtIndex(Index, Kind)) return *this; - Index = attrIdxToArrayIdx(Index); SmallVector AttrSets(this->begin(), this->end()); assert(Index < AttrSets.size()); @@ -1336,7 +1327,6 @@ unsigned WithoutIndex) const { if (!pImpl) return {}; - WithoutIndex = attrIdxToArrayIdx(WithoutIndex); if (WithoutIndex >= getNumAttrSets()) return *this; SmallVector AttrSets(this->begin(), this->end()); @@ -1494,7 +1484,6 @@ } AttributeSet AttributeList::getAttributes(unsigned Index) const { - Index = attrIdxToArrayIdx(Index); if (!pImpl || Index >= getNumAttrSets()) return {}; return pImpl->begin()[Index]; diff --git a/llvm/lib/IR/Core.cpp b/llvm/lib/IR/Core.cpp --- a/llvm/lib/IR/Core.cpp +++ b/llvm/lib/IR/Core.cpp @@ -2458,19 +2458,30 @@ F->clearGC(); } +// Attributes indexes within LLVM were changed to be less confusing. However, +// to avoid making changes to the C API, we keep the indexes exposed to the C +// API the same. +static unsigned +convertCAttributeIndexToAttributeListIndex(LLVMAttributeIndex Idx) { + return Idx + 1; +} + void LLVMAddAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef A) { - unwrap(F)->addAttributeAtIndex(Idx, unwrap(A)); + unwrap(F)->addAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), unwrap(A)); } unsigned LLVMGetAttributeCountAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx) { - auto AS = unwrap(F)->getAttributes().getAttributes(Idx); + auto AS = unwrap(F)->getAttributes().getAttributes( + convertCAttributeIndexToAttributeListIndex(Idx)); return AS.getNumAttributes(); } void LLVMGetAttributesAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs) { - auto AS = unwrap(F)->getAttributes().getAttributes(Idx); + auto AS = unwrap(F)->getAttributes().getAttributes( + convertCAttributeIndexToAttributeListIndex(Idx)); for (auto A : AS) *Attrs++ = wrap(A); } @@ -2479,24 +2490,28 @@ LLVMAttributeIndex Idx, unsigned KindID) { return wrap(unwrap(F)->getAttributeAtIndex( - Idx, (Attribute::AttrKind)KindID)); + convertCAttributeIndexToAttributeListIndex(Idx), + (Attribute::AttrKind)KindID)); } LLVMAttributeRef LLVMGetStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { - return wrap( - unwrap(F)->getAttributeAtIndex(Idx, StringRef(K, KLen))); + return wrap(unwrap(F)->getAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), StringRef(K, KLen))); } void LLVMRemoveEnumAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, unsigned KindID) { - unwrap(F)->removeAttributeAtIndex(Idx, (Attribute::AttrKind)KindID); + unwrap(F)->removeAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), + (Attribute::AttrKind)KindID); } void LLVMRemoveStringAttributeAtIndex(LLVMValueRef F, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { - unwrap(F)->removeAttributeAtIndex(Idx, StringRef(K, KLen)); + unwrap(F)->removeAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), StringRef(K, KLen)); } void LLVMAddTargetDependentFunctionAttr(LLVMValueRef Fn, const char *A, @@ -2863,25 +2878,29 @@ auto *Call = unwrap(Instr); Attribute AlignAttr = Attribute::getWithAlignment(Call->getContext(), Align(align)); - Call->addAttributeAtIndex(Idx, AlignAttr); + Call->addAttributeAtIndex(convertCAttributeIndexToAttributeListIndex(Idx), + AlignAttr); } void LLVMAddCallSiteAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef A) { - unwrap(C)->addAttributeAtIndex(Idx, unwrap(A)); + unwrap(C)->addAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), unwrap(A)); } unsigned LLVMGetCallSiteAttributeCount(LLVMValueRef C, LLVMAttributeIndex Idx) { auto *Call = unwrap(C); - auto AS = Call->getAttributes().getAttributes(Idx); + auto AS = Call->getAttributes().getAttributes( + convertCAttributeIndexToAttributeListIndex(Idx)); return AS.getNumAttributes(); } void LLVMGetCallSiteAttributes(LLVMValueRef C, LLVMAttributeIndex Idx, LLVMAttributeRef *Attrs) { auto *Call = unwrap(C); - auto AS = Call->getAttributes().getAttributes(Idx); + auto AS = Call->getAttributes().getAttributes( + convertCAttributeIndexToAttributeListIndex(Idx)); for (auto A : AS) *Attrs++ = wrap(A); } @@ -2890,24 +2909,28 @@ LLVMAttributeIndex Idx, unsigned KindID) { return wrap(unwrap(C)->getAttributeAtIndex( - Idx, (Attribute::AttrKind)KindID)); + convertCAttributeIndexToAttributeListIndex(Idx), + (Attribute::AttrKind)KindID)); } LLVMAttributeRef LLVMGetCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { - return wrap( - unwrap(C)->getAttributeAtIndex(Idx, StringRef(K, KLen))); + return wrap(unwrap(C)->getAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), StringRef(K, KLen))); } void LLVMRemoveCallSiteEnumAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, unsigned KindID) { - unwrap(C)->removeAttributeAtIndex(Idx, (Attribute::AttrKind)KindID); + unwrap(C)->removeAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), + (Attribute::AttrKind)KindID); } void LLVMRemoveCallSiteStringAttribute(LLVMValueRef C, LLVMAttributeIndex Idx, const char *K, unsigned KLen) { - unwrap(C)->removeAttributeAtIndex(Idx, StringRef(K, KLen)); + unwrap(C)->removeAttributeAtIndex( + convertCAttributeIndexToAttributeListIndex(Idx), StringRef(K, KLen)); } LLVMValueRef LLVMGetCalledValue(LLVMValueRef Instr) { diff --git a/llvm/unittests/IR/AttributesTest.cpp b/llvm/unittests/IR/AttributesTest.cpp --- a/llvm/unittests/IR/AttributesTest.cpp +++ b/llvm/unittests/IR/AttributesTest.cpp @@ -50,8 +50,9 @@ EXPECT_TRUE(ByVal < Align4); EXPECT_FALSE(ByVal < ByVal); - AttributeList ASs[] = {AttributeList::get(C, 2, Attribute::ZExt), - AttributeList::get(C, 1, Attribute::SExt)}; + AttributeList ASs[] = { + AttributeList::get(C, AttributeList::FirstArgIndex + 1, Attribute::ZExt), + AttributeList::get(C, AttributeList::FirstArgIndex, Attribute::SExt)}; AttributeList SetA = AttributeList::get(C, ASs); AttributeList SetB = @@ -169,8 +170,9 @@ TEST(Attributes, OverflowGet) { LLVMContext C; - std::pair Attrs[] = { { AttributeList::ReturnIndex, Attribute::get(C, Attribute::SExt) }, - { AttributeList::FunctionIndex, Attribute::get(C, Attribute::ReadOnly) } }; + std::pair Attrs[] = { + {AttributeList::FunctionIndex, Attribute::get(C, Attribute::ReadOnly)}, + {AttributeList::ReturnIndex, Attribute::get(C, Attribute::SExt)}}; AttributeList AL = AttributeList::get(C, Attrs); EXPECT_EQ(2U, AL.getNumAttrSets()); } diff --git a/llvm/utils/TableGen/CodeGenTarget.cpp b/llvm/utils/TableGen/CodeGenTarget.cpp --- a/llvm/utils/TableGen/CodeGenTarget.cpp +++ b/llvm/utils/TableGen/CodeGenTarget.cpp @@ -920,7 +920,7 @@ bool CodeGenIntrinsic::isParamImmArg(unsigned ParamIdx) const { // Convert argument index to attribute index starting from `FirstArgIndex`. - ArgAttribute Val{ParamIdx + 1, ImmArg, 0}; + ArgAttribute Val{ParamIdx + 2, ImmArg, 0}; return std::binary_search(ArgumentAttributes.begin(), ArgumentAttributes.end(), Val); }