Path: blob/main/contrib/llvm-project/llvm/lib/IR/AttributeImpl.h
35233 views
//===- AttributeImpl.h - Attribute Internals --------------------*- C++ -*-===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7///8/// \file9/// This file defines various helper methods and classes used by10/// LLVMContextImpl for creating and managing attributes.11///12//===----------------------------------------------------------------------===//1314#ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H15#define LLVM_LIB_IR_ATTRIBUTEIMPL_H1617#include "llvm/ADT/ArrayRef.h"18#include "llvm/ADT/DenseMap.h"19#include "llvm/ADT/FoldingSet.h"20#include "llvm/ADT/StringRef.h"21#include "llvm/IR/Attributes.h"22#include "llvm/IR/ConstantRange.h"23#include "llvm/IR/ConstantRangeList.h"24#include "llvm/Support/TrailingObjects.h"25#include <cassert>26#include <cstddef>27#include <cstdint>28#include <optional>29#include <string>30#include <utility>3132namespace llvm {3334class LLVMContext;35class Type;3637//===----------------------------------------------------------------------===//38/// \class39/// This class represents a single, uniqued attribute. That attribute40/// could be a single enum, a tuple, or a string.41class AttributeImpl : public FoldingSetNode {42unsigned char KindID; ///< Holds the AttrEntryKind of the attribute4344protected:45enum AttrEntryKind {46EnumAttrEntry,47IntAttrEntry,48StringAttrEntry,49TypeAttrEntry,50ConstantRangeAttrEntry,51ConstantRangeListAttrEntry,52};5354AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {}5556public:57// AttributesImpl is uniqued, these should not be available.58AttributeImpl(const AttributeImpl &) = delete;59AttributeImpl &operator=(const AttributeImpl &) = delete;6061bool isEnumAttribute() const { return KindID == EnumAttrEntry; }62bool isIntAttribute() const { return KindID == IntAttrEntry; }63bool isStringAttribute() const { return KindID == StringAttrEntry; }64bool isTypeAttribute() const { return KindID == TypeAttrEntry; }65bool isConstantRangeAttribute() const {66return KindID == ConstantRangeAttrEntry;67}68bool isConstantRangeListAttribute() const {69return KindID == ConstantRangeListAttrEntry;70}7172bool hasAttribute(Attribute::AttrKind A) const;73bool hasAttribute(StringRef Kind) const;7475Attribute::AttrKind getKindAsEnum() const;76uint64_t getValueAsInt() const;77bool getValueAsBool() const;7879StringRef getKindAsString() const;80StringRef getValueAsString() const;8182Type *getValueAsType() const;8384const ConstantRange &getValueAsConstantRange() const;8586ArrayRef<ConstantRange> getValueAsConstantRangeList() const;8788/// Used when sorting the attributes.89bool operator<(const AttributeImpl &AI) const;9091void Profile(FoldingSetNodeID &ID) const {92if (isEnumAttribute())93Profile(ID, getKindAsEnum());94else if (isIntAttribute())95Profile(ID, getKindAsEnum(), getValueAsInt());96else if (isStringAttribute())97Profile(ID, getKindAsString(), getValueAsString());98else if (isTypeAttribute())99Profile(ID, getKindAsEnum(), getValueAsType());100else if (isConstantRangeAttribute())101Profile(ID, getKindAsEnum(), getValueAsConstantRange());102else103Profile(ID, getKindAsEnum(), getValueAsConstantRangeList());104}105106static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind) {107assert(Attribute::isEnumAttrKind(Kind) && "Expected enum attribute");108ID.AddInteger(Kind);109}110111static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,112uint64_t Val) {113assert(Attribute::isIntAttrKind(Kind) && "Expected int attribute");114ID.AddInteger(Kind);115ID.AddInteger(Val);116}117118static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) {119ID.AddString(Kind);120if (!Values.empty()) ID.AddString(Values);121}122123static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,124Type *Ty) {125ID.AddInteger(Kind);126ID.AddPointer(Ty);127}128129static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,130const ConstantRange &CR) {131ID.AddInteger(Kind);132CR.getLower().Profile(ID);133CR.getUpper().Profile(ID);134}135136static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,137ArrayRef<ConstantRange> Val) {138ID.AddInteger(Kind);139ID.AddInteger(Val.size());140for (auto &CR : Val) {141CR.getLower().Profile(ID);142CR.getUpper().Profile(ID);143}144}145};146147static_assert(std::is_trivially_destructible<AttributeImpl>::value,148"AttributeImpl should be trivially destructible");149150//===----------------------------------------------------------------------===//151/// \class152/// A set of classes that contain the value of the153/// attribute object. There are three main categories: enum attribute entries,154/// represented by Attribute::AttrKind; alignment attribute entries; and string155/// attribute enties, which are for target-dependent attributes.156157class EnumAttributeImpl : public AttributeImpl {158Attribute::AttrKind Kind;159160protected:161EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind)162: AttributeImpl(ID), Kind(Kind) {}163164public:165EnumAttributeImpl(Attribute::AttrKind Kind)166: AttributeImpl(EnumAttrEntry), Kind(Kind) {167assert(Kind != Attribute::AttrKind::None &&168"Can't create a None attribute!");169}170171Attribute::AttrKind getEnumKind() const { return Kind; }172};173174class IntAttributeImpl : public EnumAttributeImpl {175uint64_t Val;176177public:178IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val)179: EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {180assert(Attribute::isIntAttrKind(Kind) &&181"Wrong kind for int attribute!");182}183184uint64_t getValue() const { return Val; }185};186187class StringAttributeImpl final188: public AttributeImpl,189private TrailingObjects<StringAttributeImpl, char> {190friend TrailingObjects;191192unsigned KindSize;193unsigned ValSize;194size_t numTrailingObjects(OverloadToken<char>) const {195return KindSize + 1 + ValSize + 1;196}197198public:199StringAttributeImpl(StringRef Kind, StringRef Val = StringRef())200: AttributeImpl(StringAttrEntry), KindSize(Kind.size()),201ValSize(Val.size()) {202char *TrailingString = getTrailingObjects<char>();203// Some users rely on zero-termination.204llvm::copy(Kind, TrailingString);205TrailingString[KindSize] = '\0';206llvm::copy(Val, &TrailingString[KindSize + 1]);207TrailingString[KindSize + 1 + ValSize] = '\0';208}209210StringRef getStringKind() const {211return StringRef(getTrailingObjects<char>(), KindSize);212}213StringRef getStringValue() const {214return StringRef(getTrailingObjects<char>() + KindSize + 1, ValSize);215}216217static size_t totalSizeToAlloc(StringRef Kind, StringRef Val) {218return TrailingObjects::totalSizeToAlloc<char>(Kind.size() + 1 +219Val.size() + 1);220}221};222223class TypeAttributeImpl : public EnumAttributeImpl {224Type *Ty;225226public:227TypeAttributeImpl(Attribute::AttrKind Kind, Type *Ty)228: EnumAttributeImpl(TypeAttrEntry, Kind), Ty(Ty) {}229230Type *getTypeValue() const { return Ty; }231};232233class ConstantRangeAttributeImpl : public EnumAttributeImpl {234ConstantRange CR;235236public:237ConstantRangeAttributeImpl(Attribute::AttrKind Kind, const ConstantRange &CR)238: EnumAttributeImpl(ConstantRangeAttrEntry, Kind), CR(CR) {}239240const ConstantRange &getConstantRangeValue() const { return CR; }241};242243class ConstantRangeListAttributeImpl final244: public EnumAttributeImpl,245private TrailingObjects<ConstantRangeListAttributeImpl, ConstantRange> {246friend TrailingObjects;247248unsigned Size;249size_t numTrailingObjects(OverloadToken<ConstantRange>) const { return Size; }250251public:252ConstantRangeListAttributeImpl(Attribute::AttrKind Kind,253ArrayRef<ConstantRange> Val)254: EnumAttributeImpl(ConstantRangeListAttrEntry, Kind), Size(Val.size()) {255assert(Size > 0);256ConstantRange *TrailingCR = getTrailingObjects<ConstantRange>();257std::uninitialized_copy(Val.begin(), Val.end(), TrailingCR);258}259260~ConstantRangeListAttributeImpl() {261ConstantRange *TrailingCR = getTrailingObjects<ConstantRange>();262for (unsigned I = 0; I != Size; ++I)263TrailingCR[I].~ConstantRange();264}265266ArrayRef<ConstantRange> getConstantRangeListValue() const {267return ArrayRef(getTrailingObjects<ConstantRange>(), Size);268}269270static size_t totalSizeToAlloc(ArrayRef<ConstantRange> Val) {271return TrailingObjects::totalSizeToAlloc<ConstantRange>(Val.size());272}273};274275class AttributeBitSet {276/// Bitset with a bit for each available attribute Attribute::AttrKind.277uint8_t AvailableAttrs[12] = {};278static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,279"Too many attributes");280281public:282bool hasAttribute(Attribute::AttrKind Kind) const {283return AvailableAttrs[Kind / 8] & (1 << (Kind % 8));284}285286void addAttribute(Attribute::AttrKind Kind) {287AvailableAttrs[Kind / 8] |= 1 << (Kind % 8);288}289};290291//===----------------------------------------------------------------------===//292/// \class293/// This class represents a group of attributes that apply to one294/// element: function, return type, or parameter.295class AttributeSetNode final296: public FoldingSetNode,297private TrailingObjects<AttributeSetNode, Attribute> {298friend TrailingObjects;299300unsigned NumAttrs; ///< Number of attributes in this node.301AttributeBitSet AvailableAttrs; ///< Available enum attributes.302303DenseMap<StringRef, Attribute> StringAttrs;304305AttributeSetNode(ArrayRef<Attribute> Attrs);306307static AttributeSetNode *getSorted(LLVMContext &C,308ArrayRef<Attribute> SortedAttrs);309std::optional<Attribute> findEnumAttribute(Attribute::AttrKind Kind) const;310311public:312// AttributesSetNode is uniqued, these should not be available.313AttributeSetNode(const AttributeSetNode &) = delete;314AttributeSetNode &operator=(const AttributeSetNode &) = delete;315316void operator delete(void *p) { ::operator delete(p); }317318static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);319320static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);321322/// Return the number of attributes this AttributeList contains.323unsigned getNumAttributes() const { return NumAttrs; }324325bool hasAttribute(Attribute::AttrKind Kind) const {326return AvailableAttrs.hasAttribute(Kind);327}328bool hasAttribute(StringRef Kind) const;329bool hasAttributes() const { return NumAttrs != 0; }330331Attribute getAttribute(Attribute::AttrKind Kind) const;332Attribute getAttribute(StringRef Kind) const;333334MaybeAlign getAlignment() const;335MaybeAlign getStackAlignment() const;336uint64_t getDereferenceableBytes() const;337uint64_t getDereferenceableOrNullBytes() const;338std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()339const;340unsigned getVScaleRangeMin() const;341std::optional<unsigned> getVScaleRangeMax() const;342UWTableKind getUWTableKind() const;343AllocFnKind getAllocKind() const;344MemoryEffects getMemoryEffects() const;345FPClassTest getNoFPClass() const;346std::string getAsString(bool InAttrGrp) const;347Type *getAttributeType(Attribute::AttrKind Kind) const;348349using iterator = const Attribute *;350351iterator begin() const { return getTrailingObjects<Attribute>(); }352iterator end() const { return begin() + NumAttrs; }353354void Profile(FoldingSetNodeID &ID) const {355Profile(ID, ArrayRef(begin(), end()));356}357358static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {359for (const auto &Attr : AttrList)360Attr.Profile(ID);361}362};363364//===----------------------------------------------------------------------===//365/// \class366/// This class represents a set of attributes that apply to the function,367/// return type, and parameters.368class AttributeListImpl final369: public FoldingSetNode,370private TrailingObjects<AttributeListImpl, AttributeSet> {371friend class AttributeList;372friend TrailingObjects;373374private:375unsigned NumAttrSets; ///< Number of entries in this set.376/// Available enum function attributes.377AttributeBitSet AvailableFunctionAttrs;378/// Union of enum attributes available at any index.379AttributeBitSet AvailableSomewhereAttrs;380381// Helper fn for TrailingObjects class.382size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; }383384public:385AttributeListImpl(ArrayRef<AttributeSet> Sets);386387// AttributesSetImpt is uniqued, these should not be available.388AttributeListImpl(const AttributeListImpl &) = delete;389AttributeListImpl &operator=(const AttributeListImpl &) = delete;390391/// Return true if the AttributeSet or the FunctionIndex has an392/// enum attribute of the given kind.393bool hasFnAttribute(Attribute::AttrKind Kind) const {394return AvailableFunctionAttrs.hasAttribute(Kind);395}396397/// Return true if the specified attribute is set for at least one398/// parameter or for the return value. If Index is not nullptr, the index399/// of a parameter with the specified attribute is provided.400bool hasAttrSomewhere(Attribute::AttrKind Kind,401unsigned *Index = nullptr) const;402403using iterator = const AttributeSet *;404405iterator begin() const { return getTrailingObjects<AttributeSet>(); }406iterator end() const { return begin() + NumAttrSets; }407408void Profile(FoldingSetNodeID &ID) const;409static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeSet> Nodes);410411void dump() const;412};413414static_assert(std::is_trivially_destructible<AttributeListImpl>::value,415"AttributeListImpl should be trivially destructible");416417} // end namespace llvm418419#endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H420421422