diff options
author | Bill Wendling <isanbard@gmail.com> | 2013-02-05 22:37:24 +0000 |
---|---|---|
committer | Bill Wendling <isanbard@gmail.com> | 2013-02-05 22:37:24 +0000 |
commit | 8c74ecfbddabe89e150abff4fdff0a27108874b9 (patch) | |
tree | 7365c1c933ddb77cd29d0a5422fb7ce5dd39fb4e /lib/IR | |
parent | 2a1b60d791522d73be91d4281c90d25bd5e3d117 (diff) | |
download | external_llvm-8c74ecfbddabe89e150abff4fdff0a27108874b9.zip external_llvm-8c74ecfbddabe89e150abff4fdff0a27108874b9.tar.gz external_llvm-8c74ecfbddabe89e150abff4fdff0a27108874b9.tar.bz2 |
Convert to storing the attribute's internals as enums, integers, and strings.
The stuff we're handing are all enums (Attribute::AttrKind), integers and
strings. Don't convert them to Constants, which is an unnecessary step here. The
rest of the changes are mostly mechanical.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174456 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/IR')
-rw-r--r-- | lib/IR/AttributeImpl.h | 122 | ||||
-rw-r--r-- | lib/IR/Attributes.cpp | 256 |
2 files changed, 251 insertions, 127 deletions
diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index bf87562..5f9e3e7 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -27,47 +27,127 @@ class LLVMContext; //===----------------------------------------------------------------------===// /// \class +/// \brief A set of classes that contain the kind and (optional) value of the +/// attribute object. There are three main categories: enum attribute entries, +/// represented by Attribute::AttrKind; alignment attribute entries; and string +/// attribute enties, which are for target-dependent attributes. +class AttributeEntry { + unsigned char KindID; +protected: + enum AttrEntryKind { + EnumAttrEntry, + AlignAttrEntry, + StringAttrEntry + }; +public: + AttributeEntry(AttrEntryKind Kind) + : KindID(Kind) {} + virtual ~AttributeEntry() {} + + unsigned getKindID() const { return KindID; } + + static inline bool classof(const AttributeEntry *) { return true; } +}; + +class EnumAttributeEntry : public AttributeEntry { + Attribute::AttrKind Kind; +public: + EnumAttributeEntry(Attribute::AttrKind Kind) + : AttributeEntry(EnumAttrEntry), Kind(Kind) {} + + Attribute::AttrKind getEnumKind() const { return Kind; } + + static inline bool classof(const AttributeEntry *AE) { + return AE->getKindID() == EnumAttrEntry; + } + static inline bool classof(const EnumAttributeEntry *) { return true; } +}; + +class AlignAttributeEntry : public AttributeEntry { + Attribute::AttrKind Kind; + unsigned Align; +public: + AlignAttributeEntry(Attribute::AttrKind Kind, unsigned Align) + : AttributeEntry(AlignAttrEntry), Kind(Kind), Align(Align) {} + + Attribute::AttrKind getEnumKind() const { return Kind; } + unsigned getAlignment() const { return Align; } + + static inline bool classof(const AttributeEntry *AE) { + return AE->getKindID() == AlignAttrEntry; + } + static inline bool classof(const AlignAttributeEntry *) { return true; } +}; + +class StringAttributeEntry : public AttributeEntry { + std::string Kind; + std::string Val; +public: + StringAttributeEntry(StringRef Kind, StringRef Val = StringRef()) + : AttributeEntry(StringAttrEntry), Kind(Kind), Val(Val) {} + + StringRef getStringKind() const { return Kind; } + StringRef getStringValue() const { return Val; } + + static inline bool classof(const AttributeEntry *AE) { + return AE->getKindID() == StringAttrEntry; + } + static inline bool classof(const StringAttributeEntry *) { return true; } +}; + +//===----------------------------------------------------------------------===// +/// \class /// \brief This class represents a single, uniqued attribute. That attribute /// could be a single enum, a tuple, or a string. class AttributeImpl : public FoldingSetNode { - LLVMContext &Context; ///< Global context for uniquing objects - Constant *Kind; ///< Kind of attribute: enum or string - Constant *Values; ///< Values associated with the attribute + LLVMContext &Context; ///< Global context for uniquing objects + Constant *Kind; ///< Kind of attribute: enum or string + + AttributeEntry *Entry; ///< Holds the kind and value of the attribute // AttributesImpl is uniqued, these should not be publicly available. void operator=(const AttributeImpl &) LLVM_DELETED_FUNCTION; AttributeImpl(const AttributeImpl &) LLVM_DELETED_FUNCTION; public: - AttributeImpl(LLVMContext &C, Constant *Kind, Constant *Values = 0) - : Context(C), Kind(Kind), Values(Values) {} + AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind); + AttributeImpl(LLVMContext &C, Attribute::AttrKind Kind, unsigned Align); + AttributeImpl(LLVMContext &C, StringRef Kind, StringRef Val = StringRef()); + ~AttributeImpl(); LLVMContext &getContext() { return Context; } - bool hasAttribute(Attribute::AttrKind A) const; + bool isEnumAttribute() const; + bool isAlignAttribute() const; + bool isStringAttribute() const; - Constant *getAttributeKind() const { return Kind; } - Constant *getAttributeValues() const { return Values; } - - uint64_t getAlignment() const; - uint64_t getStackAlignment() const; + bool hasAttribute(Attribute::AttrKind A) const; + bool hasAttribute(StringRef Kind) const; - /// \brief Equality and non-equality comparison operators. - bool operator==(Attribute::AttrKind Kind) const; - bool operator!=(Attribute::AttrKind Kind) const; + Attribute::AttrKind getKindAsEnum() const; + uint64_t getValueAsInt() const; - bool operator==(StringRef Kind) const; - bool operator!=(StringRef Kind) const; + StringRef getKindAsString() const; + StringRef getValueAsString() const; /// \brief Used when sorting the attributes. bool operator<(const AttributeImpl &AI) const; void Profile(FoldingSetNodeID &ID) const { - Profile(ID, Kind, Values); + if (isEnumAttribute()) + Profile(ID, getKindAsEnum(), 0); + else if (isAlignAttribute()) + Profile(ID, getKindAsEnum(), getValueAsInt()); + else + Profile(ID, getKindAsString(), getValueAsString()); + } + static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind, + uint64_t Val) { + ID.AddInteger(Kind); + if (Val) ID.AddInteger(Val); } - static void Profile(FoldingSetNodeID &ID, Constant *Kind, Constant *Values) { - ID.AddPointer(Kind); - if (Values) - ID.AddPointer(Values); + static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) { + ID.AddString(Kind); + ID.AddString(Values); } // FIXME: Remove this! diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 8a0551c..d61bd09 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -30,11 +30,12 @@ using namespace llvm; // Attribute Construction Methods //===----------------------------------------------------------------------===// -Attribute Attribute::get(LLVMContext &Context, Constant *Kind, Constant *Val) { +Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, + uint64_t Val) { LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; - ID.AddPointer(Kind); - if (Val) ID.AddPointer(Val); + ID.AddInteger(Kind); + if (Val) ID.AddInteger(Val); void *InsertPoint; AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); @@ -42,7 +43,9 @@ Attribute Attribute::get(LLVMContext &Context, Constant *Kind, Constant *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 = !Val ? + new AttributeImpl(Context, Kind) : + new AttributeImpl(Context, Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -50,47 +53,88 @@ Attribute Attribute::get(LLVMContext &Context, Constant *Kind, Constant *Val) { 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::get(LLVMContext &Context, StringRef Kind, StringRef Val) { + LLVMContextImpl *pImpl = Context.pImpl; + FoldingSetNodeID ID; + ID.AddString(Kind); + if (!Val.empty()) ID.AddString(Val); + + void *InsertPoint; + AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); + + 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); + pImpl->AttrsSet.InsertNode(PA, InsertPoint); + } + + // Return the Attribute that we found or created. + return Attribute(PA); } Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t 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)); + return get(Context, Alignment, Align); } Attribute Attribute::getWithStackAlignment(LLVMContext &Context, uint64_t 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)); + return get(Context, StackAlignment, Align); } //===----------------------------------------------------------------------===// // Attribute Accessor Methods //===----------------------------------------------------------------------===// -bool Attribute::hasAttribute(AttrKind Val) const { - return pImpl && pImpl->hasAttribute(Val); +bool Attribute::isEnumAttribute() const { + return pImpl && pImpl->isEnumAttribute(); } -Constant *Attribute::getAttributeKind() const { - return pImpl ? pImpl->getAttributeKind() : 0; +bool Attribute::isAlignAttribute() const { + return pImpl && pImpl->isAlignAttribute(); } -Constant *Attribute::getAttributeValues() const { - return pImpl ? pImpl->getAttributeValues() : 0; +bool Attribute::isStringAttribute() const { + return pImpl && pImpl->isStringAttribute(); +} + +Attribute::AttrKind Attribute::getKindAsEnum() const { + assert((isEnumAttribute() || isAlignAttribute()) && + "Invalid attribute type to get the kind as an enum!"); + return pImpl ? pImpl->getKindAsEnum() : None; +} + +uint64_t Attribute::getValueAsInt() const { + assert(isAlignAttribute() && + "Expected the attribute to be an alignment attribute!"); + return pImpl ? pImpl->getValueAsInt() : 0; +} + +StringRef Attribute::getKindAsString() const { + assert(isStringAttribute() && + "Invalid attribute type to get the kind as a string!"); + return pImpl ? pImpl->getKindAsString() : StringRef(); +} + +StringRef Attribute::getValueAsString() const { + assert(isStringAttribute() && + "Invalid attribute type to get the value as a string!"); + return pImpl ? pImpl->getValueAsString() : StringRef(); +} + +bool Attribute::hasAttribute(AttrKind Val) const { + return (pImpl && pImpl->hasAttribute(Val)) || (!pImpl && Val == None); } /// This returns the alignment field of an attribute as a byte alignment value. unsigned Attribute::getAlignment() const { assert(hasAttribute(Attribute::Alignment) && "Trying to get alignment from non-alignment attribute!"); - return pImpl->getAlignment(); + return pImpl->getValueAsInt(); } /// This returns the stack alignment field of an attribute as a byte alignment @@ -98,7 +142,7 @@ unsigned Attribute::getAlignment() const { unsigned Attribute::getStackAlignment() const { assert(hasAttribute(Attribute::StackAlignment) && "Trying to get alignment from non-alignment attribute!"); - return pImpl->getStackAlignment(); + return pImpl->getValueAsInt(); } std::string Attribute::getAsString() const { @@ -166,17 +210,17 @@ std::string Attribute::getAsString() const { // align=4 // alignstack=8 // - if (hasAttribute(Attribute::StackAlignment)) { + if (hasAttribute(Attribute::Alignment)) { std::string Result; - Result += "alignstack("; - Result += utostr(getStackAlignment()); - Result += ")"; + Result += "align "; + Result += utostr(getValueAsInt()); return Result; } - if (hasAttribute(Attribute::Alignment)) { + if (hasAttribute(Attribute::StackAlignment)) { std::string Result; - Result += "align "; - Result += utostr(getAlignment()); + Result += "alignstack("; + Result += utostr(getValueAsInt()); + Result += ")"; return Result; } @@ -186,33 +230,21 @@ std::string Attribute::getAsString() const { // "kind" = "value" // "kind" = ( "value1" "value2" "value3" ) // - if (ConstantDataArray *CDA = - dyn_cast<ConstantDataArray>(pImpl->getAttributeKind())) { + if (isStringAttribute()) { std::string Result; - Result += '\"' + CDA->getAsString().str() + '"'; + Result += '\"' + getKindAsString().str() + '"'; - Constant *Vals = pImpl->getAttributeValues(); - if (!Vals) return Result; - - // FIXME: This should support more than just ConstantDataArrays. Also, - // support a vector of attribute values. + StringRef Val = pImpl->getValueAsString(); + if (Val.empty()) return Result; Result += " = "; - Result += '\"' + cast<ConstantDataArray>(Vals)->getAsString().str() + '"'; - + Result += '\"' + Val.str() + '"'; return Result; } llvm_unreachable("Unknown attribute"); } -bool Attribute::operator==(AttrKind K) const { - return (pImpl && *pImpl == K) || (!pImpl && K == None); -} -bool Attribute::operator!=(AttrKind K) const { - return !(*this == K); -} - bool Attribute::operator<(Attribute A) const { if (!pImpl && !A.pImpl) return false; if (!pImpl) return true; @@ -224,68 +256,86 @@ bool Attribute::operator<(Attribute A) const { // AttributeImpl Definition //===----------------------------------------------------------------------===// -bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { - if (ConstantInt *CI = dyn_cast<ConstantInt>(Kind)) - return CI->getZExtValue() == A; - return false; +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); } -uint64_t AttributeImpl::getAlignment() const { - assert(hasAttribute(Attribute::Alignment) && - "Trying to retrieve the alignment from a non-alignment attr!"); - return cast<ConstantInt>(Values)->getZExtValue(); +AttributeImpl::AttributeImpl(LLVMContext &C, StringRef Kind, StringRef Val) + : Context(C), Entry(new StringAttributeEntry(Kind, Val)) {} + +AttributeImpl::~AttributeImpl() { + delete Entry; } -uint64_t AttributeImpl::getStackAlignment() const { - assert(hasAttribute(Attribute::StackAlignment) && - "Trying to retrieve the stack alignment from a non-alignment attr!"); - return cast<ConstantInt>(Values)->getZExtValue(); +bool AttributeImpl::isEnumAttribute() const { + return isa<EnumAttributeEntry>(Entry); } -bool AttributeImpl::operator==(Attribute::AttrKind kind) const { - if (ConstantInt *CI = dyn_cast<ConstantInt>(Kind)) - return CI->getZExtValue() == kind; - return false; +bool AttributeImpl::isAlignAttribute() const { + return isa<AlignAttributeEntry>(Entry); } -bool AttributeImpl::operator!=(Attribute::AttrKind kind) const { - return !(*this == kind); + +bool AttributeImpl::isStringAttribute() const { + return isa<StringAttributeEntry>(Entry); } -bool AttributeImpl::operator==(StringRef kind) const { - if (ConstantDataArray *CDA = dyn_cast<ConstantDataArray>(Kind)) - if (CDA->isString()) - return CDA->getAsString() == kind; - return false; +bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { + if (isStringAttribute()) return false; + return getKindAsEnum() == A; } -bool AttributeImpl::operator!=(StringRef kind) const { - return !(*this == kind); +bool AttributeImpl::hasAttribute(StringRef Kind) const { + if (!isStringAttribute()) return false; + return getKindAsString() == Kind; } -bool AttributeImpl::operator<(const AttributeImpl &AI) const { - // This sorts the attributes with Attribute::AttrKinds coming first (sorted - // relative to their enum value) and then strings. +Attribute::AttrKind AttributeImpl::getKindAsEnum() const { + if (EnumAttributeEntry *E = dyn_cast<EnumAttributeEntry>(Entry)) + return E->getEnumKind(); + return cast<AlignAttributeEntry>(Entry)->getEnumKind(); +} - if (!Kind && !AI.Kind) return false; - if (!Kind && AI.Kind) return true; - if (Kind && !AI.Kind) return false; +uint64_t AttributeImpl::getValueAsInt() const { + return cast<AlignAttributeEntry>(Entry)->getAlignment(); +} - ConstantInt *ThisCI = dyn_cast<ConstantInt>(Kind); - ConstantInt *ThatCI = dyn_cast<ConstantInt>(AI.Kind); +StringRef AttributeImpl::getKindAsString() const { + return cast<StringAttributeEntry>(Entry)->getStringKind(); +} - ConstantDataArray *ThisCDA = dyn_cast<ConstantDataArray>(Kind); - ConstantDataArray *ThatCDA = dyn_cast<ConstantDataArray>(AI.Kind); +StringRef AttributeImpl::getValueAsString() const { + return cast<StringAttributeEntry>(Entry)->getStringValue(); +} - if (ThisCI && ThatCI) - return ThisCI->getZExtValue() < ThatCI->getZExtValue(); +bool AttributeImpl::operator<(const AttributeImpl &AI) const { + // This sorts the attributes with Attribute::AttrKinds coming first (sorted + // relative to their enum value) and then strings. + if (isEnumAttribute()) + if (AI.isAlignAttribute() || AI.isEnumAttribute()) + return getKindAsEnum() < AI.getKindAsEnum(); - if (ThisCI && ThatCDA) - return true; + if (isAlignAttribute()) { + if (!AI.isStringAttribute() && getKindAsEnum() < AI.getKindAsEnum()) + return true; + if (AI.isAlignAttribute()) + return getValueAsInt() < AI.getValueAsInt(); + } - if (ThisCDA && ThatCI) - return false; + if (isStringAttribute()) { + if (!AI.isStringAttribute()) return false; + if (getKindAsString() < AI.getKindAsString()) return true; + if (getKindAsString() == AI.getKindAsString()) + return getValueAsString() < AI.getValueAsString(); + } - return ThisCDA->getAsString() < ThatCDA->getAsString(); + return false; } uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { @@ -413,15 +463,14 @@ uint64_t AttributeSetImpl::Raw(uint64_t Index) const { for (AttributeSetNode::const_iterator II = ASN->begin(), IE = ASN->end(); II != IE; ++II) { Attribute Attr = *II; - ConstantInt *Kind = cast<ConstantInt>(Attr.getAttributeKind()); - Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue()); + Attribute::AttrKind Kind = Attr.getKindAsEnum(); - if (KindVal == Attribute::Alignment) + if (Kind == Attribute::Alignment) Mask |= (Log2_32(ASN->getAlignment()) + 1) << 16; - else if (KindVal == Attribute::StackAlignment) + else if (Kind == Attribute::StackAlignment) Mask |= (Log2_32(ASN->getStackAlignment()) + 1) << 26; else - Mask |= AttributeImpl::getAttrMask(KindVal); + Mask |= AttributeImpl::getAttrMask(Kind); } return Mask; @@ -465,7 +514,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 != Attribute::None && + assert(!Attrs[i].second.hasAttribute(Attribute::None) && "Pointless attribute!"); } #endif @@ -815,13 +864,13 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { } AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { - ConstantInt *Kind = cast<ConstantInt>(Attr.getAttributeKind()); - Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue()); - Attrs.insert(KindVal); + // FIXME: Handle string attributes. + Attribute::AttrKind Kind = Attr.getKindAsEnum(); + Attrs.insert(Kind); - if (KindVal == Attribute::Alignment) + if (Kind == Attribute::Alignment) Alignment = Attr.getAlignment(); - else if (KindVal == Attribute::StackAlignment) + else if (Kind == Attribute::StackAlignment) StackAlignment = Attr.getStackAlignment(); return *this; } @@ -853,8 +902,8 @@ AttrBuilder &AttrBuilder::removeAttributes(AttributeSet A, uint64_t Index) { assert(Idx != ~0U && "Couldn't find index in AttributeSet!"); for (AttributeSet::iterator I = A.begin(Idx), E = A.end(Idx); I != E; ++I) { - ConstantInt *CI = cast<ConstantInt>(I->getAttributeKind()); - Attribute::AttrKind Kind = Attribute::AttrKind(CI->getZExtValue()); + // FIXME: Support string attributes. + Attribute::AttrKind Kind = I->getKindAsEnum(); Attrs.erase(Kind); if (Kind == Attribute::Alignment) @@ -915,15 +964,10 @@ bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const { 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<ConstantInt>(Attr.getAttributeKind()); - Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue()); - - if (Attrs.count(KindVal)) + I != E; ++I) + // FIXME: Support string attributes. + if (Attrs.count(I->getKindAsEnum())) return true; - } return false; } |