X-Git-Url: http://plrg.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FAttributes.cpp;h=909f22f15221f63d59924edf50e1c2d0a86429a4;hb=f9271ea159b97e2febedcf095c3c4122cb24d077;hp=2cf76213e07e137e835cdb9ea180d986957aa8a6;hpb=3ba51cefb75364a17e3a23c54c216035c33e67a6;p=oota-llvm.git diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 2cf76213e07..909f22f1522 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -30,21 +30,11 @@ using namespace llvm; // Attribute Construction Methods //===----------------------------------------------------------------------===// -Attribute Attribute::get(LLVMContext &Context, AttrKind Kind) { - AttrBuilder B; - return Attribute::get(Context, B.addAttribute(Kind)); -} - -Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { - // If there are no attributes, return an empty Attribute class. - if (!B.hasAttributes()) - return Attribute(); - - // Otherwise, build a key to look up the existing attributes. +Attribute Attribute::get(LLVMContext &Context, Constant *Kind, Constant *Val) { LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; - ConstantInt *CI = ConstantInt::get(Type::getInt64Ty(Context), B.Raw()); - ID.AddPointer(CI); + ID.AddPointer(Kind); + if (Val) ID.AddPointer(Val); void *InsertPoint; AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); @@ -52,7 +42,7 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { 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, CI); + PA = new AttributeImpl(Context, Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -60,15 +50,24 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { return Attribute(PA); } +Attribute Attribute::get(LLVMContext &Context, AttrKind Kind, Constant *Val) { + ConstantInt *KindVal = ConstantInt::get(Type::getInt64Ty(Context), Kind); + return get(Context, KindVal, Val); +} + Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) { - AttrBuilder B; - return get(Context, B.addAlignmentAttr(Align)); + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); + assert(Align <= 0x40000000 && "Alignment too large."); + return get(Context, Alignment, + ConstantInt::get(Type::getInt64Ty(Context), Align)); } Attribute Attribute::getWithStackAlignment(LLVMContext &Context, uint64_t Align) { - AttrBuilder B; - return get(Context, B.addStackAlignmentAttr(Align)); + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); + assert(Align <= 0x100 && "Alignment too large."); + return get(Context, StackAlignment, + ConstantInt::get(Type::getInt64Ty(Context), Align)); } //===----------------------------------------------------------------------===// @@ -79,80 +78,94 @@ bool Attribute::hasAttribute(AttrKind Val) const { return pImpl && pImpl->hasAttribute(Val); } -bool Attribute::hasAttributes() const { - return pImpl && pImpl->hasAttributes(); +Constant *Attribute::getAttributeKind() const { + return pImpl ? pImpl->getAttributeKind() : 0; +} + +Constant *Attribute::getAttributeValues() const { + return pImpl ? pImpl->getAttributeValues() : 0; } /// This returns the alignment field of an attribute as a byte alignment value. unsigned Attribute::getAlignment() const { - if (!hasAttribute(Attribute::Alignment)) - return 0; + assert(hasAttribute(Attribute::Alignment) && + "Trying to get alignment from non-alignment attribute!"); return pImpl->getAlignment(); } /// This returns the stack alignment field of an attribute as a byte alignment /// value. unsigned Attribute::getStackAlignment() const { - if (!hasAttribute(Attribute::StackAlignment)) - return 0; + assert(hasAttribute(Attribute::StackAlignment) && + "Trying to get alignment from non-alignment attribute!"); return pImpl->getStackAlignment(); } std::string Attribute::getAsString() const { - if (hasAttribute(Attribute::ZExt)) - return "zeroext"; - if (hasAttribute(Attribute::SExt)) - return "signext"; - if (hasAttribute(Attribute::NoReturn)) - return "noreturn"; - if (hasAttribute(Attribute::NoUnwind)) - return "nounwind"; - if (hasAttribute(Attribute::UWTable)) - return "uwtable"; - if (hasAttribute(Attribute::ReturnsTwice)) - return "returns_twice"; + if (!pImpl) return ""; + + if (hasAttribute(Attribute::AddressSafety)) + return "address_safety"; + if (hasAttribute(Attribute::AlwaysInline)) + return "alwaysinline"; + if (hasAttribute(Attribute::ByVal)) + return "byval"; + if (hasAttribute(Attribute::InlineHint)) + return "inlinehint"; if (hasAttribute(Attribute::InReg)) return "inreg"; + if (hasAttribute(Attribute::MinSize)) + return "minsize"; + if (hasAttribute(Attribute::Naked)) + return "naked"; + if (hasAttribute(Attribute::Nest)) + return "nest"; if (hasAttribute(Attribute::NoAlias)) return "noalias"; if (hasAttribute(Attribute::NoCapture)) return "nocapture"; - if (hasAttribute(Attribute::StructRet)) - return "sret"; - if (hasAttribute(Attribute::ByVal)) - return "byval"; - if (hasAttribute(Attribute::Nest)) - return "nest"; + if (hasAttribute(Attribute::NoDuplicate)) + return "noduplicate"; + if (hasAttribute(Attribute::NoImplicitFloat)) + return "noimplicitfloat"; + if (hasAttribute(Attribute::NoInline)) + return "noinline"; + if (hasAttribute(Attribute::NonLazyBind)) + return "nonlazybind"; + if (hasAttribute(Attribute::NoRedZone)) + return "noredzone"; + if (hasAttribute(Attribute::NoReturn)) + return "noreturn"; + if (hasAttribute(Attribute::NoUnwind)) + return "nounwind"; + if (hasAttribute(Attribute::OptimizeForSize)) + return "optsize"; if (hasAttribute(Attribute::ReadNone)) return "readnone"; if (hasAttribute(Attribute::ReadOnly)) return "readonly"; - if (hasAttribute(Attribute::OptimizeForSize)) - return "optsize"; - if (hasAttribute(Attribute::NoInline)) - return "noinline"; - if (hasAttribute(Attribute::InlineHint)) - return "inlinehint"; - if (hasAttribute(Attribute::AlwaysInline)) - return "alwaysinline"; + if (hasAttribute(Attribute::ReturnsTwice)) + return "returns_twice"; + if (hasAttribute(Attribute::SExt)) + return "signext"; if (hasAttribute(Attribute::StackProtect)) return "ssp"; if (hasAttribute(Attribute::StackProtectReq)) return "sspreq"; if (hasAttribute(Attribute::StackProtectStrong)) return "sspstrong"; - if (hasAttribute(Attribute::NoRedZone)) - return "noredzone"; - if (hasAttribute(Attribute::NoImplicitFloat)) - return "noimplicitfloat"; - if (hasAttribute(Attribute::Naked)) - return "naked"; - if (hasAttribute(Attribute::NonLazyBind)) - return "nonlazybind"; - if (hasAttribute(Attribute::AddressSafety)) - return "address_safety"; - if (hasAttribute(Attribute::MinSize)) - return "minsize"; + if (hasAttribute(Attribute::StructRet)) + return "sret"; + if (hasAttribute(Attribute::UWTable)) + return "uwtable"; + if (hasAttribute(Attribute::ZExt)) + return "zeroext"; + + // FIXME: These should be output like this: + // + // align=4 + // alignstack=8 + // if (hasAttribute(Attribute::StackAlignment)) { std::string Result; Result += "alignstack("; @@ -164,17 +177,37 @@ std::string Attribute::getAsString() const { std::string Result; Result += "align "; Result += utostr(getAlignment()); - Result += ""; return Result; } - if (hasAttribute(Attribute::NoDuplicate)) - return "noduplicate"; + + // Convert target-dependent attributes to strings of the form: + // + // "kind" + // "kind" = "value" + // "kind" = ( "value1" "value2" "value3" ) + // + if (ConstantDataArray *CDA = + dyn_cast(pImpl->getAttributeKind())) { + std::string Result; + Result += '\"' + CDA->getAsString().str() + '"'; + + Constant *Vals = pImpl->getAttributeValues(); + if (!Vals) return Result; + + // FIXME: This should support more than just ConstantDataArrays. Also, + // support a vector of attribute values. + + Result += " = "; + Result += '\"' + cast(Vals)->getAsString().str() + '"'; + + return Result; + } llvm_unreachable("Unknown attribute"); } bool Attribute::operator==(AttrKind K) const { - return pImpl && *pImpl == K; + return (pImpl && *pImpl == K) || (!pImpl && K == None); } bool Attribute::operator!=(AttrKind K) const { return !(*this == K); @@ -187,78 +220,61 @@ bool Attribute::operator<(Attribute A) const { return *pImpl < *A.pImpl; } -uint64_t Attribute::Raw() const { - return pImpl ? pImpl->Raw() : 0; -} - //===----------------------------------------------------------------------===// // AttributeImpl Definition //===----------------------------------------------------------------------===// -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) - : Context(C) { - Data = ConstantInt::get(Type::getInt64Ty(C), data); -} -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data, - ArrayRef values) - : Context(C) { - Data = ConstantInt::get(Type::getInt64Ty(C), data); - Vals.reserve(values.size()); - Vals.append(values.begin(), values.end()); -} -AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) - : Context(C) { - Data = ConstantDataArray::getString(C, data); -} - bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { - return (Raw() & getAttrMask(A)) != 0; -} - -bool AttributeImpl::hasAttributes() const { - return Raw() != 0; + if (ConstantInt *CI = dyn_cast(Kind)) + return CI->getZExtValue() == A; + return false; } uint64_t AttributeImpl::getAlignment() const { - uint64_t Mask = Raw() & getAttrMask(Attribute::Alignment); - return 1ULL << ((Mask >> 16) - 1); + assert(hasAttribute(Attribute::Alignment) && + "Trying to retrieve the alignment from a non-alignment attr!"); + return cast(Values)->getZExtValue(); } uint64_t AttributeImpl::getStackAlignment() const { - uint64_t Mask = Raw() & getAttrMask(Attribute::StackAlignment); - return 1ULL << ((Mask >> 26) - 1); + assert(hasAttribute(Attribute::StackAlignment) && + "Trying to retrieve the stack alignment from a non-alignment attr!"); + return cast(Values)->getZExtValue(); } -bool AttributeImpl::operator==(Attribute::AttrKind Kind) const { - if (ConstantInt *CI = dyn_cast(Data)) - return CI->getZExtValue() == Kind; +bool AttributeImpl::operator==(Attribute::AttrKind kind) const { + if (ConstantInt *CI = dyn_cast(Kind)) + return CI->getZExtValue() == kind; return false; } -bool AttributeImpl::operator!=(Attribute::AttrKind Kind) const { - return !(*this == Kind); +bool AttributeImpl::operator!=(Attribute::AttrKind kind) const { + return !(*this == kind); } -bool AttributeImpl::operator==(StringRef Kind) const { - if (ConstantDataArray *CDA = dyn_cast(Data)) +bool AttributeImpl::operator==(StringRef kind) const { + if (ConstantDataArray *CDA = dyn_cast(Kind)) if (CDA->isString()) - return CDA->getAsString() == Kind; + return CDA->getAsString() == kind; return false; } -bool AttributeImpl::operator!=(StringRef Kind) const { - return !(*this == Kind); +bool AttributeImpl::operator!=(StringRef kind) const { + return !(*this == kind); } bool AttributeImpl::operator<(const AttributeImpl &AI) const { - if (!Data && !AI.Data) return false; - if (!Data && AI.Data) return true; - if (Data && !AI.Data) return false; + // This sorts the attributes with Attribute::AttrKinds coming first (sorted + // relative to their enum value) and then strings. - ConstantInt *ThisCI = dyn_cast(Data); - ConstantInt *ThatCI = dyn_cast(AI.Data); + if (!Kind && !AI.Kind) return false; + if (!Kind && AI.Kind) return true; + if (Kind && !AI.Kind) return false; - ConstantDataArray *ThisCDA = dyn_cast(Data); - ConstantDataArray *ThatCDA = dyn_cast(AI.Data); + ConstantInt *ThisCI = dyn_cast(Kind); + ConstantInt *ThatCI = dyn_cast(AI.Kind); + + ConstantDataArray *ThisCDA = dyn_cast(Kind); + ConstantDataArray *ThatCDA = dyn_cast(AI.Kind); if (ThisCI && ThatCI) return ThisCI->getZExtValue() < ThatCI->getZExtValue(); @@ -272,11 +288,6 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const { return ThisCDA->getAsString() < ThatCDA->getAsString(); } -uint64_t AttributeImpl::Raw() const { - // FIXME: Remove this. - return cast(Data)->getZExtValue(); -} - uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { // FIXME: Remove this. switch (Val) { @@ -382,9 +393,9 @@ unsigned AttributeSetNode::getStackAlignment() const { std::string AttributeSetNode::getAsString() const { std::string Str = ""; for (SmallVectorImpl::const_iterator I = AttrList.begin(), - E = AttrList.end(); I != E; ++I) { - if (I != AttrList.begin()) Str += " "; + E = AttrList.end(); I != E; ) { Str += I->getAsString(); + if (++I != E) Str += " "; } return Str; } @@ -397,12 +408,23 @@ uint64_t AttributeSetImpl::Raw(uint64_t Index) const { for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) { if (getSlotIndex(I) != Index) continue; const AttributeSetNode *ASN = AttrNodes[I].second; - AttrBuilder B; + uint64_t Mask = 0; for (AttributeSetNode::const_iterator II = ASN->begin(), - IE = ASN->end(); II != IE; ++II) - B.addAttributes(*II); - return B.Raw(); + IE = ASN->end(); II != IE; ++II) { + Attribute Attr = *II; + ConstantInt *Kind = cast(Attr.getAttributeKind()); + Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue()); + + if (KindVal == Attribute::Alignment) + Mask |= (Log2_32(ASN->getAlignment()) + 1) << 16; + else if (KindVal == Attribute::StackAlignment) + Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26; + else + Mask |= AttributeImpl::getAttrMask(KindVal); + } + + return Mask; } return 0; @@ -443,7 +465,7 @@ AttributeSet AttributeSet::get(LLVMContext &C, for (unsigned i = 0, e = Attrs.size(); i != e; ++i) { assert((!i || Attrs[i-1].first <= Attrs[i].first) && "Misordered Attributes list!"); - assert(Attrs[i].second.hasAttributes() && + assert(Attrs[i].second != Attribute::None && "Pointless attribute!"); } #endif @@ -560,7 +582,7 @@ AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx, if (Attrs.getSlotIndex(I) == Idx) { for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I), IE = Attrs.pImpl->end(I); II != IE; ++II) - B.addAttributes(*II); + B.addAttribute(*II); break; } @@ -604,15 +626,13 @@ AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, AttrSet.push_back(getSlotAttributes(I)); } - // Now add the attribute into the correct slot. There may already be an + // Now remove the attribute from the correct slot. There may already be an // AttributeSet there. AttrBuilder B(AS, Idx); 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), - IE = Attrs.pImpl->end(I); II != IE; ++II) - B.removeAttributes(*II); + B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Idx); break; } @@ -706,6 +726,18 @@ AttributeSetNode *AttributeSet::getAttributes(unsigned Idx) const { return 0; } +AttributeSet::iterator AttributeSet::begin(unsigned Idx) const { + if (!pImpl) + return ArrayRef().begin(); + return pImpl->begin(Idx); +} + +AttributeSet::iterator AttributeSet::end(unsigned Idx) const { + if (!pImpl) + return ArrayRef().end(); + return pImpl->end(Idx); +} + //===----------------------------------------------------------------------===// // AttributeSet Introspection Methods //===----------------------------------------------------------------------===// @@ -759,33 +791,15 @@ AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) AttributeSetImpl *pImpl = AS.pImpl; if (!pImpl) return; - AttrBuilder B; - for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { if (pImpl->getSlotIndex(I) != Idx) continue; - for (AttributeSetNode::const_iterator II = pImpl->begin(I), + for (AttributeSetImpl::const_iterator II = pImpl->begin(I), IE = pImpl->end(I); II != IE; ++II) - B.addAttributes(*II); + addAttribute(*II); break; } - - if (!B.hasAttributes()) return; - - uint64_t Mask = B.Raw(); - - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) { - if (uint64_t A = (Mask & AttributeImpl::getAttrMask(I))) { - Attrs.insert(I); - - if (I == Attribute::Alignment) - Alignment = 1ULL << ((A >> 16) - 1); - else if (I == Attribute::StackAlignment) - StackAlignment = 1ULL << ((A >> 26)-1); - } - } } void AttrBuilder::clear() { @@ -794,12 +808,27 @@ void AttrBuilder::clear() { } AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { + assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && + "Adding alignment attribute without adding alignment value!"); Attrs.insert(Val); return *this; } +AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { + ConstantInt *Kind = cast(Attr.getAttributeKind()); + Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue()); + Attrs.insert(KindVal); + + if (KindVal == Attribute::Alignment) + Alignment = Attr.getAlignment(); + else if (KindVal == Attribute::StackAlignment) + StackAlignment = Attr.getStackAlignment(); + return *this; +} + AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { Attrs.erase(Val); + if (Val == Attribute::Alignment) Alignment = 0; else if (Val == Attribute::StackAlignment) @@ -808,34 +837,25 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { return *this; } -AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) { - uint64_t Mask = Attr.Raw(); - - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) - if ((Mask & AttributeImpl::getAttrMask(I)) != 0) - Attrs.insert(I); - - if (Attr.getAlignment()) - Alignment = Attr.getAlignment(); - if (Attr.getStackAlignment()) - StackAlignment = Attr.getStackAlignment(); - return *this; -} +AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { + unsigned Idx = ~0U; + for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I) + if (A.getSlotIndex(I) == Index) { + Idx = I; + break; + } -AttrBuilder &AttrBuilder::removeAttributes(Attribute A) { - uint64_t Mask = A.Raw(); + assert(Idx != ~0U && "Couldn't find index in AttributeSet!"); - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) { - if (Mask & AttributeImpl::getAttrMask(I)) { - Attrs.erase(I); + for (AttributeSet::iterator I = A.begin(Idx), E = A.end(Idx); I != E; ++I) { + ConstantInt *CI = cast(I->getAttributeKind()); + Attribute::AttrKind Kind = Attribute::AttrKind(CI->getZExtValue()); + Attrs.erase(Kind); - if (I == Attribute::Alignment) - Alignment = 0; - else if (I == Attribute::StackAlignment) - StackAlignment = 0; - } + if (Kind == Attribute::Alignment) + Alignment = 0; + else if (Kind == Attribute::StackAlignment) + StackAlignment = 0; } return *this; @@ -872,8 +892,28 @@ bool AttrBuilder::hasAttributes() const { return !Attrs.empty(); } -bool AttrBuilder::hasAttributes(const Attribute &A) const { - return Raw() & A.Raw(); +bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { + unsigned Idx = ~0U; + for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I) + if (A.getSlotIndex(I) == Index) { + Idx = I; + break; + } + + assert(Idx != ~0U && "Couldn't find the index!"); + + for (AttributeSet::iterator I = A.begin(Idx), E = A.end(Idx); + I != E; ++I) { + Attribute Attr = *I; + // FIXME: Support StringRefs. + ConstantInt *Kind = cast(Attr.getAttributeKind()); + Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue()); + + if (Attrs.count(KindVal)) + return true; + } + + return false; } bool AttrBuilder::hasAlignmentAttr() const { @@ -887,6 +927,7 @@ bool AttrBuilder::operator==(const AttrBuilder &B) { } AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { + // FIXME: Remove this in 4.0. if (!Val) return *this; for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; @@ -904,29 +945,12 @@ AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { return *this; } -uint64_t AttrBuilder::Raw() const { - uint64_t Mask = 0; - - for (DenseSet::const_iterator I = Attrs.begin(), - E = Attrs.end(); I != E; ++I) { - Attribute::AttrKind Kind = *I; - - if (Kind == Attribute::Alignment) - Mask |= (Log2_32(Alignment) + 1) << 16; - else if (Kind == Attribute::StackAlignment) - Mask |= (Log2_32(StackAlignment) + 1) << 26; - else - Mask |= AttributeImpl::getAttrMask(Kind); - } - - return Mask; -} - //===----------------------------------------------------------------------===// // AttributeFuncs Function Defintions //===----------------------------------------------------------------------===// -Attribute AttributeFuncs::typeIncompatible(Type *Ty) { +/// \brief Which attributes cannot be applied to a type. +AttributeSet AttributeFuncs::typeIncompatible(Type *Ty, uint64_t Index) { AttrBuilder Incompatible; if (!Ty->isIntegerTy()) @@ -942,46 +966,5 @@ Attribute AttributeFuncs::typeIncompatible(Type *Ty) { .addAttribute(Attribute::NoCapture) .addAttribute(Attribute::StructRet); - return Attribute::get(Ty->getContext(), Incompatible); -} - -/// \brief This returns an integer containing an encoding of all the LLVM -/// attributes found in the given attribute bitset. Any change to this encoding -/// is a breaking change to bitcode compatibility. -/// N.B. This should be used only by the bitcode reader! -uint64_t AttributeFuncs::encodeLLVMAttributesForBitcode(AttributeSet Attrs, - unsigned Index) { - // FIXME: It doesn't make sense to store the alignment information as an - // expanded out value, we should store it as a log2 value. However, we can't - // just change that here without breaking bitcode compatibility. If this ever - // becomes a problem in practice, we should introduce new tag numbers in the - // bitcode file and have those tags use a more efficiently encoded alignment - // field. - - // Store the alignment in the bitcode as a 16-bit raw value instead of a 5-bit - // log2 encoded value. Shift the bits above the alignment up by 11 bits. - uint64_t EncodedAttrs = Attrs.Raw(Index) & 0xffff; - if (Attrs.hasAttribute(Index, Attribute::Alignment)) - EncodedAttrs |= Attrs.getParamAlignment(Index) << 16; - EncodedAttrs |= (Attrs.Raw(Index) & (0xffffULL << 21)) << 11; - return EncodedAttrs; -} - -/// \brief This fills an AttrBuilder object with the LLVM attributes that have -/// been decoded from the given integer. This function must stay in sync with -/// 'encodeLLVMAttributesForBitcode'. -/// N.B. This should be used only by the bitcode reader! -void AttributeFuncs::decodeLLVMAttributesForBitcode(LLVMContext &C, - AttrBuilder &B, - uint64_t EncodedAttrs) { - // The alignment is stored as a 16-bit raw value from bits 31--16. We shift - // the bits above 31 down by 11 bits. - unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16; - assert((!Alignment || isPowerOf2_32(Alignment)) && - "Alignment must be a power of two."); - - if (Alignment) - B.addAlignmentAttr(Alignment); - B.addRawValue(((EncodedAttrs & (0xffffULL << 32)) >> 11) | - (EncodedAttrs & 0xffff)); + return AttributeSet::get(Ty->getContext(), Index, Incompatible); }