diff options
author | Andreas Jonson <andjo403@hotmail.com> | 2024-03-09 12:47:43 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-03-09 19:47:43 +0800 |
commit | 40282674e9808baeb9b88afdd3cbd7da46825544 (patch) | |
tree | 9b7da27d9aa58e5e15bac42c0cb640e6fccf38de /llvm/lib/IR/Attributes.cpp | |
parent | 11cd2a33f1a80c1b8ad1968c1316204b172e4937 (diff) | |
download | llvm-40282674e9808baeb9b88afdd3cbd7da46825544.zip llvm-40282674e9808baeb9b88afdd3cbd7da46825544.tar.gz llvm-40282674e9808baeb9b88afdd3cbd7da46825544.tar.bz2 |
Reapply [IR] Add new Range attribute using new ConstantRange Attribute type (#84617)
The only change from https://github.com/llvm/llvm-project/pull/83171 is the
change of the allocator so the destructor is called for
ConstantRangeAttributeImpl.
reverts https://github.com/llvm/llvm-project/pull/84549
Diffstat (limited to 'llvm/lib/IR/Attributes.cpp')
-rw-r--r-- | llvm/lib/IR/Attributes.cpp | 81 |
1 files changed, 79 insertions, 2 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 00acbbe..b2d9992c 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -24,6 +24,7 @@ #include "llvm/ADT/StringSwitch.h" #include "llvm/Config/llvm-config.h" #include "llvm/IR/AttributeMask.h" +#include "llvm/IR/ConstantRange.h" #include "llvm/IR/Function.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Type.h" @@ -165,6 +166,31 @@ Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, return Attribute(PA); } +Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, + const ConstantRange &CR) { + assert(Attribute::isConstantRangeAttrKind(Kind) && + "Not a ConstantRange attribute"); + LLVMContextImpl *pImpl = Context.pImpl; + FoldingSetNodeID ID; + ID.AddInteger(Kind); + ID.AddInteger(CR.getLower()); + ID.AddInteger(CR.getUpper()); + + 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 (pImpl->ConstantRangeAttributeAlloc.Allocate()) + ConstantRangeAttributeImpl(Kind, CR); + pImpl->AttrsSet.InsertNode(PA, InsertPoint); + } + + // 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()); @@ -287,9 +313,14 @@ bool Attribute::isTypeAttribute() const { return pImpl && pImpl->isTypeAttribute(); } +bool Attribute::isConstantRangeAttribute() const { + return pImpl && pImpl->isConstantRangeAttribute(); +} + Attribute::AttrKind Attribute::getKindAsEnum() const { if (!pImpl) return None; - assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) && + assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute() || + isConstantRangeAttribute()) && "Invalid attribute type to get the kind as an enum!"); return pImpl->getKindAsEnum(); } @@ -329,6 +360,11 @@ Type *Attribute::getValueAsType() const { return pImpl->getValueAsType(); } +ConstantRange Attribute::getValueAsConstantRange() const { + assert(isConstantRangeAttribute() && + "Invalid attribute type to get the value as a ConstantRange!"); + return pImpl->getValueAsConstantRange(); +} bool Attribute::hasAttribute(AttrKind Kind) const { return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None); @@ -408,6 +444,12 @@ FPClassTest Attribute::getNoFPClass() const { return static_cast<FPClassTest>(pImpl->getValueAsInt()); } +ConstantRange Attribute::getRange() const { + assert(hasAttribute(Attribute::Range) && + "Trying to get range args from non-range attribute"); + return pImpl->getValueAsConstantRange(); +} + static const char *getModRefStr(ModRefInfo MR) { switch (MR) { case ModRefInfo::NoModRef: @@ -562,6 +604,18 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return Result; } + if (hasAttribute(Attribute::Range)) { + std::string Result; + raw_string_ostream OS(Result); + ConstantRange CR = getValueAsConstantRange(); + OS << "range("; + OS << "i" << CR.getBitWidth() << " "; + OS << CR.getLower() << ", " << CR.getUpper(); + OS << ")"; + OS.flush(); + return Result; + } + // Convert target-dependent attributes to strings of the form: // // "kind" @@ -651,7 +705,8 @@ bool AttributeImpl::hasAttribute(StringRef Kind) const { } Attribute::AttrKind AttributeImpl::getKindAsEnum() const { - assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute()); + assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute() || + isConstantRangeAttribute()); return static_cast<const EnumAttributeImpl *>(this)->getEnumKind(); } @@ -680,6 +735,12 @@ Type *AttributeImpl::getValueAsType() const { return static_cast<const TypeAttributeImpl *>(this)->getTypeValue(); } +ConstantRange AttributeImpl::getValueAsConstantRange() const { + assert(isConstantRangeAttribute()); + return static_cast<const ConstantRangeAttributeImpl *>(this) + ->getConstantRangeValue(); +} + bool AttributeImpl::operator<(const AttributeImpl &AI) const { if (this == &AI) return false; @@ -693,6 +754,7 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const { return getKindAsEnum() < AI.getKindAsEnum(); assert(!AI.isEnumAttribute() && "Non-unique attribute"); assert(!AI.isTypeAttribute() && "Comparison of types would be unstable"); + assert(!AI.isConstantRangeAttribute() && "Unclear how to compare ranges"); // TODO: Is this actually needed? assert(AI.isIntAttribute() && "Only possibility left"); return getValueAsInt() < AI.getValueAsInt(); @@ -1881,6 +1943,15 @@ AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) { return addTypeAttr(Attribute::InAlloca, Ty); } +AttrBuilder &AttrBuilder::addConstantRangeAttr(Attribute::AttrKind Kind, + const ConstantRange &CR) { + return addAttribute(Attribute::get(Ctx, Kind, CR)); +} + +AttrBuilder &AttrBuilder::addRangeAttr(const ConstantRange &CR) { + return addConstantRangeAttr(Attribute::Range, CR); +} + 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()) @@ -1952,6 +2023,12 @@ AttributeMask AttributeFuncs::typeIncompatible(Type *Ty, Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt); } + if (!Ty->isIntOrIntVectorTy()) { + // Attributes that only apply to integers or vector of integers. + if (ASK & ASK_SAFE_TO_DROP) + Incompatible.addAttribute(Attribute::Range); + } + if (!Ty->isPointerTy()) { // Attributes that only apply to pointers. if (ASK & ASK_SAFE_TO_DROP) |