X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FAttributes.cpp;h=9d9d948527cf0a47fa41d9d4eed7b603485d5472;hb=ce30a8106d7d33af9c18518c11e808eaeebc2cce;hp=629679c6831d039aeca09a138145bb1f95f240fd;hpb=94328f4ff3d450104f15c9dae437cea80417233d;p=oota-llvm.git diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 629679c6831..9d9d948527c 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -43,9 +43,10 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, if (!PA) { // If we didn't find any existing attributes of the same shape then create a // new one and insert it. - PA = !Val ? - new AttributeImpl(Context, Kind) : - new AttributeImpl(Context, Kind, Val); + if (!Val) + PA = new EnumAttributeImpl(Kind); + else + PA = new AlignAttributeImpl(Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -65,7 +66,7 @@ Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) { if (!PA) { // If we didn't find any existing attributes of the same shape then create a // new one and insert it. - PA = new AttributeImpl(Context, Kind, Val); + PA = new StringAttributeImpl(Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -103,24 +104,28 @@ bool Attribute::isStringAttribute() const { } Attribute::AttrKind Attribute::getKindAsEnum() const { + if (!pImpl) return None; assert((isEnumAttribute() || isAlignAttribute()) && "Invalid attribute type to get the kind as an enum!"); return pImpl ? pImpl->getKindAsEnum() : None; } uint64_t Attribute::getValueAsInt() const { + if (!pImpl) return 0; assert(isAlignAttribute() && "Expected the attribute to be an alignment attribute!"); return pImpl ? pImpl->getValueAsInt() : 0; } StringRef Attribute::getKindAsString() const { + if (!pImpl) return StringRef(); assert(isStringAttribute() && "Invalid attribute type to get the kind as a string!"); return pImpl ? pImpl->getKindAsString() : StringRef(); } StringRef Attribute::getValueAsString() const { + if (!pImpl) return StringRef(); assert(isStringAttribute() && "Invalid attribute type to get the value as a string!"); return pImpl ? pImpl->getValueAsString() : StringRef(); @@ -153,12 +158,16 @@ unsigned Attribute::getStackAlignment() const { std::string Attribute::getAsString(bool InAttrGrp) const { if (!pImpl) return ""; - if (hasAttribute(Attribute::AddressSafety)) - return "address_safety"; + if (hasAttribute(Attribute::SanitizeAddress)) + return "sanitize_address"; if (hasAttribute(Attribute::AlwaysInline)) return "alwaysinline"; + if (hasAttribute(Attribute::Builtin)) + return "builtin"; if (hasAttribute(Attribute::ByVal)) return "byval"; + if (hasAttribute(Attribute::InAlloca)) + return "inalloca"; if (hasAttribute(Attribute::InlineHint)) return "inlinehint"; if (hasAttribute(Attribute::InReg)) @@ -171,6 +180,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "nest"; if (hasAttribute(Attribute::NoAlias)) return "noalias"; + if (hasAttribute(Attribute::NoBuiltin)) + return "nobuiltin"; if (hasAttribute(Attribute::NoCapture)) return "nocapture"; if (hasAttribute(Attribute::NoDuplicate)) @@ -187,12 +198,16 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "noreturn"; if (hasAttribute(Attribute::NoUnwind)) return "nounwind"; + if (hasAttribute(Attribute::OptimizeNone)) + return "optnone"; if (hasAttribute(Attribute::OptimizeForSize)) return "optsize"; if (hasAttribute(Attribute::ReadNone)) return "readnone"; if (hasAttribute(Attribute::ReadOnly)) return "readonly"; + if (hasAttribute(Attribute::Returned)) + return "returned"; if (hasAttribute(Attribute::ReturnsTwice)) return "returns_twice"; if (hasAttribute(Attribute::SExt)) @@ -205,14 +220,16 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "sspstrong"; if (hasAttribute(Attribute::StructRet)) return "sret"; - if (hasAttribute(Attribute::ThreadSafety)) - return "thread_safety"; - if (hasAttribute(Attribute::UninitializedChecks)) - return "uninitialized_checks"; + if (hasAttribute(Attribute::SanitizeThread)) + return "sanitize_thread"; + if (hasAttribute(Attribute::SanitizeMemory)) + return "sanitize_memory"; if (hasAttribute(Attribute::UWTable)) return "uwtable"; if (hasAttribute(Attribute::ZExt)) return "zeroext"; + if (hasAttribute(Attribute::Cold)) + return "cold"; // FIXME: These should be output like this: // @@ -271,35 +288,11 @@ bool Attribute::operator<(Attribute A) const { // AttributeImpl Definition //===----------------------------------------------------------------------===// -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind) - : Context(C), Entry(new EnumAttributeEntry(Kind)) {} - -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind, - unsigned Align) - : Context(C) { - assert((Kind == Attribute::Alignment || Kind == Attribute::StackAlignment) && - "Wrong kind for alignment attribute!"); - Entry = new AlignAttributeEntry(Kind, Align); -} - -AttributeImpl::AttributeImpl(LLVMContext &C, StringRef Kind, StringRef Val) - : Context(C), Entry(new StringAttributeEntry(Kind, Val)) {} - -AttributeImpl::~AttributeImpl() { - delete Entry; -} - -bool AttributeImpl::isEnumAttribute() const { - return isa(Entry); -} - -bool AttributeImpl::isAlignAttribute() const { - return isa(Entry); -} - -bool AttributeImpl::isStringAttribute() const { - return isa(Entry); -} +// Pin the vtabels to this file. +AttributeImpl::~AttributeImpl() {} +void EnumAttributeImpl::anchor() {} +void AlignAttributeImpl::anchor() {} +void StringAttributeImpl::anchor() {} bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { if (isStringAttribute()) return false; @@ -312,21 +305,23 @@ bool AttributeImpl::hasAttribute(StringRef Kind) const { } Attribute::AttrKind AttributeImpl::getKindAsEnum() const { - if (EnumAttributeEntry *E = dyn_cast(Entry)) - return E->getEnumKind(); - return cast(Entry)->getEnumKind(); + assert(isEnumAttribute() || isAlignAttribute()); + return static_cast(this)->getEnumKind(); } uint64_t AttributeImpl::getValueAsInt() const { - return cast(Entry)->getAlignment(); + assert(isAlignAttribute()); + return static_cast(this)->getAlignment(); } StringRef AttributeImpl::getKindAsString() const { - return cast(Entry)->getStringKind(); + assert(isStringAttribute()); + return static_cast(this)->getStringKind(); } StringRef AttributeImpl::getValueAsString() const { - return cast(Entry)->getStringValue(); + assert(isStringAttribute()); + return static_cast(this)->getStringValue(); } bool AttributeImpl::operator<(const AttributeImpl &AI) const { @@ -355,8 +350,6 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { // FIXME: Remove this. switch (Val) { case Attribute::EndAttrKinds: - case Attribute::AttrKindEmptyKey: - case Attribute::AttrKindTombstoneKey: llvm_unreachable("Synthetic enumerators which should never get here"); case Attribute::None: return 0; @@ -386,12 +379,18 @@ uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { case Attribute::ReturnsTwice: return 1 << 29; case Attribute::UWTable: return 1 << 30; case Attribute::NonLazyBind: return 1U << 31; - case Attribute::AddressSafety: return 1ULL << 32; + case Attribute::SanitizeAddress: return 1ULL << 32; case Attribute::MinSize: return 1ULL << 33; case Attribute::NoDuplicate: return 1ULL << 34; case Attribute::StackProtectStrong: return 1ULL << 35; - case Attribute::ThreadSafety: return 1ULL << 36; - case Attribute::UninitializedChecks: return 1ULL << 37; + case Attribute::SanitizeThread: return 1ULL << 36; + case Attribute::SanitizeMemory: return 1ULL << 37; + case Attribute::NoBuiltin: return 1ULL << 38; + case Attribute::Returned: return 1ULL << 39; + case Attribute::Cold: return 1ULL << 40; + case Attribute::Builtin: return 1ULL << 41; + case Attribute::OptimizeNone: return 1ULL << 42; + case Attribute::InAlloca: return 1ULL << 43; } llvm_unreachable("Unsupported attribute type"); } @@ -423,7 +422,10 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, // If we didn't find any existing attributes of the same shape then create a // new one and insert it. if (!PA) { - PA = new AttributeSetNode(SortedAttrs); + // Coallocate entries after the AttributeSetNode itself. + void *Mem = ::operator new(sizeof(AttributeSetNode) + + sizeof(Attribute) * SortedAttrs.size()); + PA = new (Mem) AttributeSetNode(SortedAttrs); pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint); } @@ -432,59 +434,53 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, } bool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const { - for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return true; return false; } bool AttributeSetNode::hasAttribute(StringRef Kind) const { - for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return true; return false; } Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const { - for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return *I; return Attribute(); } Attribute AttributeSetNode::getAttribute(StringRef Kind) const { - for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Kind)) return *I; return Attribute(); } unsigned AttributeSetNode::getAlignment() const { - for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Attribute::Alignment)) return I->getAlignment(); return 0; } unsigned AttributeSetNode::getStackAlignment() const { - for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) + for (iterator I = begin(), E = end(); I != E; ++I) if (I->hasAttribute(Attribute::StackAlignment)) return I->getStackAlignment(); return 0; } std::string AttributeSetNode::getAsString(bool InAttrGrp) const { - std::string Str = ""; - for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ) { + std::string Str; + for (iterator I = begin(), E = end(); I != E; ++I) { + if (I != begin()) + Str += ' '; Str += I->getAsString(InAttrGrp); - if (++I != E) Str += " "; } return Str; } @@ -493,13 +489,13 @@ std::string AttributeSetNode::getAsString(bool InAttrGrp) const { // AttributeSetImpl Definition //===----------------------------------------------------------------------===// -uint64_t AttributeSetImpl::Raw(uint64_t Index) const { +uint64_t AttributeSetImpl::Raw(unsigned Index) const { for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) { if (getSlotIndex(I) != Index) continue; - const AttributeSetNode *ASN = AttrNodes[I].second; + const AttributeSetNode *ASN = getSlotNode(I); uint64_t Mask = 0; - for (AttributeSetNode::const_iterator II = ASN->begin(), + for (AttributeSetNode::iterator II = ASN->begin(), IE = ASN->end(); II != IE; ++II) { Attribute Attr = *II; @@ -522,6 +518,10 @@ uint64_t AttributeSetImpl::Raw(uint64_t Index) const { return 0; } +void AttributeSetImpl::dump() const { + AttributeSet(const_cast(this)).dump(); +} + //===----------------------------------------------------------------------===// // AttributeSet Construction and Mutation Methods //===----------------------------------------------------------------------===// @@ -539,7 +539,11 @@ AttributeSet::getImpl(LLVMContext &C, // If we didn't find any existing attributes of the same shape then // create a new one and insert it. if (!PA) { - PA = new AttributeSetImpl(C, Attrs); + // Coallocate entries after the AttributeSetImpl itself. + void *Mem = ::operator new(sizeof(AttributeSetImpl) + + sizeof(std::pair) * + Attrs.size()); + PA = new (Mem) AttributeSetImpl(C, Attrs); pImpl->AttrsLists.InsertNode(PA, InsertPoint); } @@ -591,60 +595,96 @@ AttributeSet AttributeSet::get(LLVMContext &C, return getImpl(C, Attrs); } -AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { +AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, AttrBuilder &B) { if (!B.hasAttributes()) return AttributeSet(); // Add target-independent attributes. SmallVector, 8> Attrs; - for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) { - Attribute::AttrKind Kind = *I; + for (Attribute::AttrKind Kind = Attribute::None; + Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) { + if (!B.contains(Kind)) + continue; + if (Kind == Attribute::Alignment) - Attrs.push_back(std::make_pair(Idx, Attribute:: + Attrs.push_back(std::make_pair(Index, Attribute:: getWithAlignment(C, B.getAlignment()))); else if (Kind == Attribute::StackAlignment) - Attrs.push_back(std::make_pair(Idx, Attribute:: + Attrs.push_back(std::make_pair(Index, Attribute:: getWithStackAlignment(C, B.getStackAlignment()))); else - Attrs.push_back(std::make_pair(Idx, Attribute::get(C, Kind))); + Attrs.push_back(std::make_pair(Index, Attribute::get(C, Kind))); } // Add target-dependent (string) attributes. for (AttrBuilder::td_iterator I = B.td_begin(), E = B.td_end(); I != E; ++I) - Attrs.push_back(std::make_pair(Idx, Attribute::get(C, I->first,I->second))); + Attrs.push_back(std::make_pair(Index, Attribute::get(C, I->first,I->second))); return get(C, Attrs); } -AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, +AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index, ArrayRef Kind) { SmallVector, 8> Attrs; for (ArrayRef::iterator I = Kind.begin(), E = Kind.end(); I != E; ++I) - Attrs.push_back(std::make_pair(Idx, Attribute::get(C, *I))); + Attrs.push_back(std::make_pair(Index, Attribute::get(C, *I))); return get(C, Attrs); } AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef Attrs) { if (Attrs.empty()) return AttributeSet(); + if (Attrs.size() == 1) return Attrs[0]; SmallVector, 8> AttrNodeVec; - for (unsigned I = 0, E = Attrs.size(); I != E; ++I) { - AttributeSet AS = Attrs[I]; - if (!AS.pImpl) continue; - AttrNodeVec.append(AS.pImpl->AttrNodes.begin(), AS.pImpl->AttrNodes.end()); + AttributeSetImpl *A0 = Attrs[0].pImpl; + if (A0) + AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumAttributes())); + // 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) { + AttributeSetImpl *AS = Attrs[I].pImpl; + if (!AS) continue; + SmallVector, 8>::iterator + ANVI = AttrNodeVec.begin(), ANVE; + for (const AttributeSetImpl::IndexAttrPair + *AI = AS->getNode(0), + *AE = AS->getNode(AS->getNumAttributes()); + AI != AE; ++AI) { + ANVE = AttrNodeVec.end(); + while (ANVI != ANVE && ANVI->first <= AI->first) + ++ANVI; + ANVI = AttrNodeVec.insert(ANVI, *AI) + 1; + } } return getImpl(C, AttrNodeVec); } -AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Idx, +AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Attr) const { - return addAttributes(C, Idx, AttributeSet::get(C, Idx, Attr)); + if (hasAttribute(Index, Attr)) return *this; + return addAttributes(C, Index, AttributeSet::get(C, Index, Attr)); +} + +AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, + StringRef Kind) const { + llvm::AttrBuilder B; + B.addAttribute(Kind); + return addAttributes(C, Index, AttributeSet::get(C, Index, B)); +} + +AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index, + StringRef Kind, StringRef Value) const { + llvm::AttrBuilder B; + B.addAttribute(Kind, Value); + return addAttributes(C, Index, AttributeSet::get(C, Index, B)); } -AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, +AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const { if (!pImpl) return Attrs; if (!Attrs.pImpl) return *this; @@ -652,8 +692,8 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, #ifndef NDEBUG // FIXME it is not obvious how this should work for alignment. For now, say // we can't change a known alignment. - unsigned OldAlign = getParamAlignment(Idx); - unsigned NewAlign = Attrs.getParamAlignment(Idx); + unsigned OldAlign = getParamAlignment(Index); + unsigned NewAlign = Attrs.getParamAlignment(Index); assert((!OldAlign || !NewAlign || OldAlign == NewAlign) && "Attempt to change alignment!"); #endif @@ -664,8 +704,8 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, AttributeSet AS; uint64_t LastIndex = 0; for (unsigned I = 0, E = NumAttrs; I != E; ++I) { - if (getSlotIndex(I) >= Idx) { - if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++); + if (getSlotIndex(I) >= Index) { + if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++); break; } LastIndex = I + 1; @@ -674,17 +714,17 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, // Now add the attribute into the correct slot. There may already be an // AttributeSet there. - AttrBuilder B(AS, Idx); + AttrBuilder B(AS, Index); for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) - if (Attrs.getSlotIndex(I) == Idx) { - for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I), + if (Attrs.getSlotIndex(I) == Index) { + for (AttributeSetImpl::iterator II = Attrs.pImpl->begin(I), IE = Attrs.pImpl->end(I); II != IE; ++II) B.addAttribute(*II); break; } - AttrSet.push_back(AttributeSet::get(C, Idx, B)); + AttrSet.push_back(AttributeSet::get(C, Index, B)); // Add the remaining attribute slots. for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) @@ -693,12 +733,13 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, return get(C, AttrSet); } -AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Idx, +AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Attr) const { - return removeAttributes(C, Idx, AttributeSet::get(C, Idx, Attr)); + if (!hasAttribute(Index, Attr)) return *this; + return removeAttributes(C, Index, AttributeSet::get(C, Index, Attr)); } -AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, +AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const { if (!pImpl) return AttributeSet(); if (!Attrs.pImpl) return *this; @@ -706,7 +747,7 @@ AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, #ifndef NDEBUG // 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.hasAttribute(Idx, Attribute::Alignment) && + assert(!Attrs.hasAttribute(Index, Attribute::Alignment) && "Attempt to change alignment!"); #endif @@ -716,8 +757,8 @@ AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, AttributeSet AS; uint64_t LastIndex = 0; for (unsigned I = 0, E = NumAttrs; I != E; ++I) { - if (getSlotIndex(I) >= Idx) { - if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++); + if (getSlotIndex(I) >= Index) { + if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++); break; } LastIndex = I + 1; @@ -726,15 +767,15 @@ AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, // Now remove the attribute from the correct slot. There may already be an // AttributeSet there. - AttrBuilder B(AS, Idx); + AttrBuilder B(AS, Index); for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I) - if (Attrs.getSlotIndex(I) == Idx) { - B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Idx); + if (Attrs.getSlotIndex(I) == Index) { + B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Index); break; } - AttrSet.push_back(AttributeSet::get(C, Idx, B)); + AttrSet.push_back(AttributeSet::get(C, Index, B)); // Add the remaining attribute slots. for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I) @@ -751,11 +792,11 @@ LLVMContext &AttributeSet::getContext() const { return pImpl->getContext(); } -AttributeSet AttributeSet::getParamAttributes(unsigned Idx) const { - return pImpl && hasAttributes(Idx) ? +AttributeSet AttributeSet::getParamAttributes(unsigned Index) const { + return pImpl && hasAttributes(Index) ? AttributeSet::get(pImpl->getContext(), ArrayRef >( - std::make_pair(Idx, getAttributes(Idx)))) : + std::make_pair(Index, getAttributes(Index)))) : AttributeSet(); } @@ -798,7 +839,7 @@ bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { if (pImpl == 0) return false; for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) - for (AttributeSetImpl::const_iterator II = pImpl->begin(I), + for (AttributeSetImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I); II != IE; ++II) if (II->hasAttribute(Attr)) return true; @@ -835,27 +876,27 @@ std::string AttributeSet::getAsString(unsigned Index, } /// \brief The attributes for the specified index are returned. -AttributeSetNode *AttributeSet::getAttributes(unsigned Idx) const { +AttributeSetNode *AttributeSet::getAttributes(unsigned Index) const { if (!pImpl) return 0; // Loop through to find the attribute node we want. for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) - if (pImpl->getSlotIndex(I) == Idx) + if (pImpl->getSlotIndex(I) == Index) return pImpl->getSlotNode(I); return 0; } -AttributeSet::iterator AttributeSet::begin(unsigned Idx) const { +AttributeSet::iterator AttributeSet::begin(unsigned Slot) const { if (!pImpl) return ArrayRef().begin(); - return pImpl->begin(Idx); + return pImpl->begin(Slot); } -AttributeSet::iterator AttributeSet::end(unsigned Idx) const { +AttributeSet::iterator AttributeSet::end(unsigned Slot) const { if (!pImpl) return ArrayRef().end(); - return pImpl->end(Idx); + return pImpl->end(Slot); } //===----------------------------------------------------------------------===// @@ -869,7 +910,7 @@ unsigned AttributeSet::getNumSlots() const { return pImpl ? pImpl->getNumAttributes() : 0; } -uint64_t AttributeSet::getSlotIndex(unsigned Slot) const { +unsigned AttributeSet::getSlotIndex(unsigned Slot) const { assert(pImpl && Slot < pImpl->getNumAttributes() && "Slot # out of range!"); return pImpl->getSlotIndex(Slot); @@ -906,15 +947,15 @@ void AttributeSet::dump() const { // AttrBuilder Method Implementations //===----------------------------------------------------------------------===// -AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) - : Alignment(0), StackAlignment(0) { +AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Index) + : Attrs(0), Alignment(0), StackAlignment(0) { AttributeSetImpl *pImpl = AS.pImpl; if (!pImpl) return; for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { - if (pImpl->getSlotIndex(I) != Idx) continue; + if (pImpl->getSlotIndex(I) != Index) continue; - for (AttributeSetImpl::const_iterator II = pImpl->begin(I), + for (AttributeSetImpl::iterator II = pImpl->begin(I), IE = pImpl->end(I); II != IE; ++II) addAttribute(*II); @@ -923,14 +964,15 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) } void AttrBuilder::clear() { - Attrs.clear(); + Attrs.reset(); Alignment = StackAlignment = 0; } AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { + assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && "Adding alignment attribute without adding alignment value!"); - Attrs.insert(Val); + Attrs[Val] = true; return *this; } @@ -941,7 +983,7 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { } Attribute::AttrKind Kind = Attr.getKindAsEnum(); - Attrs.insert(Kind); + Attrs[Kind] = true; if (Kind == Attribute::Alignment) Alignment = Attr.getAlignment(); @@ -956,7 +998,8 @@ AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) { } AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { - Attrs.erase(Val); + assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!"); + Attrs[Val] = false; if (Val == Attribute::Alignment) Alignment = 0; @@ -967,20 +1010,20 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { } AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { - unsigned Idx = ~0U; + unsigned Slot = ~0U; for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I) if (A.getSlotIndex(I) == Index) { - Idx = I; + Slot = I; break; } - assert(Idx != ~0U && "Couldn't find index in AttributeSet!"); + assert(Slot != ~0U && "Couldn't find index in AttributeSet!"); - for (AttributeSet::iterator I = A.begin(Idx), E = A.end(Idx); I != E; ++I) { + for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) { Attribute Attr = *I; if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { Attribute::AttrKind Kind = I->getKindAsEnum(); - Attrs.erase(Kind); + Attrs[Kind] = false; if (Kind == Attribute::Alignment) Alignment = 0; @@ -1011,7 +1054,7 @@ AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); assert(Align <= 0x40000000 && "Alignment too large."); - Attrs.insert(Attribute::Alignment); + Attrs[Attribute::Alignment] = true; Alignment = Align; return *this; } @@ -1023,7 +1066,7 @@ AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); assert(Align <= 0x100 && "Alignment too large."); - Attrs.insert(Attribute::StackAlignment); + Attrs[Attribute::StackAlignment] = true; StackAlignment = Align; return *this; } @@ -1036,7 +1079,7 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { if (!StackAlignment) StackAlignment = B.StackAlignment; - Attrs.insert(B.Attrs.begin(), B.Attrs.end()); + Attrs |= B.Attrs; for (td_const_iterator I = B.TargetDepAttrs.begin(), E = B.TargetDepAttrs.end(); I != E; ++I) @@ -1045,33 +1088,29 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { return *this; } -bool AttrBuilder::contains(Attribute::AttrKind A) const { - return Attrs.count(A); -} - bool AttrBuilder::contains(StringRef A) const { return TargetDepAttrs.find(A) != TargetDepAttrs.end(); } bool AttrBuilder::hasAttributes() const { - return !Attrs.empty() || !TargetDepAttrs.empty(); + return !Attrs.none() || !TargetDepAttrs.empty(); } bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { - unsigned Idx = ~0U; + unsigned Slot = ~0U; for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I) if (A.getSlotIndex(I) == Index) { - Idx = I; + Slot = I; break; } - assert(Idx != ~0U && "Couldn't find the index!"); + assert(Slot != ~0U && "Couldn't find the index!"); - for (AttributeSet::iterator I = A.begin(Idx), E = A.end(Idx); + for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) { Attribute Attr = *I; if (Attr.isEnumAttribute() || Attr.isAlignAttribute()) { - if (Attrs.count(I->getKindAsEnum())) + if (Attrs[I->getKindAsEnum()]) return true; } else { assert(Attr.isStringAttribute() && "Invalid attribute kind!"); @@ -1087,10 +1126,8 @@ bool AttrBuilder::hasAlignmentAttr() const { } bool AttrBuilder::operator==(const AttrBuilder &B) { - for (DenseSet::iterator I = Attrs.begin(), - E = Attrs.end(); I != E; ++I) - if (!B.Attrs.count(*I)) - return false; + if (Attrs != B.Attrs) + return false; for (td_const_iterator I = TargetDepAttrs.begin(), E = TargetDepAttrs.end(); I != E; ++I) @@ -1107,7 +1144,7 @@ AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; I = Attribute::AttrKind(I + 1)) { if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { - Attrs.insert(I); + Attrs[I] = true; if (I == Attribute::Alignment) Alignment = 1ULL << ((A >> 16) - 1); @@ -1138,7 +1175,10 @@ AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) { .addAttribute(Attribute::Nest) .addAttribute(Attribute::NoAlias) .addAttribute(Attribute::NoCapture) - .addAttribute(Attribute::StructRet); + .addAttribute(Attribute::ReadNone) + .addAttribute(Attribute::ReadOnly) + .addAttribute(Attribute::StructRet) + .addAttribute(Attribute::InAlloca); return AttributeSet::get(Ty->getContext(), Index, Incompatible); }