Begin the transition to using the AttributesImpl object for the Attributes ivar.

Start using the AttributesImpl object to hold the value of the attributes. All
queries go through the interfaces now.

This has one unfortunate consequence. I needed to move the AttributesImpl.h file
into include/llvm. But this is only temporary! Otherwise, the changes needed to
support this would be too large.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165433 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling 2012-10-08 21:47:17 +00:00
parent 5b4461c0f1
commit 8e635dbc78
4 changed files with 229 additions and 85 deletions

View File

@ -15,6 +15,7 @@
#ifndef LLVM_ATTRIBUTES_H #ifndef LLVM_ATTRIBUTES_H
#define LLVM_ATTRIBUTES_H #define LLVM_ATTRIBUTES_H
#include "llvm/AttributesImpl.h"
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include <cassert> #include <cassert>
@ -142,20 +143,20 @@ class AttributesImpl;
/// Attributes - A bitset of attributes. /// Attributes - A bitset of attributes.
class Attributes { class Attributes {
// Currently, we need less than 64 bits. // Currently, we need less than 64 bits.
uint64_t Bits; AttributesImpl Attrs;
explicit Attributes(AttributesImpl *A); explicit Attributes(AttributesImpl *A);
public: public:
Attributes() : Bits(0) {} Attributes() : Attrs(0) {}
explicit Attributes(uint64_t Val) : Bits(Val) {} explicit Attributes(uint64_t Val);
/*implicit*/ Attributes(Attribute::AttrConst Val) : Bits(Val.v) {} /*implicit*/ Attributes(Attribute::AttrConst Val);
class Builder { class Builder {
friend class Attributes; friend class Attributes;
uint64_t Bits; uint64_t Bits;
public: public:
Builder() : Bits(0) {} Builder() : Bits(0) {}
Builder(const Attributes &A) : Bits(A.Bits) {} Builder(const Attributes &A) : Bits(A.Raw()) {}
void addAddressSafetyAttr(); void addAddressSafetyAttr();
void addAlwaysInlineAttr(); void addAlwaysInlineAttr();
@ -185,6 +186,32 @@ public:
void addAlignmentAttr(unsigned Align); void addAlignmentAttr(unsigned Align);
void addStackAlignmentAttr(unsigned Align); void addStackAlignmentAttr(unsigned Align);
void removeAddressSafetyAttr();
void removeAlwaysInlineAttr();
void removeByValAttr();
void removeInlineHintAttr();
void removeInRegAttr();
void removeNakedAttr();
void removeNestAttr();
void removeNoAliasAttr();
void removeNoCaptureAttr();
void removeNoImplicitFloatAttr();
void removeNoInlineAttr();
void removeNonLazyBindAttr();
void removeNoRedZoneAttr();
void removeNoReturnAttr();
void removeNoUnwindAttr();
void removeOptimizeForSizeAttr();
void removeReadNoneAttr();
void removeReadOnlyAttr();
void removeReturnsTwiceAttr();
void removeSExtAttr();
void removeStackProtectAttr();
void removeStackProtectReqAttr();
void removeStructRetAttr();
void removeUWTableAttr();
void removeZExtAttr();
}; };
/// get - Return a uniquified Attributes object. This takes the uniquified /// get - Return a uniquified Attributes object. This takes the uniquified
@ -194,7 +221,7 @@ public:
// Attribute query methods. // Attribute query methods.
// FIXME: StackAlignment & Alignment attributes have no predicate methods. // FIXME: StackAlignment & Alignment attributes have no predicate methods.
bool hasAttributes() const { bool hasAttributes() const {
return Bits != 0; return Attrs.hasAttributes();
} }
bool hasAttributes(const Attributes &A) const; bool hasAttributes(const Attributes &A) const;
bool hasAddressSafetyAttr() const; bool hasAddressSafetyAttr() const;
@ -236,22 +263,22 @@ public:
bool isEmptyOrSingleton() const; bool isEmptyOrSingleton() const;
// This is a "safe bool() operator". // This is a "safe bool() operator".
operator const void *() const { return Bits ? this : 0; } operator const void *() const { return Attrs.Bits ? this : 0; }
bool operator == (const Attributes &Attrs) const { bool operator == (const Attributes &A) const {
return Bits == Attrs.Bits; return Attrs.Bits == A.Attrs.Bits;
} }
bool operator != (const Attributes &Attrs) const { bool operator != (const Attributes &A) const {
return Bits != Attrs.Bits; return Attrs.Bits != A.Attrs.Bits;
} }
Attributes operator | (const Attributes &Attrs) const; Attributes operator | (const Attributes &A) const;
Attributes operator & (const Attributes &Attrs) const; Attributes operator & (const Attributes &A) const;
Attributes operator ^ (const Attributes &Attrs) const; Attributes operator ^ (const Attributes &A) const;
Attributes &operator |= (const Attributes &Attrs); Attributes &operator |= (const Attributes &A);
Attributes &operator &= (const Attributes &Attrs); Attributes &operator &= (const Attributes &A);
Attributes operator ~ () const; Attributes operator ~ () const;
uint64_t Raw() const { return Bits; } uint64_t Raw() const;
/// constructAlignmentFromInt - This turns an int alignment (a power of 2, /// constructAlignmentFromInt - This turns an int alignment (a power of 2,
/// normally) into the form used internally in Attributes. /// normally) into the form used internally in Attributes.

View File

@ -19,14 +19,24 @@
namespace llvm { namespace llvm {
class AttributesImpl : public FoldingSetNode { class Attributes;
uint64_t Bits; // FIXME: We will be expanding this.
void operator=(const AttributesImpl &) LLVM_DELETED_FUNCTION; class AttributesImpl : public FoldingSetNode {
AttributesImpl(const AttributesImpl &) LLVM_DELETED_FUNCTION; friend class Attributes;
uint64_t Bits; // FIXME: We will be expanding this.
public: public:
AttributesImpl(uint64_t bits) : Bits(bits) {} AttributesImpl(uint64_t bits) : Bits(bits) {}
bool hasAttribute(uint64_t A) const;
bool hasAttributes() const;
bool hasAttributes(const Attributes &A) const;
uint64_t getAlignment() const;
uint64_t getStackAlignment() const;
bool isEmptyOrSingleton() const;
void Profile(FoldingSetNodeID &ID) const { void Profile(FoldingSetNodeID &ID) const {
Profile(ID, Bits); Profile(ID, Bits);
} }

View File

@ -12,7 +12,6 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/Attributes.h" #include "llvm/Attributes.h"
#include "AttributesImpl.h"
#include "LLVMContextImpl.h" #include "LLVMContextImpl.h"
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/ADT/StringExtras.h" #include "llvm/ADT/StringExtras.h"
@ -25,99 +24,129 @@
using namespace llvm; using namespace llvm;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Attribute Function Definitions // Attributes Implementation
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
Attributes::Attributes(uint64_t Val) : Attrs(Val) {}
Attributes::Attributes(Attribute::AttrConst Val) : Attrs(Val.v) {}
Attributes::Attributes(AttributesImpl *A) : Attrs(A->Bits) {}
Attributes Attributes::get(LLVMContext &Context, Attributes::Builder &B) {
// If there are no attributes, return an empty Attributes class.
if (B.Bits == 0)
return Attributes();
// Otherwise, build a key to look up the existing attributes.
LLVMContextImpl *pImpl = Context.pImpl;
FoldingSetNodeID ID;
ID.AddInteger(B.Bits);
void *InsertPoint;
AttributesImpl *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 AttributesImpl(B.Bits);
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
}
// Return the AttributesList that we found or created.
return Attributes(PA);
}
bool Attributes::hasAttributes(const Attributes &A) const { bool Attributes::hasAttributes(const Attributes &A) const {
return Bits & A.Bits; return Attrs.hasAttributes(A);
} }
bool Attributes::hasAddressSafetyAttr() const { bool Attributes::hasAddressSafetyAttr() const {
return Bits & Attribute::AddressSafety_i; return Attrs.hasAttribute(Attribute::AddressSafety_i);
} }
bool Attributes::hasAlignmentAttr() const { bool Attributes::hasAlignmentAttr() const {
return Bits & Attribute::Alignment_i; return Attrs.hasAttribute(Attribute::Alignment_i);
} }
bool Attributes::hasAlwaysInlineAttr() const { bool Attributes::hasAlwaysInlineAttr() const {
return Bits & Attribute::AlwaysInline_i; return Attrs.hasAttribute(Attribute::AlwaysInline_i);
} }
bool Attributes::hasByValAttr() const { bool Attributes::hasByValAttr() const {
return Bits & Attribute::ByVal_i; return Attrs.hasAttribute(Attribute::ByVal_i);
} }
bool Attributes::hasInlineHintAttr() const { bool Attributes::hasInlineHintAttr() const {
return Bits & Attribute::InlineHint_i; return Attrs.hasAttribute(Attribute::InlineHint_i);
} }
bool Attributes::hasInRegAttr() const { bool Attributes::hasInRegAttr() const {
return Bits & Attribute::InReg_i; return Attrs.hasAttribute(Attribute::InReg_i);
} }
bool Attributes::hasNakedAttr() const { bool Attributes::hasNakedAttr() const {
return Bits & Attribute::Naked_i; return Attrs.hasAttribute(Attribute::Naked_i);
} }
bool Attributes::hasNestAttr() const { bool Attributes::hasNestAttr() const {
return Bits & Attribute::Nest_i; return Attrs.hasAttribute(Attribute::Nest_i);
} }
bool Attributes::hasNoAliasAttr() const { bool Attributes::hasNoAliasAttr() const {
return Bits & Attribute::NoAlias_i; return Attrs.hasAttribute(Attribute::NoAlias_i);
} }
bool Attributes::hasNoCaptureAttr() const { bool Attributes::hasNoCaptureAttr() const {
return Bits & Attribute::NoCapture_i; return Attrs.hasAttribute(Attribute::NoCapture_i);
} }
bool Attributes::hasNoImplicitFloatAttr() const { bool Attributes::hasNoImplicitFloatAttr() const {
return Bits & Attribute::NoImplicitFloat_i; return Attrs.hasAttribute(Attribute::NoImplicitFloat_i);
} }
bool Attributes::hasNoInlineAttr() const { bool Attributes::hasNoInlineAttr() const {
return Bits & Attribute::NoInline_i; return Attrs.hasAttribute(Attribute::NoInline_i);
} }
bool Attributes::hasNonLazyBindAttr() const { bool Attributes::hasNonLazyBindAttr() const {
return Bits & Attribute::NonLazyBind_i; return Attrs.hasAttribute(Attribute::NonLazyBind_i);
} }
bool Attributes::hasNoRedZoneAttr() const { bool Attributes::hasNoRedZoneAttr() const {
return Bits & Attribute::NoRedZone_i; return Attrs.hasAttribute(Attribute::NoRedZone_i);
} }
bool Attributes::hasNoReturnAttr() const { bool Attributes::hasNoReturnAttr() const {
return Bits & Attribute::NoReturn_i; return Attrs.hasAttribute(Attribute::NoReturn_i);
} }
bool Attributes::hasNoUnwindAttr() const { bool Attributes::hasNoUnwindAttr() const {
return Bits & Attribute::NoUnwind_i; return Attrs.hasAttribute(Attribute::NoUnwind_i);
} }
bool Attributes::hasOptimizeForSizeAttr() const { bool Attributes::hasOptimizeForSizeAttr() const {
return Bits & Attribute::OptimizeForSize_i; return Attrs.hasAttribute(Attribute::OptimizeForSize_i);
} }
bool Attributes::hasReadNoneAttr() const { bool Attributes::hasReadNoneAttr() const {
return Bits & Attribute::ReadNone_i; return Attrs.hasAttribute(Attribute::ReadNone_i);
} }
bool Attributes::hasReadOnlyAttr() const { bool Attributes::hasReadOnlyAttr() const {
return Bits & Attribute::ReadOnly_i; return Attrs.hasAttribute(Attribute::ReadOnly_i);
} }
bool Attributes::hasReturnsTwiceAttr() const { bool Attributes::hasReturnsTwiceAttr() const {
return Bits & Attribute::ReturnsTwice_i; return Attrs.hasAttribute(Attribute::ReturnsTwice_i);
} }
bool Attributes::hasSExtAttr() const { bool Attributes::hasSExtAttr() const {
return Bits & Attribute::SExt_i; return Attrs.hasAttribute(Attribute::SExt_i);
} }
bool Attributes::hasStackAlignmentAttr() const { bool Attributes::hasStackAlignmentAttr() const {
return Bits & Attribute::StackAlignment_i; return Attrs.hasAttribute(Attribute::StackAlignment_i);
} }
bool Attributes::hasStackProtectAttr() const { bool Attributes::hasStackProtectAttr() const {
return Bits & Attribute::StackProtect_i; return Attrs.hasAttribute(Attribute::StackProtect_i);
} }
bool Attributes::hasStackProtectReqAttr() const { bool Attributes::hasStackProtectReqAttr() const {
return Bits & Attribute::StackProtectReq_i; return Attrs.hasAttribute(Attribute::StackProtectReq_i);
} }
bool Attributes::hasStructRetAttr() const { bool Attributes::hasStructRetAttr() const {
return Bits & Attribute::StructRet_i; return Attrs.hasAttribute(Attribute::StructRet_i);
} }
bool Attributes::hasUWTableAttr() const { bool Attributes::hasUWTableAttr() const {
return Bits & Attribute::UWTable_i; return Attrs.hasAttribute(Attribute::UWTable_i);
} }
bool Attributes::hasZExtAttr() const { bool Attributes::hasZExtAttr() const {
return Bits & Attribute::ZExt_i; return Attrs.hasAttribute(Attribute::ZExt_i);
} }
/// This returns the alignment field of an attribute as a byte alignment value. /// This returns the alignment field of an attribute as a byte alignment value.
unsigned Attributes::getAlignment() const { unsigned Attributes::getAlignment() const {
if (!hasAlignmentAttr()) if (!hasAlignmentAttr())
return 0; return 0;
return 1U << (((Bits & Attribute::Alignment_i) >> 16) - 1); return 1U << ((Attrs.getAlignment() >> 16) - 1);
} }
/// This returns the stack alignment field of an attribute as a byte alignment /// This returns the stack alignment field of an attribute as a byte alignment
@ -125,32 +154,36 @@ unsigned Attributes::getAlignment() const {
unsigned Attributes::getStackAlignment() const { unsigned Attributes::getStackAlignment() const {
if (!hasStackAlignmentAttr()) if (!hasStackAlignmentAttr())
return 0; return 0;
return 1U << (((Bits & Attribute::StackAlignment_i) >> 26) - 1); return 1U << ((Attrs.getStackAlignment() >> 26) - 1);
} }
bool Attributes::isEmptyOrSingleton() const { bool Attributes::isEmptyOrSingleton() const {
return (Bits & (Bits - 1)) == 0; return Attrs.isEmptyOrSingleton();
} }
Attributes Attributes::operator | (const Attributes &Attrs) const { Attributes Attributes::operator | (const Attributes &A) const {
return Attributes(Bits | Attrs.Bits); return Attributes(Raw() | A.Raw());
} }
Attributes Attributes::operator & (const Attributes &Attrs) const { Attributes Attributes::operator & (const Attributes &A) const {
return Attributes(Bits & Attrs.Bits); return Attributes(Raw() & A.Raw());
} }
Attributes Attributes::operator ^ (const Attributes &Attrs) const { Attributes Attributes::operator ^ (const Attributes &A) const {
return Attributes(Bits ^ Attrs.Bits); return Attributes(Raw() ^ A.Raw());
} }
Attributes &Attributes::operator |= (const Attributes &Attrs) { Attributes &Attributes::operator |= (const Attributes &A) {
Bits |= Attrs.Bits; Attrs.Bits |= A.Raw();
return *this; return *this;
} }
Attributes &Attributes::operator &= (const Attributes &Attrs) { Attributes &Attributes::operator &= (const Attributes &A) {
Bits &= Attrs.Bits; Attrs.Bits &= A.Raw();
return *this; return *this;
} }
Attributes Attributes::operator ~ () const { Attributes Attributes::operator ~ () const {
return Attributes(~Bits); return Attributes(~Raw());
}
uint64_t Attributes::Raw() const {
return Attrs.Bits;
} }
Attributes Attributes::typeIncompatible(Type *Ty) { Attributes Attributes::typeIncompatible(Type *Ty) {
@ -336,34 +369,108 @@ void Attributes::Builder::addStackAlignmentAttr(unsigned Align) {
Bits |= (Log2_32(Align) + 1) << 26; Bits |= (Log2_32(Align) + 1) << 26;
} }
void Attributes::Builder::removeAddressSafetyAttr() {
Bits &= ~Attribute::AddressSafety_i;
}
void Attributes::Builder::removeAlwaysInlineAttr() {
Bits &= ~Attribute::AlwaysInline_i;
}
void Attributes::Builder::removeByValAttr() {
Bits &= ~Attribute::ByVal_i;
}
void Attributes::Builder::removeInlineHintAttr() {
Bits &= ~Attribute::InlineHint_i;
}
void Attributes::Builder::removeInRegAttr() {
Bits &= ~Attribute::InReg_i;
}
void Attributes::Builder::removeNakedAttr() {
Bits &= ~Attribute::Naked_i;
}
void Attributes::Builder::removeNestAttr() {
Bits &= ~Attribute::Nest_i;
}
void Attributes::Builder::removeNoAliasAttr() {
Bits &= ~Attribute::NoAlias_i;
}
void Attributes::Builder::removeNoCaptureAttr() {
Bits &= ~Attribute::NoCapture_i;
}
void Attributes::Builder::removeNoImplicitFloatAttr() {
Bits &= ~Attribute::NoImplicitFloat_i;
}
void Attributes::Builder::removeNoInlineAttr() {
Bits &= ~Attribute::NoInline_i;
}
void Attributes::Builder::removeNonLazyBindAttr() {
Bits &= ~Attribute::NonLazyBind_i;
}
void Attributes::Builder::removeNoRedZoneAttr() {
Bits &= ~Attribute::NoRedZone_i;
}
void Attributes::Builder::removeNoReturnAttr() {
Bits &= ~Attribute::NoReturn_i;
}
void Attributes::Builder::removeNoUnwindAttr() {
Bits &= ~Attribute::NoUnwind_i;
}
void Attributes::Builder::removeOptimizeForSizeAttr() {
Bits &= ~Attribute::OptimizeForSize_i;
}
void Attributes::Builder::removeReadNoneAttr() {
Bits &= ~Attribute::ReadNone_i;
}
void Attributes::Builder::removeReadOnlyAttr() {
Bits &= ~Attribute::ReadOnly_i;
}
void Attributes::Builder::removeReturnsTwiceAttr() {
Bits &= ~Attribute::ReturnsTwice_i;
}
void Attributes::Builder::removeSExtAttr() {
Bits &= ~Attribute::SExt_i;
}
void Attributes::Builder::removeStackProtectAttr() {
Bits &= ~Attribute::StackProtect_i;
}
void Attributes::Builder::removeStackProtectReqAttr() {
Bits &= ~Attribute::StackProtectReq_i;
}
void Attributes::Builder::removeStructRetAttr() {
Bits &= ~Attribute::StructRet_i;
}
void Attributes::Builder::removeUWTableAttr() {
Bits &= ~Attribute::UWTable_i;
}
void Attributes::Builder::removeZExtAttr() {
Bits &= ~Attribute::ZExt_i;
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// AttributeImpl Definition // AttributeImpl Definition
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
Attributes::Attributes(AttributesImpl *A) : Bits(0) {} bool AttributesImpl::hasAttribute(uint64_t A) const {
return (Bits & A) != 0;
}
Attributes Attributes::get(LLVMContext &Context, Attributes::Builder &B) { bool AttributesImpl::hasAttributes() const {
// If there are no attributes, return an empty Attributes class. return Bits != 0;
if (B.Bits == 0) }
return Attributes();
// Otherwise, build a key to look up the existing attributes. bool AttributesImpl::hasAttributes(const Attributes &A) const {
LLVMContextImpl *pImpl = Context.pImpl; return Bits & A.Raw(); // FIXME: Raw() won't work here in the future.
FoldingSetNodeID ID; }
ID.AddInteger(B.Bits);
void *InsertPoint; uint64_t AttributesImpl::getAlignment() const {
AttributesImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); return Bits & Attribute::Alignment_i;
}
if (!PA) { uint64_t AttributesImpl::getStackAlignment() const {
// If we didn't find any existing attributes of the same shape then create a return Bits & Attribute::StackAlignment_i;
// new one and insert it. }
PA = new AttributesImpl(B.Bits);
pImpl->AttrsSet.InsertNode(PA, InsertPoint);
}
// Return the AttributesList that we found or created. bool AttributesImpl::isEmptyOrSingleton() const {
return Attributes(PA); return (Bits & (Bits - 1)) == 0;
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//

View File

@ -16,9 +16,9 @@
#define LLVM_LLVMCONTEXT_IMPL_H #define LLVM_LLVMCONTEXT_IMPL_H
#include "llvm/LLVMContext.h" #include "llvm/LLVMContext.h"
#include "AttributesImpl.h"
#include "ConstantsContext.h" #include "ConstantsContext.h"
#include "LeaksContext.h" #include "LeaksContext.h"
#include "llvm/AttributesImpl.h"
#include "llvm/Constants.h" #include "llvm/Constants.h"
#include "llvm/DerivedTypes.h" #include "llvm/DerivedTypes.h"
#include "llvm/Metadata.h" #include "llvm/Metadata.h"