brintos

brintos / llvm-project-archived public Read only

0
0
Text · 13.3 KiB · 707c820 Raw
416 lines · c
1//===- AttributeImpl.h - Attribute Internals --------------------*- C++ -*-===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8///9/// \file10/// This file defines various helper methods and classes used by11/// LLVMContextImpl for creating and managing attributes.12///13//===----------------------------------------------------------------------===//14 15#ifndef LLVM_LIB_IR_ATTRIBUTEIMPL_H16#define LLVM_LIB_IR_ATTRIBUTEIMPL_H17 18#include "llvm/ADT/ArrayRef.h"19#include "llvm/ADT/DenseMap.h"20#include "llvm/ADT/FoldingSet.h"21#include "llvm/ADT/StringRef.h"22#include "llvm/IR/Attributes.h"23#include "llvm/IR/ConstantRange.h"24#include "llvm/IR/ConstantRangeList.h"25#include "llvm/Support/TrailingObjects.h"26#include <cassert>27#include <cstddef>28#include <cstdint>29#include <optional>30#include <string>31#include <utility>32 33namespace llvm {34 35class LLVMContext;36class Type;37 38//===----------------------------------------------------------------------===//39/// \class40/// This class represents a single, uniqued attribute. That attribute41/// could be a single enum, a tuple, or a string.42class AttributeImpl : public FoldingSetNode {43  unsigned char KindID; ///< Holds the AttrEntryKind of the attribute44 45protected:46  enum AttrEntryKind {47    EnumAttrEntry,48    IntAttrEntry,49    StringAttrEntry,50    TypeAttrEntry,51    ConstantRangeAttrEntry,52    ConstantRangeListAttrEntry,53  };54 55  AttributeImpl(AttrEntryKind KindID) : KindID(KindID) {}56 57public:58  // AttributesImpl is uniqued, these should not be available.59  AttributeImpl(const AttributeImpl &) = delete;60  AttributeImpl &operator=(const AttributeImpl &) = delete;61 62  bool isEnumAttribute() const { return KindID == EnumAttrEntry; }63  bool isIntAttribute() const { return KindID == IntAttrEntry; }64  bool isStringAttribute() const { return KindID == StringAttrEntry; }65  bool isTypeAttribute() const { return KindID == TypeAttrEntry; }66  bool isConstantRangeAttribute() const {67    return KindID == ConstantRangeAttrEntry;68  }69  bool isConstantRangeListAttribute() const {70    return KindID == ConstantRangeListAttrEntry;71  }72 73  bool hasAttribute(Attribute::AttrKind A) const;74  bool hasAttribute(StringRef Kind) const;75 76  Attribute::AttrKind getKindAsEnum() const;77  uint64_t getValueAsInt() const;78  bool getValueAsBool() const;79 80  StringRef getKindAsString() const;81  StringRef getValueAsString() const;82 83  Type *getValueAsType() const;84 85  const ConstantRange &getValueAsConstantRange() const;86 87  ArrayRef<ConstantRange> getValueAsConstantRangeList() const;88 89  /// Used to sort attributes. KindOnly controls if the sort includes the90  /// attributes' values or just the kind.91  int cmp(const AttributeImpl &AI, bool KindOnly) const;92  /// Used when sorting the attributes.93  bool operator<(const AttributeImpl &AI) const;94 95  void Profile(FoldingSetNodeID &ID) const {96    if (isEnumAttribute())97      Profile(ID, getKindAsEnum());98    else if (isIntAttribute())99      Profile(ID, getKindAsEnum(), getValueAsInt());100    else if (isStringAttribute())101      Profile(ID, getKindAsString(), getValueAsString());102    else if (isTypeAttribute())103      Profile(ID, getKindAsEnum(), getValueAsType());104    else if (isConstantRangeAttribute())105      Profile(ID, getKindAsEnum(), getValueAsConstantRange());106    else107      Profile(ID, getKindAsEnum(), getValueAsConstantRangeList());108  }109 110  static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind) {111    assert(Attribute::isEnumAttrKind(Kind) && "Expected enum attribute");112    ID.AddInteger(Kind);113  }114 115  static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,116                      uint64_t Val) {117    assert(Attribute::isIntAttrKind(Kind) && "Expected int attribute");118    ID.AddInteger(Kind);119    ID.AddInteger(Val);120  }121 122  static void Profile(FoldingSetNodeID &ID, StringRef Kind, StringRef Values) {123    ID.AddString(Kind);124    if (!Values.empty()) ID.AddString(Values);125  }126 127  static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,128                      Type *Ty) {129    ID.AddInteger(Kind);130    ID.AddPointer(Ty);131  }132 133  static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,134                      const ConstantRange &CR) {135    ID.AddInteger(Kind);136    CR.getLower().Profile(ID);137    CR.getUpper().Profile(ID);138  }139 140  static void Profile(FoldingSetNodeID &ID, Attribute::AttrKind Kind,141                      ArrayRef<ConstantRange> Val) {142    ID.AddInteger(Kind);143    ID.AddInteger(Val.size());144    for (auto &CR : Val) {145      CR.getLower().Profile(ID);146      CR.getUpper().Profile(ID);147    }148  }149};150 151static_assert(std::is_trivially_destructible<AttributeImpl>::value,152              "AttributeImpl should be trivially destructible");153 154//===----------------------------------------------------------------------===//155/// \class156/// A set of classes that contain the value of the157/// attribute object. There are three main categories: enum attribute entries,158/// represented by Attribute::AttrKind; alignment attribute entries; and string159/// attribute enties, which are for target-dependent attributes.160 161class EnumAttributeImpl : public AttributeImpl {162  Attribute::AttrKind Kind;163 164protected:165  EnumAttributeImpl(AttrEntryKind ID, Attribute::AttrKind Kind)166      : AttributeImpl(ID), Kind(Kind) {}167 168public:169  EnumAttributeImpl(Attribute::AttrKind Kind)170      : AttributeImpl(EnumAttrEntry), Kind(Kind) {171    assert(Kind != Attribute::AttrKind::None &&172           "Can't create a None attribute!");173  }174 175  Attribute::AttrKind getEnumKind() const { return Kind; }176};177 178class IntAttributeImpl : public EnumAttributeImpl {179  uint64_t Val;180 181public:182  IntAttributeImpl(Attribute::AttrKind Kind, uint64_t Val)183      : EnumAttributeImpl(IntAttrEntry, Kind), Val(Val) {184    assert(Attribute::isIntAttrKind(Kind) &&185           "Wrong kind for int attribute!");186  }187 188  uint64_t getValue() const { return Val; }189};190 191class StringAttributeImpl final192    : public AttributeImpl,193      private TrailingObjects<StringAttributeImpl, char> {194  friend TrailingObjects;195 196  unsigned KindSize;197  unsigned ValSize;198 199public:200  StringAttributeImpl(StringRef Kind, StringRef Val = StringRef())201      : AttributeImpl(StringAttrEntry), KindSize(Kind.size()),202        ValSize(Val.size()) {203    char *TrailingString = getTrailingObjects();204    // Some users rely on zero-termination.205    llvm::copy(Kind, TrailingString);206    TrailingString[KindSize] = '\0';207    llvm::copy(Val, &TrailingString[KindSize + 1]);208    TrailingString[KindSize + 1 + ValSize] = '\0';209  }210 211  StringRef getStringKind() const {212    return StringRef(getTrailingObjects(), KindSize);213  }214  StringRef getStringValue() const {215    return StringRef(getTrailingObjects() + KindSize + 1, ValSize);216  }217 218  static size_t totalSizeToAlloc(StringRef Kind, StringRef Val) {219    return TrailingObjects::totalSizeToAlloc<char>(Kind.size() + 1 +220                                                   Val.size() + 1);221  }222};223 224class TypeAttributeImpl : public EnumAttributeImpl {225  Type *Ty;226 227public:228  TypeAttributeImpl(Attribute::AttrKind Kind, Type *Ty)229      : EnumAttributeImpl(TypeAttrEntry, Kind), Ty(Ty) {}230 231  Type *getTypeValue() const { return Ty; }232};233 234class ConstantRangeAttributeImpl : public EnumAttributeImpl {235  ConstantRange CR;236 237public:238  ConstantRangeAttributeImpl(Attribute::AttrKind Kind, const ConstantRange &CR)239      : EnumAttributeImpl(ConstantRangeAttrEntry, Kind), CR(CR) {}240 241  const ConstantRange &getConstantRangeValue() const { return CR; }242};243 244class ConstantRangeListAttributeImpl final245    : public EnumAttributeImpl,246      private TrailingObjects<ConstantRangeListAttributeImpl, ConstantRange> {247  friend TrailingObjects;248 249  unsigned Size;250 251public:252  ConstantRangeListAttributeImpl(Attribute::AttrKind Kind,253                                 ArrayRef<ConstantRange> Val)254      : EnumAttributeImpl(ConstantRangeListAttrEntry, Kind), Size(Val.size()) {255    assert(Size > 0);256    llvm::uninitialized_copy(Val, getTrailingObjects());257  }258 259  ~ConstantRangeListAttributeImpl() {260    for (ConstantRange &CR : getTrailingObjects(Size))261      CR.~ConstantRange();262  }263 264  ArrayRef<ConstantRange> getConstantRangeListValue() const {265    return getTrailingObjects(Size);266  }267 268  static size_t totalSizeToAlloc(ArrayRef<ConstantRange> Val) {269    return TrailingObjects::totalSizeToAlloc<ConstantRange>(Val.size());270  }271};272 273class AttributeBitSet {274  /// Bitset with a bit for each available attribute Attribute::AttrKind.275  uint8_t AvailableAttrs[16] = {};276  static_assert(Attribute::EndAttrKinds <= sizeof(AvailableAttrs) * CHAR_BIT,277                "Too many attributes");278 279public:280  bool hasAttribute(Attribute::AttrKind Kind) const {281    return AvailableAttrs[Kind / 8] & (1 << (Kind % 8));282  }283 284  void addAttribute(Attribute::AttrKind Kind) {285    AvailableAttrs[Kind / 8] |= 1 << (Kind % 8);286  }287};288 289//===----------------------------------------------------------------------===//290/// \class291/// This class represents a group of attributes that apply to one292/// element: function, return type, or parameter.293class AttributeSetNode final294    : public FoldingSetNode,295      private TrailingObjects<AttributeSetNode, Attribute> {296  friend TrailingObjects;297 298  unsigned NumAttrs; ///< Number of attributes in this node.299  AttributeBitSet AvailableAttrs; ///< Available enum attributes.300 301  DenseMap<StringRef, Attribute> StringAttrs;302 303  AttributeSetNode(ArrayRef<Attribute> Attrs);304 305  static AttributeSetNode *getSorted(LLVMContext &C,306                                     ArrayRef<Attribute> SortedAttrs);307  std::optional<Attribute> findEnumAttribute(Attribute::AttrKind Kind) const;308 309public:310  // AttributesSetNode is uniqued, these should not be available.311  AttributeSetNode(const AttributeSetNode &) = delete;312  AttributeSetNode &operator=(const AttributeSetNode &) = delete;313 314  void operator delete(void *p) { ::operator delete(p); }315 316  static AttributeSetNode *get(LLVMContext &C, const AttrBuilder &B);317 318  static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs);319 320  /// Return the number of attributes this AttributeList contains.321  unsigned getNumAttributes() const { return NumAttrs; }322 323  bool hasAttribute(Attribute::AttrKind Kind) const {324    return AvailableAttrs.hasAttribute(Kind);325  }326  bool hasAttribute(StringRef Kind) const;327  bool hasAttributes() const { return NumAttrs != 0; }328 329  Attribute getAttribute(Attribute::AttrKind Kind) const;330  Attribute getAttribute(StringRef Kind) const;331 332  MaybeAlign getAlignment() const;333  MaybeAlign getStackAlignment() const;334  uint64_t getDereferenceableBytes() const;335  uint64_t getDereferenceableOrNullBytes() const;336  std::optional<std::pair<unsigned, std::optional<unsigned>>> getAllocSizeArgs()337      const;338  unsigned getVScaleRangeMin() const;339  std::optional<unsigned> getVScaleRangeMax() const;340  UWTableKind getUWTableKind() const;341  AllocFnKind getAllocKind() const;342  MemoryEffects getMemoryEffects() const;343  CaptureInfo getCaptureInfo() const;344  FPClassTest getNoFPClass() const;345  std::string getAsString(bool InAttrGrp) const;346  Type *getAttributeType(Attribute::AttrKind Kind) const;347 348  using iterator = const Attribute *;349 350  iterator begin() const { return getTrailingObjects(); }351  iterator end() const { return begin() + NumAttrs; }352 353  void Profile(FoldingSetNodeID &ID) const {354    Profile(ID, ArrayRef(begin(), end()));355  }356 357  static void Profile(FoldingSetNodeID &ID, ArrayRef<Attribute> AttrList) {358    for (const auto &Attr : AttrList)359      Attr.Profile(ID);360  }361};362 363//===----------------------------------------------------------------------===//364/// \class365/// This class represents a set of attributes that apply to the function,366/// return type, and parameters.367class AttributeListImpl final368    : public FoldingSetNode,369      private TrailingObjects<AttributeListImpl, AttributeSet> {370  friend class AttributeList;371  friend TrailingObjects;372 373private:374  unsigned NumAttrSets; ///< Number of entries in this set.375  /// Available enum function attributes.376  AttributeBitSet AvailableFunctionAttrs;377  /// Union of enum attributes available at any index.378  AttributeBitSet AvailableSomewhereAttrs;379 380public:381  AttributeListImpl(ArrayRef<AttributeSet> Sets);382 383  // AttributesSetImpt is uniqued, these should not be available.384  AttributeListImpl(const AttributeListImpl &) = delete;385  AttributeListImpl &operator=(const AttributeListImpl &) = delete;386 387  /// Return true if the AttributeSet or the FunctionIndex has an388  /// enum attribute of the given kind.389  bool hasFnAttribute(Attribute::AttrKind Kind) const {390    return AvailableFunctionAttrs.hasAttribute(Kind);391  }392 393  /// Return true if the specified attribute is set for at least one394  /// parameter or for the return value. If Index is not nullptr, the index395  /// of a parameter with the specified attribute is provided.396  bool hasAttrSomewhere(Attribute::AttrKind Kind,397                        unsigned *Index = nullptr) const;398 399  using iterator = const AttributeSet *;400 401  iterator begin() const { return getTrailingObjects(); }402  iterator end() const { return begin() + NumAttrSets; }403 404  void Profile(FoldingSetNodeID &ID) const;405  static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeSet> Nodes);406 407  void dump() const;408};409 410static_assert(std::is_trivially_destructible<AttributeListImpl>::value,411              "AttributeListImpl should be trivially destructible");412 413} // end namespace llvm414 415#endif // LLVM_LIB_IR_ATTRIBUTEIMPL_H416