diff options
author | Bradley Smith <bradley.smith@arm.com> | 2021-03-03 13:53:30 +0000 |
---|---|---|
committer | Bradley Smith <bradley.smith@arm.com> | 2021-03-22 12:05:06 +0000 |
commit | 48f5a392cb73d99a58f01448926f6964ab5b0d0a (patch) | |
tree | 50bae4942a4fa20a48bfb446dd2b2e065f550a83 /llvm/lib/IR/Attributes.cpp | |
parent | 2bbc9bccf095b92b3ed1ab9669fab8a7dc96ee6d (diff) | |
download | llvm-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.cpp | 102 |
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; } //===----------------------------------------------------------------------===// |