diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-08-20 20:50:12 +0000 |
commit | e6d1592492a3a379186bfb02bd0f4eda0669c0d5 (patch) | |
tree | 599ab169a01f1c86eda9adc774edaedde2f2db5b /lib/IR/Attributes.cpp | |
parent | 1a56a5ead7a2e84bee8240f5f6b033b5f1707154 (diff) |
Notes
Diffstat (limited to 'lib/IR/Attributes.cpp')
-rw-r--r-- | lib/IR/Attributes.cpp | 150 |
1 files changed, 136 insertions, 14 deletions
diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index ff46debb7a9e..bb90bcd7dd74 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -1,9 +1,8 @@ //===- Attributes.cpp - Implement AttributesList --------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // @@ -122,6 +121,27 @@ Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) { return Attribute(PA); } +Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind, + Type *Ty) { + LLVMContextImpl *pImpl = Context.pImpl; + FoldingSetNodeID ID; + ID.AddInteger(Kind); + ID.AddPointer(Ty); + + 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 TypeAttributeImpl(Kind, Ty); + pImpl->AttrsSet.InsertNode(PA, InsertPoint); + } + + // Return the Attribute that we found or created. + return Attribute(PA); +} + Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) { assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); assert(Align <= 0x40000000 && "Alignment too large."); @@ -147,6 +167,10 @@ Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context, return get(Context, DereferenceableOrNull, Bytes); } +Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) { + return get(Context, ByVal, Ty); +} + Attribute Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const Optional<unsigned> &NumElemsArg) { @@ -171,9 +195,13 @@ bool Attribute::isStringAttribute() const { return pImpl && pImpl->isStringAttribute(); } +bool Attribute::isTypeAttribute() const { + return pImpl && pImpl->isTypeAttribute(); +} + Attribute::AttrKind Attribute::getKindAsEnum() const { if (!pImpl) return None; - assert((isEnumAttribute() || isIntAttribute()) && + assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) && "Invalid attribute type to get the kind as an enum!"); return pImpl->getKindAsEnum(); } @@ -199,6 +227,14 @@ StringRef Attribute::getValueAsString() const { return pImpl->getValueAsString(); } +Type *Attribute::getValueAsType() const { + if (!pImpl) return {}; + assert(isTypeAttribute() && + "Invalid attribute type to get the value as a type!"); + return pImpl->getValueAsType(); +} + + bool Attribute::hasAttribute(AttrKind Kind) const { return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None); } @@ -247,14 +283,14 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "sanitize_address"; if (hasAttribute(Attribute::SanitizeHWAddress)) return "sanitize_hwaddress"; + if (hasAttribute(Attribute::SanitizeMemTag)) + return "sanitize_memtag"; if (hasAttribute(Attribute::AlwaysInline)) return "alwaysinline"; if (hasAttribute(Attribute::ArgMemOnly)) return "argmemonly"; if (hasAttribute(Attribute::Builtin)) return "builtin"; - if (hasAttribute(Attribute::ByVal)) - return "byval"; if (hasAttribute(Attribute::Convergent)) return "convergent"; if (hasAttribute(Attribute::SwiftError)) @@ -287,6 +323,8 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "nocapture"; if (hasAttribute(Attribute::NoDuplicate)) return "noduplicate"; + if (hasAttribute(Attribute::NoFree)) + return "nofree"; if (hasAttribute(Attribute::NoImplicitFloat)) return "noimplicitfloat"; if (hasAttribute(Attribute::NoInline)) @@ -299,6 +337,10 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "noredzone"; if (hasAttribute(Attribute::NoReturn)) return "noreturn"; + if (hasAttribute(Attribute::NoSync)) + return "nosync"; + if (hasAttribute(Attribute::WillReturn)) + return "willreturn"; if (hasAttribute(Attribute::NoCfCheck)) return "nocf_check"; if (hasAttribute(Attribute::NoRecurse)) @@ -351,6 +393,21 @@ std::string Attribute::getAsString(bool InAttrGrp) const { return "zeroext"; if (hasAttribute(Attribute::Cold)) return "cold"; + if (hasAttribute(Attribute::ImmArg)) + return "immarg"; + + if (hasAttribute(Attribute::ByVal)) { + std::string Result; + Result += "byval"; + if (Type *Ty = getValueAsType()) { + raw_string_ostream OS(Result); + Result += '('; + Ty->print(OS, false, true); + OS.flush(); + Result += ')'; + } + return Result; + } // FIXME: These should be output like this: // @@ -450,6 +507,8 @@ void IntAttributeImpl::anchor() {} void StringAttributeImpl::anchor() {} +void TypeAttributeImpl::anchor() {} + bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { if (isStringAttribute()) return false; return getKindAsEnum() == A; @@ -461,7 +520,7 @@ bool AttributeImpl::hasAttribute(StringRef Kind) const { } Attribute::AttrKind AttributeImpl::getKindAsEnum() const { - assert(isEnumAttribute() || isIntAttribute()); + assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute()); return static_cast<const EnumAttributeImpl *>(this)->getEnumKind(); } @@ -480,6 +539,11 @@ StringRef AttributeImpl::getValueAsString() const { return static_cast<const StringAttributeImpl *>(this)->getStringValue(); } +Type *AttributeImpl::getValueAsType() const { + assert(isTypeAttribute()); + return static_cast<const TypeAttributeImpl *>(this)->getTypeValue(); +} + bool AttributeImpl::operator<(const AttributeImpl &AI) const { // This sorts the attributes with Attribute::AttrKinds coming first (sorted // relative to their enum value) and then strings. @@ -487,10 +551,23 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const { if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum(); if (AI.isIntAttribute()) return true; if (AI.isStringAttribute()) return true; + if (AI.isTypeAttribute()) return true; + } + + if (isTypeAttribute()) { + if (AI.isEnumAttribute()) return false; + if (AI.isTypeAttribute()) { + assert(getKindAsEnum() != AI.getKindAsEnum() && + "Comparison of types would be unstable"); + return getKindAsEnum() < AI.getKindAsEnum(); + } + if (AI.isIntAttribute()) return true; + if (AI.isStringAttribute()) return true; } if (isIntAttribute()) { if (AI.isEnumAttribute()) return false; + if (AI.isTypeAttribute()) return false; if (AI.isIntAttribute()) { if (getKindAsEnum() == AI.getKindAsEnum()) return getValueAsInt() < AI.getValueAsInt(); @@ -499,7 +576,9 @@ bool AttributeImpl::operator<(const AttributeImpl &AI) const { if (AI.isStringAttribute()) return true; } + assert(isStringAttribute()); if (AI.isEnumAttribute()) return false; + if (AI.isTypeAttribute()) return false; if (AI.isIntAttribute()) return false; if (getKindAsString() == AI.getKindAsString()) return getValueAsString() < AI.getValueAsString(); @@ -607,6 +686,10 @@ uint64_t AttributeSet::getDereferenceableOrNullBytes() const { return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0; } +Type *AttributeSet::getByValType() const { + return SetNode ? SetNode->getByValType() : nullptr; +} + std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const { return SetNode ? SetNode->getAllocSizeArgs() : std::pair<unsigned, Optional<unsigned>>(0, 0); @@ -637,13 +720,18 @@ LLVM_DUMP_METHOD void AttributeSet::dump() const { //===----------------------------------------------------------------------===// AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs) - : AvailableAttrs(0), NumAttrs(Attrs.size()) { + : NumAttrs(Attrs.size()) { // There's memory after the node where we can store the entries in. llvm::copy(Attrs, getTrailingObjects<Attribute>()); + static_assert(Attribute::EndAttrKinds <= + sizeof(AvailableAttrs) * CHAR_BIT, + "Too many attributes"); + for (const auto I : *this) { if (!I.isStringAttribute()) { - AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum(); + Attribute::AttrKind Kind = I.getKindAsEnum(); + AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8); } } } @@ -690,6 +778,9 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) { Attribute Attr; switch (Kind) { + case Attribute::ByVal: + Attr = Attribute::getWithByValType(C, B.getByValType()); + break; case Attribute::Alignment: Attr = Attribute::getWithAlignment(C, B.getAlignment()); break; @@ -759,6 +850,13 @@ unsigned AttributeSetNode::getStackAlignment() const { return 0; } +Type *AttributeSetNode::getByValType() const { + for (const auto I : *this) + if (I.hasAttribute(Attribute::ByVal)) + return I.getValueAsType(); + return 0; +} + uint64_t AttributeSetNode::getDereferenceableBytes() const { for (const auto I : *this) if (I.hasAttribute(Attribute::Dereferenceable)) @@ -805,7 +903,7 @@ static constexpr unsigned attrIdxToArrayIdx(unsigned Index) { AttributeListImpl::AttributeListImpl(LLVMContext &C, ArrayRef<AttributeSet> Sets) - : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) { + : Context(C), NumAttrSets(Sets.size()) { assert(!Sets.empty() && "pointless AttributeListImpl"); // There's memory after the node where we can store the entries in. @@ -818,8 +916,10 @@ AttributeListImpl::AttributeListImpl(LLVMContext &C, static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U, "function should be stored in slot 0"); for (const auto I : Sets[0]) { - if (!I.isStringAttribute()) - AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum(); + if (!I.isStringAttribute()) { + Attribute::AttrKind Kind = I.getKindAsEnum(); + AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8); + } } } @@ -1257,6 +1357,11 @@ unsigned AttributeList::getParamAlignment(unsigned ArgNo) const { return getAttributes(ArgNo + FirstArgIndex).getAlignment(); } +Type *AttributeList::getParamByValType(unsigned Index) const { + return getAttributes(Index+FirstArgIndex).getByValType(); +} + + unsigned AttributeList::getStackAlignment(unsigned Index) const { return getAttributes(Index).getStackAlignment(); } @@ -1335,6 +1440,7 @@ void AttrBuilder::clear() { TargetDepAttrs.clear(); Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0; AllocSizeArgs = 0; + ByValType = nullptr; } AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { @@ -1359,6 +1465,8 @@ AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) { Alignment = Attr.getAlignment(); else if (Kind == Attribute::StackAlignment) StackAlignment = Attr.getStackAlignment(); + else if (Kind == Attribute::ByVal) + ByValType = Attr.getValueAsType(); else if (Kind == Attribute::Dereferenceable) DerefBytes = Attr.getDereferenceableBytes(); else if (Kind == Attribute::DereferenceableOrNull) @@ -1381,6 +1489,8 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { Alignment = 0; else if (Val == Attribute::StackAlignment) StackAlignment = 0; + else if (Val == Attribute::ByVal) + ByValType = nullptr; else if (Val == Attribute::Dereferenceable) DerefBytes = 0; else if (Val == Attribute::DereferenceableOrNull) @@ -1463,6 +1573,12 @@ AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) { return *this; } +AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) { + Attrs[Attribute::ByVal] = true; + ByValType = Ty; + return *this; +} + AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { // FIXME: What if both have alignments, but they don't match?! if (!Alignment) @@ -1480,6 +1596,9 @@ AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) { if (!AllocSizeArgs) AllocSizeArgs = B.AllocSizeArgs; + if (!ByValType) + ByValType = B.ByValType; + Attrs |= B.Attrs; for (auto I : B.td_attrs()) @@ -1505,6 +1624,9 @@ AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) { if (B.AllocSizeArgs) AllocSizeArgs = 0; + if (B.ByValType) + ByValType = nullptr; + Attrs &= ~B.Attrs; for (auto I : B.td_attrs()) @@ -1564,7 +1686,7 @@ bool AttrBuilder::operator==(const AttrBuilder &B) { return false; return Alignment == B.Alignment && StackAlignment == B.StackAlignment && - DerefBytes == B.DerefBytes; + DerefBytes == B.DerefBytes && ByValType == B.ByValType; } //===----------------------------------------------------------------------===// |