diff options
Diffstat (limited to 'llvm/lib/IR/Attributes.cpp')
| -rw-r--r-- | llvm/lib/IR/Attributes.cpp | 90 |
1 files changed, 87 insertions, 3 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 7a3c9a99ee4d..b2fdd218e5d4 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -25,6 +25,7 @@ #include "llvm/Config/llvm-config.h" #include "llvm/IR/AttributeMask.h" #include "llvm/IR/ConstantRange.h" +#include "llvm/IR/ConstantRangeList.h" #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Type.h" @@ -191,6 +192,43 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, return Attribute(PA); } +Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, + ArrayRef<ConstantRange> Val) { + assert(Attribute::isConstantRangeListAttrKind(Kind) && + "Not a ConstantRangeList attribute"); + LLVMContextImpl *pImpl = Context.pImpl; + FoldingSetNodeID ID; + ID.AddInteger(Kind); + ID.AddInteger(Val.size()); + for (auto &CR : Val) { + CR.getLower().Profile(ID); + CR.getUpper().Profile(ID); + } + + 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. + // ConstantRangeListAttributeImpl is a dynamically sized class and cannot + // use SpecificBumpPtrAllocator. Instead, we use normal Alloc for + // allocation and record the allocated pointer in + // `ConstantRangeListAttributes`. LLVMContext destructor will call the + // destructor of the allocated pointer explicitly. + void *Mem = pImpl->Alloc.Allocate( + ConstantRangeListAttributeImpl::totalSizeToAlloc(Val), + alignof(ConstantRangeListAttributeImpl)); + PA = new (Mem) ConstantRangeListAttributeImpl(Kind, Val); + pImpl->AttrsSet.InsertNode(PA, InsertPoint); + pImpl->ConstantRangeListAttributes.push_back( + reinterpret_cast<ConstantRangeListAttributeImpl *>(PA)); + } + + // Return the Attribute that we found or created. + return Attribute(PA); +} + Attribute Attribute::getWithAlignment(LLVMContext &Context, Align A) { assert(A <= llvm::Value::MaximumAlignment && "Alignment too large."); return get(Context, Alignment, A.value()); @@ -317,10 +355,14 @@ bool Attribute::isConstantRangeAttribute() const { return pImpl && pImpl->isConstantRangeAttribute(); } +bool Attribute::isConstantRangeListAttribute() const { + return pImpl && pImpl->isConstantRangeListAttribute(); +} + Attribute::AttrKind Attribute::getKindAsEnum() const { if (!pImpl) return None; assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute() || - isConstantRangeAttribute()) && + isConstantRangeAttribute() || isConstantRangeListAttribute()) && "Invalid attribute type to get the kind as an enum!"); return pImpl->getKindAsEnum(); } @@ -366,6 +408,12 @@ const ConstantRange &Attribute::getValueAsConstantRange() const { return pImpl->getValueAsConstantRange(); } +ArrayRef<ConstantRange> Attribute::getValueAsConstantRangeList() const { + assert(isConstantRangeListAttribute() && + "Invalid attribute type to get the value as a ConstantRangeList!"); + return pImpl->getValueAsConstantRangeList(); +} + bool Attribute::hasAttribute(AttrKind Kind) const { return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None); } @@ -450,6 +498,12 @@ const ConstantRange &Attribute::getRange() const { return pImpl->getValueAsConstantRange(); } +ArrayRef<ConstantRange> Attribute::getInitializes() const { + assert(hasAttribute(Attribute::Initializes) && + "Trying to get initializes attr from non-ConstantRangeList attribute"); + return pImpl->getValueAsConstantRangeList(); +} + static const char *getModRefStr(ModRefInfo MR) { switch (MR) { case ModRefInfo::NoModRef: @@ -611,6 +665,17 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return Result; } + if (hasAttribute(Attribute::Initializes)) { + std::string Result; + raw_string_ostream OS(Result); + ConstantRangeList CRL = getInitializes(); + OS << "initializes("; + CRL.print(OS); + OS << ")"; + OS.flush(); + return Result; + } + // Convert target-dependent attributes to strings of the form: // // "kind" @@ -701,7 +766,7 @@ bool AttributeImpl::hasAttribute(StringRef Kind) const { Attribute::AttrKind AttributeImpl::getKindAsEnum() const { assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute() || - isConstantRangeAttribute()); + isConstantRangeAttribute() || isConstantRangeListAttribute()); return static_cast<const EnumAttributeImpl *>(this)->getEnumKind(); } @@ -736,6 +801,12 @@ const ConstantRange &AttributeImpl::getValueAsConstantRange() const { ->getConstantRangeValue(); } +ArrayRef<ConstantRange> AttributeImpl::getValueAsConstantRangeList() const { + assert(isConstantRangeListAttribute()); + return static_cast<const ConstantRangeListAttributeImpl *>(this) + ->getConstantRangeListValue(); +} + bool AttributeImpl::operator<(const AttributeImpl &AI) const { if (this == &AI) return false; @@ -750,6 +821,8 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const { assert(!AI.isEnumAttribute() && "Non-unique attribute"); assert(!AI.isTypeAttribute() && "Comparison of types would be unstable"); assert(!AI.isConstantRangeAttribute() && "Unclear how to compare ranges"); + assert(!AI.isConstantRangeListAttribute() && + "Unclear how to compare range list"); // TODO: Is this actually needed? assert(AI.isIntAttribute() && "Only possibility left"); return getValueAsInt() < AI.getValueAsInt(); @@ -1954,6 +2027,16 @@ AttrBuilder &AttrBuilder::addRangeAttr(const ConstantRange &CR) { return addConstantRangeAttr(Attribute::Range, CR); } +AttrBuilder & +AttrBuilder::addConstantRangeListAttr(Attribute::AttrKind Kind, + ArrayRef<ConstantRange> Val) { + return addAttribute(Attribute::get(Ctx, Kind, Val)); +} + +AttrBuilder &AttrBuilder::addInitializesAttr(const ConstantRangeList &CRL) { + return addConstantRangeListAttr(Attribute::Initializes, CRL.rangesRef()); +} + AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { // TODO: Could make this O(n) as we're merging two sorted lists. for (const auto &I : B.attrs()) @@ -2042,7 +2125,8 @@ AttributeMask AttributeFuncs::typeIncompatible(Type *Ty, .addAttribute(Attribute::Dereferenceable) .addAttribute(Attribute::DereferenceableOrNull) .addAttribute(Attribute::Writable) - .addAttribute(Attribute::DeadOnUnwind); + .addAttribute(Attribute::DeadOnUnwind) + .addAttribute(Attribute::Initializes); if (ASK & ASK_UNSAFE_TO_DROP) Incompatible.addAttribute(Attribute::Nest) .addAttribute(Attribute::SwiftError) |
