aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Attributes.cpp
diff options
context:
space:
mode:
authorBradley Smith <bradley.smith@arm.com>2021-03-03 13:53:30 +0000
committerBradley Smith <bradley.smith@arm.com>2021-03-22 12:05:06 +0000
commit48f5a392cb73d99a58f01448926f6964ab5b0d0a (patch)
tree50bae4942a4fa20a48bfb446dd2b2e065f550a83 /llvm/lib/IR/Attributes.cpp
parent2bbc9bccf095b92b3ed1ab9669fab8a7dc96ee6d (diff)
downloadllvm-48f5a392cb73d99a58f01448926f6964ab5b0d0a.zip
llvm-48f5a392cb73d99a58f01448926f6964ab5b0d0a.tar.gz
llvm-48f5a392cb73d99a58f01448926f6964ab5b0d0a.tar.bz2
[IR] Add vscale_range IR function attribute
This attribute represents the minimum and maximum values vscale can take. For now this attribute is not hooked up to anything during codegen, this will be added in the future when such codegen is considered stable. Additionally hook up the -msve-vector-bits=<x> clang option to emit this attribute. Differential Revision: https://reviews.llvm.org/D98030
Diffstat (limited to 'llvm/lib/IR/Attributes.cpp')
-rw-r--r--llvm/lib/IR/Attributes.cpp102
1 files changed, 100 insertions, 2 deletions
diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp
index 18c2f3a..4c087c9 100644
--- a/llvm/lib/IR/Attributes.cpp
+++ b/llvm/lib/IR/Attributes.cpp
@@ -78,6 +78,17 @@ unpackAllocSizeArgs(uint64_t Num) {
return std::make_pair(ElemSizeArg, NumElemsArg);
}
+static uint64_t packVScaleRangeArgs(unsigned MinValue, unsigned MaxValue) {
+ return uint64_t(MinValue) << 32 | MaxValue;
+}
+
+static std::pair<unsigned, unsigned> unpackVScaleRangeArgs(uint64_t Value) {
+ unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
+ unsigned MinValue = Value >> 32;
+
+ return std::make_pair(MinValue, MaxValue);
+}
+
Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
uint64_t Val) {
LLVMContextImpl *pImpl = Context.pImpl;
@@ -192,6 +203,12 @@ Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
}
+Attribute Attribute::getWithVScaleRangeArgs(LLVMContext &Context,
+ unsigned MinValue,
+ unsigned MaxValue) {
+ return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
+}
+
Attribute::AttrKind Attribute::getAttrKindFromName(StringRef AttrName) {
return StringSwitch<Attribute::AttrKind>(AttrName)
#define GET_ATTR_NAMES
@@ -220,7 +237,8 @@ bool Attribute::doesAttrKindHaveArgument(Attribute::AttrKind AttrKind) {
AttrKind == Attribute::StackAlignment ||
AttrKind == Attribute::Dereferenceable ||
AttrKind == Attribute::AllocSize ||
- AttrKind == Attribute::DereferenceableOrNull;
+ AttrKind == Attribute::DereferenceableOrNull ||
+ AttrKind == Attribute::VScaleRange;
}
bool Attribute::isExistingAttribute(StringRef Name) {
@@ -328,6 +346,12 @@ std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
return unpackAllocSizeArgs(pImpl->getValueAsInt());
}
+std::pair<unsigned, unsigned> Attribute::getVScaleRangeArgs() const {
+ assert(hasAttribute(Attribute::VScaleRange) &&
+ "Trying to get vscale args from non-vscale attribute");
+ return unpackVScaleRangeArgs(pImpl->getValueAsInt());
+}
+
std::string Attribute::getAsString(bool InAttrGrp) const {
if (!pImpl) return {};
@@ -536,6 +560,18 @@ std::string Attribute::getAsString(bool InAttrGrp) const {
return Result;
}
+ if (hasAttribute(Attribute::VScaleRange)) {
+ unsigned MinValue, MaxValue;
+ std::tie(MinValue, MaxValue) = getVScaleRangeArgs();
+
+ std::string Result = "vscale_range(";
+ Result += utostr(MinValue);
+ Result += ',';
+ Result += utostr(MaxValue);
+ Result += ')';
+ return Result;
+ }
+
// Convert target-dependent attributes to strings of the form:
//
// "kind"
@@ -778,6 +814,11 @@ std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
: std::pair<unsigned, Optional<unsigned>>(0, 0);
}
+std::pair<unsigned, unsigned> AttributeSet::getVScaleRangeArgs() const {
+ return SetNode ? SetNode->getVScaleRangeArgs()
+ : std::pair<unsigned, unsigned>(0, 0);
+}
+
std::string AttributeSet::getAsString(bool InAttrGrp) const {
return SetNode ? SetNode->getAsString(InAttrGrp) : "";
}
@@ -895,6 +936,11 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
break;
}
+ case Attribute::VScaleRange: {
+ auto A = B.getVScaleRangeArgs();
+ Attr = Attribute::getWithVScaleRangeArgs(C, A.first, A.second);
+ break;
+ }
default:
Attr = Attribute::get(C, Kind);
}
@@ -994,6 +1040,12 @@ AttributeSetNode::getAllocSizeArgs() const {
return std::make_pair(0, 0);
}
+std::pair<unsigned, unsigned> AttributeSetNode::getVScaleRangeArgs() const {
+ if (auto A = findEnumAttribute(Attribute::VScaleRange))
+ return A->getVScaleRangeArgs();
+ return std::make_pair(0, 0);
+}
+
std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
std::string Str;
for (iterator I = begin(), E = end(); I != E; ++I) {
@@ -1427,6 +1479,14 @@ AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
return addAttributes(C, Index, B);
}
+AttributeList AttributeList::addVScaleRangeAttr(LLVMContext &C, unsigned Index,
+ unsigned MinValue,
+ unsigned MaxValue) {
+ AttrBuilder B;
+ B.addVScaleRangeAttr(MinValue, MaxValue);
+ return addAttributes(C, Index, B);
+}
+
//===----------------------------------------------------------------------===//
// AttributeList Accessor Methods
//===----------------------------------------------------------------------===//
@@ -1524,6 +1584,11 @@ AttributeList::getAllocSizeArgs(unsigned Index) const {
return getAttributes(Index).getAllocSizeArgs();
}
+std::pair<unsigned, unsigned>
+AttributeList::getVScaleRangeArgs(unsigned Index) const {
+ return getAttributes(Index).getVScaleRangeArgs();
+}
+
std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
return getAttributes(Index).getAsString(InAttrGrp);
}
@@ -1587,6 +1652,7 @@ void AttrBuilder::clear() {
StackAlignment.reset();
DerefBytes = DerefOrNullBytes = 0;
AllocSizeArgs = 0;
+ VScaleRangeArgs = 0;
ByValType = nullptr;
StructRetType = nullptr;
ByRefType = nullptr;
@@ -1620,6 +1686,8 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
else if (Kind == Attribute::AllocSize)
AllocSizeArgs = Attr.getValueAsInt();
+ else if (Kind == Attribute::VScaleRange)
+ VScaleRangeArgs = Attr.getValueAsInt();
return *this;
}
@@ -1650,6 +1718,8 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
DerefOrNullBytes = 0;
else if (Val == Attribute::AllocSize)
AllocSizeArgs = 0;
+ else if (Val == Attribute::VScaleRange)
+ VScaleRangeArgs = 0;
return *this;
}
@@ -1670,6 +1740,10 @@ std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
return unpackAllocSizeArgs(AllocSizeArgs);
}
+std::pair<unsigned, unsigned> AttrBuilder::getVScaleRangeArgs() const {
+ return unpackVScaleRangeArgs(VScaleRangeArgs);
+}
+
AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
if (!Align)
return *this;
@@ -1726,6 +1800,23 @@ AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
return *this;
}
+AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
+ unsigned MaxValue) {
+ return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
+}
+
+AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
+ // (0, 0) is not present hence ignore this case
+ if (RawArgs == 0)
+ return *this;
+
+ Attrs[Attribute::VScaleRange] = true;
+ // Reuse existing machinery to store this as a single 64-bit integer so we can
+ // save a few bytes over using a pair<unsigned, unsigned>.
+ VScaleRangeArgs = RawArgs;
+ return *this;
+}
+
AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
Attrs[Attribute::ByVal] = true;
ByValType = Ty;
@@ -1779,6 +1870,9 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
if (!PreallocatedType)
PreallocatedType = B.PreallocatedType;
+ if (!VScaleRangeArgs)
+ VScaleRangeArgs = B.VScaleRangeArgs;
+
Attrs |= B.Attrs;
for (const auto &I : B.td_attrs())
@@ -1816,6 +1910,9 @@ AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
if (B.PreallocatedType)
PreallocatedType = nullptr;
+ if (B.VScaleRangeArgs)
+ VScaleRangeArgs = 0;
+
Attrs &= ~B.Attrs;
for (const auto &I : B.td_attrs())
@@ -1876,7 +1973,8 @@ bool AttrBuilder::operator==(const AttrBuilder &B) const {
return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
DerefBytes == B.DerefBytes && ByValType == B.ByValType &&
StructRetType == B.StructRetType && ByRefType == B.ByRefType &&
- PreallocatedType == B.PreallocatedType;
+ PreallocatedType == B.PreallocatedType &&
+ VScaleRangeArgs == B.VScaleRangeArgs;
}
//===----------------------------------------------------------------------===//