aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Attributes.cpp
diff options
context:
space:
mode:
authorAndreas Jonson <andjo403@hotmail.com>2024-03-09 12:47:43 +0100
committerGitHub <noreply@github.com>2024-03-09 19:47:43 +0800
commit40282674e9808baeb9b88afdd3cbd7da46825544 (patch)
tree9b7da27d9aa58e5e15bac42c0cb640e6fccf38de /llvm/lib/IR/Attributes.cpp
parent11cd2a33f1a80c1b8ad1968c1316204b172e4937 (diff)
downloadllvm-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.cpp81
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)