LLVM  8.0.1
Attributes.cpp
Go to the documentation of this file.
1 //===- Attributes.cpp - Implement AttributesList --------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // \file
11 // This file implements the Attribute, AttributeImpl, AttrBuilder,
12 // AttributeListImpl, and AttributeList classes.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/IR/Attributes.h"
17 #include "AttributeImpl.h"
18 #include "LLVMContextImpl.h"
19 #include "llvm/ADT/ArrayRef.h"
20 #include "llvm/ADT/FoldingSet.h"
21 #include "llvm/ADT/Optional.h"
22 #include "llvm/ADT/STLExtras.h"
23 #include "llvm/ADT/SmallVector.h"
24 #include "llvm/ADT/StringExtras.h"
25 #include "llvm/ADT/StringRef.h"
26 #include "llvm/ADT/Twine.h"
27 #include "llvm/Config/llvm-config.h"
28 #include "llvm/IR/Function.h"
29 #include "llvm/IR/LLVMContext.h"
30 #include "llvm/IR/Type.h"
31 #include "llvm/Support/Compiler.h"
32 #include "llvm/Support/Debug.h"
36 #include <algorithm>
37 #include <cassert>
38 #include <climits>
39 #include <cstddef>
40 #include <cstdint>
41 #include <limits>
42 #include <string>
43 #include <tuple>
44 #include <utility>
45 
46 using namespace llvm;
47 
48 //===----------------------------------------------------------------------===//
49 // Attribute Construction Methods
50 //===----------------------------------------------------------------------===//
51 
52 // allocsize has two integer arguments, but because they're both 32 bits, we can
53 // pack them into one 64-bit value, at the cost of making said value
54 // nonsensical.
55 //
56 // In order to do this, we need to reserve one value of the second (optional)
57 // allocsize argument to signify "not present."
58 static const unsigned AllocSizeNumElemsNotPresent = -1;
59 
60 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
61  const Optional<unsigned> &NumElemsArg) {
62  assert((!NumElemsArg.hasValue() ||
63  *NumElemsArg != AllocSizeNumElemsNotPresent) &&
64  "Attempting to pack a reserved value");
65 
66  return uint64_t(ElemSizeArg) << 32 |
67  NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
68 }
69 
70 static std::pair<unsigned, Optional<unsigned>>
71 unpackAllocSizeArgs(uint64_t Num) {
72  unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
73  unsigned ElemSizeArg = Num >> 32;
74 
75  Optional<unsigned> NumElemsArg;
76  if (NumElems != AllocSizeNumElemsNotPresent)
77  NumElemsArg = NumElems;
78  return std::make_pair(ElemSizeArg, NumElemsArg);
79 }
80 
82  uint64_t Val) {
83  LLVMContextImpl *pImpl = Context.pImpl;
85  ID.AddInteger(Kind);
86  if (Val) ID.AddInteger(Val);
87 
88  void *InsertPoint;
89  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
90 
91  if (!PA) {
92  // If we didn't find any existing attributes of the same shape then create a
93  // new one and insert it.
94  if (!Val)
95  PA = new EnumAttributeImpl(Kind);
96  else
97  PA = new IntAttributeImpl(Kind, Val);
98  pImpl->AttrsSet.InsertNode(PA, InsertPoint);
99  }
100 
101  // Return the Attribute that we found or created.
102  return Attribute(PA);
103 }
104 
106  LLVMContextImpl *pImpl = Context.pImpl;
108  ID.AddString(Kind);
109  if (!Val.empty()) ID.AddString(Val);
110 
111  void *InsertPoint;
112  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
113 
114  if (!PA) {
115  // If we didn't find any existing attributes of the same shape then create a
116  // new one and insert it.
117  PA = new StringAttributeImpl(Kind, Val);
118  pImpl->AttrsSet.InsertNode(PA, InsertPoint);
119  }
120 
121  // Return the Attribute that we found or created.
122  return Attribute(PA);
123 }
124 
126  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
127  assert(Align <= 0x40000000 && "Alignment too large.");
128  return get(Context, Alignment, Align);
129 }
130 
132  uint64_t Align) {
133  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
134  assert(Align <= 0x100 && "Alignment too large.");
135  return get(Context, StackAlignment, Align);
136 }
137 
139  uint64_t Bytes) {
140  assert(Bytes && "Bytes must be non-zero.");
141  return get(Context, Dereferenceable, Bytes);
142 }
143 
145  uint64_t Bytes) {
146  assert(Bytes && "Bytes must be non-zero.");
147  return get(Context, DereferenceableOrNull, Bytes);
148 }
149 
150 Attribute
152  const Optional<unsigned> &NumElemsArg) {
153  assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
154  "Invalid allocsize arguments -- given allocsize(0, 0)");
155  return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
156 }
157 
158 //===----------------------------------------------------------------------===//
159 // Attribute Accessor Methods
160 //===----------------------------------------------------------------------===//
161 
163  return pImpl && pImpl->isEnumAttribute();
164 }
165 
167  return pImpl && pImpl->isIntAttribute();
168 }
169 
171  return pImpl && pImpl->isStringAttribute();
172 }
173 
175  if (!pImpl) return None;
177  "Invalid attribute type to get the kind as an enum!");
178  return pImpl->getKindAsEnum();
179 }
180 
181 uint64_t Attribute::getValueAsInt() const {
182  if (!pImpl) return 0;
184  "Expected the attribute to be an integer attribute!");
185  return pImpl->getValueAsInt();
186 }
187 
189  if (!pImpl) return {};
191  "Invalid attribute type to get the kind as a string!");
192  return pImpl->getKindAsString();
193 }
194 
196  if (!pImpl) return {};
198  "Invalid attribute type to get the value as a string!");
199  return pImpl->getValueAsString();
200 }
201 
203  return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
204 }
205 
207  if (!isStringAttribute()) return false;
208  return pImpl && pImpl->hasAttribute(Kind);
209 }
210 
211 unsigned Attribute::getAlignment() const {
213  "Trying to get alignment from non-alignment attribute!");
214  return pImpl->getValueAsInt();
215 }
216 
219  "Trying to get alignment from non-alignment attribute!");
220  return pImpl->getValueAsInt();
221 }
222 
225  "Trying to get dereferenceable bytes from "
226  "non-dereferenceable attribute!");
227  return pImpl->getValueAsInt();
228 }
229 
232  "Trying to get dereferenceable bytes from "
233  "non-dereferenceable attribute!");
234  return pImpl->getValueAsInt();
235 }
236 
237 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
239  "Trying to get allocsize args from non-allocsize attribute");
240  return unpackAllocSizeArgs(pImpl->getValueAsInt());
241 }
242 
243 std::string Attribute::getAsString(bool InAttrGrp) const {
244  if (!pImpl) return {};
245 
247  return "sanitize_address";
249  return "sanitize_hwaddress";
251  return "alwaysinline";
253  return "argmemonly";
255  return "builtin";
257  return "byval";
259  return "convergent";
261  return "swifterror";
263  return "swiftself";
265  return "inaccessiblememonly";
267  return "inaccessiblemem_or_argmemonly";
269  return "inalloca";
271  return "inlinehint";
273  return "inreg";
275  return "jumptable";
277  return "minsize";
279  return "naked";
281  return "nest";
283  return "noalias";
285  return "nobuiltin";
287  return "nocapture";
289  return "noduplicate";
291  return "noimplicitfloat";
293  return "noinline";
295  return "nonlazybind";
297  return "nonnull";
299  return "noredzone";
301  return "noreturn";
303  return "nocf_check";
305  return "norecurse";
307  return "nounwind";
309  return "optforfuzzing";
311  return "optnone";
313  return "optsize";
315  return "readnone";
317  return "readonly";
319  return "writeonly";
321  return "returned";
323  return "returns_twice";
325  return "signext";
327  return "speculative_load_hardening";
329  return "speculatable";
331  return "ssp";
333  return "sspreq";
335  return "sspstrong";
337  return "safestack";
339  return "shadowcallstack";
341  return "strictfp";
343  return "sret";
345  return "sanitize_thread";
347  return "sanitize_memory";
349  return "uwtable";
351  return "zeroext";
353  return "cold";
354 
355  // FIXME: These should be output like this:
356  //
357  // align=4
358  // alignstack=8
359  //
361  std::string Result;
362  Result += "align";
363  Result += (InAttrGrp) ? "=" : " ";
364  Result += utostr(getValueAsInt());
365  return Result;
366  }
367 
368  auto AttrWithBytesToString = [&](const char *Name) {
369  std::string Result;
370  Result += Name;
371  if (InAttrGrp) {
372  Result += "=";
373  Result += utostr(getValueAsInt());
374  } else {
375  Result += "(";
376  Result += utostr(getValueAsInt());
377  Result += ")";
378  }
379  return Result;
380  };
381 
383  return AttrWithBytesToString("alignstack");
384 
386  return AttrWithBytesToString("dereferenceable");
387 
389  return AttrWithBytesToString("dereferenceable_or_null");
390 
392  unsigned ElemSize;
393  Optional<unsigned> NumElems;
394  std::tie(ElemSize, NumElems) = getAllocSizeArgs();
395 
396  std::string Result = "allocsize(";
397  Result += utostr(ElemSize);
398  if (NumElems.hasValue()) {
399  Result += ',';
400  Result += utostr(*NumElems);
401  }
402  Result += ')';
403  return Result;
404  }
405 
406  // Convert target-dependent attributes to strings of the form:
407  //
408  // "kind"
409  // "kind" = "value"
410  //
411  if (isStringAttribute()) {
412  std::string Result;
413  Result += (Twine('"') + getKindAsString() + Twine('"')).str();
414 
415  std::string AttrVal = pImpl->getValueAsString();
416  if (AttrVal.empty()) return Result;
417 
418  // Since some attribute strings contain special characters that cannot be
419  // printable, those have to be escaped to make the attribute value printable
420  // as is. e.g. "\01__gnu_mcount_nc"
421  {
422  raw_string_ostream OS(Result);
423  OS << "=\"";
424  printEscapedString(AttrVal, OS);
425  OS << "\"";
426  }
427  return Result;
428  }
429 
430  llvm_unreachable("Unknown attribute");
431 }
432 
434  if (!pImpl && !A.pImpl) return false;
435  if (!pImpl) return true;
436  if (!A.pImpl) return false;
437  return *pImpl < *A.pImpl;
438 }
439 
440 //===----------------------------------------------------------------------===//
441 // AttributeImpl Definition
442 //===----------------------------------------------------------------------===//
443 
444 // Pin the vtables to this file.
446 
447 void EnumAttributeImpl::anchor() {}
448 
449 void IntAttributeImpl::anchor() {}
450 
451 void StringAttributeImpl::anchor() {}
452 
454  if (isStringAttribute()) return false;
455  return getKindAsEnum() == A;
456 }
457 
459  if (!isStringAttribute()) return false;
460  return getKindAsString() == Kind;
461 }
462 
465  return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
466 }
467 
470  return static_cast<const IntAttributeImpl *>(this)->getValue();
471 }
472 
475  return static_cast<const StringAttributeImpl *>(this)->getStringKind();
476 }
477 
480  return static_cast<const StringAttributeImpl *>(this)->getStringValue();
481 }
482 
484  // This sorts the attributes with Attribute::AttrKinds coming first (sorted
485  // relative to their enum value) and then strings.
486  if (isEnumAttribute()) {
487  if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
488  if (AI.isIntAttribute()) return true;
489  if (AI.isStringAttribute()) return true;
490  }
491 
492  if (isIntAttribute()) {
493  if (AI.isEnumAttribute()) return false;
494  if (AI.isIntAttribute()) {
495  if (getKindAsEnum() == AI.getKindAsEnum())
496  return getValueAsInt() < AI.getValueAsInt();
497  return getKindAsEnum() < AI.getKindAsEnum();
498  }
499  if (AI.isStringAttribute()) return true;
500  }
501 
502  if (AI.isEnumAttribute()) return false;
503  if (AI.isIntAttribute()) return false;
504  if (getKindAsString() == AI.getKindAsString())
505  return getValueAsString() < AI.getValueAsString();
506  return getKindAsString() < AI.getKindAsString();
507 }
508 
509 //===----------------------------------------------------------------------===//
510 // AttributeSet Definition
511 //===----------------------------------------------------------------------===//
512 
514  return AttributeSet(AttributeSetNode::get(C, B));
515 }
516 
518  return AttributeSet(AttributeSetNode::get(C, Attrs));
519 }
520 
522  Attribute::AttrKind Kind) const {
523  if (hasAttribute(Kind)) return *this;
524  AttrBuilder B;
525  B.addAttribute(Kind);
526  return addAttributes(C, AttributeSet::get(C, B));
527 }
528 
530  StringRef Value) const {
531  AttrBuilder B;
532  B.addAttribute(Kind, Value);
533  return addAttributes(C, AttributeSet::get(C, B));
534 }
535 
537  const AttributeSet AS) const {
538  if (!hasAttributes())
539  return AS;
540 
541  if (!AS.hasAttributes())
542  return *this;
543 
544  AttrBuilder B(AS);
545  for (const auto I : *this)
546  B.addAttribute(I);
547 
548  return get(C, B);
549 }
550 
552  Attribute::AttrKind Kind) const {
553  if (!hasAttribute(Kind)) return *this;
554  AttrBuilder B(*this);
555  B.removeAttribute(Kind);
556  return get(C, B);
557 }
558 
560  StringRef Kind) const {
561  if (!hasAttribute(Kind)) return *this;
562  AttrBuilder B(*this);
563  B.removeAttribute(Kind);
564  return get(C, B);
565 }
566 
568  const AttrBuilder &Attrs) const {
569  AttrBuilder B(*this);
570  B.remove(Attrs);
571  return get(C, B);
572 }
573 
575  return SetNode ? SetNode->getNumAttributes() : 0;
576 }
577 
579  return SetNode ? SetNode->hasAttribute(Kind) : false;
580 }
581 
583  return SetNode ? SetNode->hasAttribute(Kind) : false;
584 }
585 
587  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
588 }
589 
591  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
592 }
593 
594 unsigned AttributeSet::getAlignment() const {
595  return SetNode ? SetNode->getAlignment() : 0;
596 }
597 
599  return SetNode ? SetNode->getStackAlignment() : 0;
600 }
601 
603  return SetNode ? SetNode->getDereferenceableBytes() : 0;
604 }
605 
607  return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
608 }
609 
610 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
611  return SetNode ? SetNode->getAllocSizeArgs()
612  : std::pair<unsigned, Optional<unsigned>>(0, 0);
613 }
614 
615 std::string AttributeSet::getAsString(bool InAttrGrp) const {
616  return SetNode ? SetNode->getAsString(InAttrGrp) : "";
617 }
618 
620  return SetNode ? SetNode->begin() : nullptr;
621 }
622 
624  return SetNode ? SetNode->end() : nullptr;
625 }
626 
627 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
629  dbgs() << "AS =\n";
630  dbgs() << " { ";
631  dbgs() << getAsString(true) << " }\n";
632 }
633 #endif
634 
635 //===----------------------------------------------------------------------===//
636 // AttributeSetNode Definition
637 //===----------------------------------------------------------------------===//
638 
639 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
640  : AvailableAttrs(0), NumAttrs(Attrs.size()) {
641  // There's memory after the node where we can store the entries in.
642  llvm::copy(Attrs, getTrailingObjects<Attribute>());
643 
644  for (const auto I : *this) {
645  if (!I.isStringAttribute()) {
646  AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
647  }
648  }
649 }
650 
652  ArrayRef<Attribute> Attrs) {
653  if (Attrs.empty())
654  return nullptr;
655 
656  // Otherwise, build a key to look up the existing attributes.
657  LLVMContextImpl *pImpl = C.pImpl;
659 
660  SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
661  llvm::sort(SortedAttrs);
662 
663  for (const auto Attr : SortedAttrs)
664  Attr.Profile(ID);
665 
666  void *InsertPoint;
667  AttributeSetNode *PA =
668  pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
669 
670  // If we didn't find any existing attributes of the same shape then create a
671  // new one and insert it.
672  if (!PA) {
673  // Coallocate entries after the AttributeSetNode itself.
674  void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
675  PA = new (Mem) AttributeSetNode(SortedAttrs);
676  pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
677  }
678 
679  // Return the AttributeSetNode that we found or created.
680  return PA;
681 }
682 
684  // Add target-independent attributes.
688  if (!B.contains(Kind))
689  continue;
690 
691  Attribute Attr;
692  switch (Kind) {
695  break;
698  break;
701  C, B.getDereferenceableBytes());
702  break;
706  break;
707  case Attribute::AllocSize: {
708  auto A = B.getAllocSizeArgs();
709  Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
710  break;
711  }
712  default:
713  Attr = Attribute::get(C, Kind);
714  }
715  Attrs.push_back(Attr);
716  }
717 
718  // Add target-dependent (string) attributes.
719  for (const auto &TDA : B.td_attrs())
720  Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
721 
722  return get(C, Attrs);
723 }
724 
726  for (const auto I : *this)
727  if (I.hasAttribute(Kind))
728  return true;
729  return false;
730 }
731 
733  if (hasAttribute(Kind)) {
734  for (const auto I : *this)
735  if (I.hasAttribute(Kind))
736  return I;
737  }
738  return {};
739 }
740 
742  for (const auto I : *this)
743  if (I.hasAttribute(Kind))
744  return I;
745  return {};
746 }
747 
749  for (const auto I : *this)
750  if (I.hasAttribute(Attribute::Alignment))
751  return I.getAlignment();
752  return 0;
753 }
754 
756  for (const auto I : *this)
757  if (I.hasAttribute(Attribute::StackAlignment))
758  return I.getStackAlignment();
759  return 0;
760 }
761 
763  for (const auto I : *this)
764  if (I.hasAttribute(Attribute::Dereferenceable))
765  return I.getDereferenceableBytes();
766  return 0;
767 }
768 
770  for (const auto I : *this)
771  if (I.hasAttribute(Attribute::DereferenceableOrNull))
772  return I.getDereferenceableOrNullBytes();
773  return 0;
774 }
775 
776 std::pair<unsigned, Optional<unsigned>>
778  for (const auto I : *this)
779  if (I.hasAttribute(Attribute::AllocSize))
780  return I.getAllocSizeArgs();
781  return std::make_pair(0, 0);
782 }
783 
784 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
785  std::string Str;
786  for (iterator I = begin(), E = end(); I != E; ++I) {
787  if (I != begin())
788  Str += ' ';
789  Str += I->getAsString(InAttrGrp);
790  }
791  return Str;
792 }
793 
794 //===----------------------------------------------------------------------===//
795 // AttributeListImpl Definition
796 //===----------------------------------------------------------------------===//
797 
798 /// Map from AttributeList index to the internal array index. Adding one happens
799 /// to work, but it relies on unsigned integer wrapping. MSVC warns about
800 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
801 /// folds it to add anyway.
802 static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
803  return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
804 }
805 
808  : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) {
809  assert(!Sets.empty() && "pointless AttributeListImpl");
810 
811  // There's memory after the node where we can store the entries in.
812  llvm::copy(Sets, getTrailingObjects<AttributeSet>());
813 
814  // Initialize AvailableFunctionAttrs summary bitset.
815  static_assert(Attribute::EndAttrKinds <=
816  sizeof(AvailableFunctionAttrs) * CHAR_BIT,
817  "Too many attributes");
818  static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
819  "function should be stored in slot 0");
820  for (const auto I : Sets[0]) {
821  if (!I.isStringAttribute())
822  AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum();
823  }
824 }
825 
827  Profile(ID, makeArrayRef(begin(), end()));
828 }
829 
831  ArrayRef<AttributeSet> Sets) {
832  for (const auto &Set : Sets)
833  ID.AddPointer(Set.SetNode);
834 }
835 
836 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
838  AttributeList(const_cast<AttributeListImpl *>(this)).dump();
839 }
840 #endif
841 
842 //===----------------------------------------------------------------------===//
843 // AttributeList Construction and Mutation Methods
844 //===----------------------------------------------------------------------===//
845 
847  ArrayRef<AttributeSet> AttrSets) {
848  assert(!AttrSets.empty() && "pointless AttributeListImpl");
849 
850  LLVMContextImpl *pImpl = C.pImpl;
852  AttributeListImpl::Profile(ID, AttrSets);
853 
854  void *InsertPoint;
855  AttributeListImpl *PA =
856  pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
857 
858  // If we didn't find any existing attributes of the same shape then
859  // create a new one and insert it.
860  if (!PA) {
861  // Coallocate entries after the AttributeListImpl itself.
862  void *Mem = ::operator new(
863  AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
864  PA = new (Mem) AttributeListImpl(C, AttrSets);
865  pImpl->AttrsLists.InsertNode(PA, InsertPoint);
866  }
867 
868  // Return the AttributesList that we found or created.
869  return AttributeList(PA);
870 }
871 
874  ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
875  // If there are no attributes then return a null AttributesList pointer.
876  if (Attrs.empty())
877  return {};
878 
879  assert(std::is_sorted(Attrs.begin(), Attrs.end(),
880  [](const std::pair<unsigned, Attribute> &LHS,
881  const std::pair<unsigned, Attribute> &RHS) {
882  return LHS.first < RHS.first;
883  }) && "Misordered Attributes list!");
884  assert(llvm::none_of(Attrs,
885  [](const std::pair<unsigned, Attribute> &Pair) {
886  return Pair.second.hasAttribute(Attribute::None);
887  }) &&
888  "Pointless attribute!");
889 
890  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
891  // list.
893  for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
894  E = Attrs.end(); I != E; ) {
895  unsigned Index = I->first;
897  while (I != E && I->first == Index) {
898  AttrVec.push_back(I->second);
899  ++I;
900  }
901 
902  AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
903  }
904 
905  return get(C, AttrPairVec);
906 }
907 
910  ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
911  // If there are no attributes then return a null AttributesList pointer.
912  if (Attrs.empty())
913  return {};
914 
915  assert(std::is_sorted(Attrs.begin(), Attrs.end(),
916  [](const std::pair<unsigned, AttributeSet> &LHS,
917  const std::pair<unsigned, AttributeSet> &RHS) {
918  return LHS.first < RHS.first;
919  }) &&
920  "Misordered Attributes list!");
921  assert(llvm::none_of(Attrs,
922  [](const std::pair<unsigned, AttributeSet> &Pair) {
923  return !Pair.second.hasAttributes();
924  }) &&
925  "Pointless attribute!");
926 
927  unsigned MaxIndex = Attrs.back().first;
928  // If the MaxIndex is FunctionIndex and there are other indices in front
929  // of it, we need to use the largest of those to get the right size.
930  if (MaxIndex == FunctionIndex && Attrs.size() > 1)
931  MaxIndex = Attrs[Attrs.size() - 2].first;
932 
933  SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
934  for (const auto Pair : Attrs)
935  AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
936 
937  return getImpl(C, AttrVec);
938 }
939 
941  AttributeSet RetAttrs,
942  ArrayRef<AttributeSet> ArgAttrs) {
943  // Scan from the end to find the last argument with attributes. Most
944  // arguments don't have attributes, so it's nice if we can have fewer unique
945  // AttributeListImpls by dropping empty attribute sets at the end of the list.
946  unsigned NumSets = 0;
947  for (size_t I = ArgAttrs.size(); I != 0; --I) {
948  if (ArgAttrs[I - 1].hasAttributes()) {
949  NumSets = I + 2;
950  break;
951  }
952  }
953  if (NumSets == 0) {
954  // Check function and return attributes if we didn't have argument
955  // attributes.
956  if (RetAttrs.hasAttributes())
957  NumSets = 2;
958  else if (FnAttrs.hasAttributes())
959  NumSets = 1;
960  }
961 
962  // If all attribute sets were empty, we can use the empty attribute list.
963  if (NumSets == 0)
964  return {};
965 
967  AttrSets.reserve(NumSets);
968  // If we have any attributes, we always have function attributes.
969  AttrSets.push_back(FnAttrs);
970  if (NumSets > 1)
971  AttrSets.push_back(RetAttrs);
972  if (NumSets > 2) {
973  // Drop the empty argument attribute sets at the end.
974  ArgAttrs = ArgAttrs.take_front(NumSets - 2);
975  AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
976  }
977 
978  return getImpl(C, AttrSets);
979 }
980 
982  const AttrBuilder &B) {
983  if (!B.hasAttributes())
984  return {};
985  Index = attrIdxToArrayIdx(Index);
986  SmallVector<AttributeSet, 8> AttrSets(Index + 1);
987  AttrSets[Index] = AttributeSet::get(C, B);
988  return getImpl(C, AttrSets);
989 }
990 
994  for (const auto K : Kinds)
995  Attrs.emplace_back(Index, Attribute::get(C, K));
996  return get(C, Attrs);
997 }
998 
1000  ArrayRef<StringRef> Kinds) {
1002  for (const auto K : Kinds)
1003  Attrs.emplace_back(Index, Attribute::get(C, K));
1004  return get(C, Attrs);
1005 }
1006 
1008  ArrayRef<AttributeList> Attrs) {
1009  if (Attrs.empty())
1010  return {};
1011  if (Attrs.size() == 1)
1012  return Attrs[0];
1013 
1014  unsigned MaxSize = 0;
1015  for (const auto List : Attrs)
1016  MaxSize = std::max(MaxSize, List.getNumAttrSets());
1017 
1018  // If every list was empty, there is no point in merging the lists.
1019  if (MaxSize == 0)
1020  return {};
1021 
1022  SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1023  for (unsigned I = 0; I < MaxSize; ++I) {
1024  AttrBuilder CurBuilder;
1025  for (const auto List : Attrs)
1026  CurBuilder.merge(List.getAttributes(I - 1));
1027  NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1028  }
1029 
1030  return getImpl(C, NewAttrSets);
1031 }
1032 
1034  Attribute::AttrKind Kind) const {
1035  if (hasAttribute(Index, Kind)) return *this;
1036  AttrBuilder B;
1037  B.addAttribute(Kind);
1038  return addAttributes(C, Index, B);
1039 }
1040 
1042  StringRef Kind,
1043  StringRef Value) const {
1044  AttrBuilder B;
1045  B.addAttribute(Kind, Value);
1046  return addAttributes(C, Index, B);
1047 }
1048 
1050  Attribute A) const {
1051  AttrBuilder B;
1052  B.addAttribute(A);
1053  return addAttributes(C, Index, B);
1054 }
1055 
1057  const AttrBuilder &B) const {
1058  if (!B.hasAttributes())
1059  return *this;
1060 
1061  if (!pImpl)
1062  return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1063 
1064 #ifndef NDEBUG
1065  // FIXME it is not obvious how this should work for alignment. For now, say
1066  // we can't change a known alignment.
1067  unsigned OldAlign = getAttributes(Index).getAlignment();
1068  unsigned NewAlign = B.getAlignment();
1069  assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1070  "Attempt to change alignment!");
1071 #endif
1072 
1073  Index = attrIdxToArrayIdx(Index);
1074  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1075  if (Index >= AttrSets.size())
1076  AttrSets.resize(Index + 1);
1077 
1078  AttrBuilder Merged(AttrSets[Index]);
1079  Merged.merge(B);
1080  AttrSets[Index] = AttributeSet::get(C, Merged);
1081 
1082  return getImpl(C, AttrSets);
1083 }
1084 
1086  ArrayRef<unsigned> ArgNos,
1087  Attribute A) const {
1088  assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
1089 
1090  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1091  unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1092  if (MaxIndex >= AttrSets.size())
1093  AttrSets.resize(MaxIndex + 1);
1094 
1095  for (unsigned ArgNo : ArgNos) {
1096  unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1097  AttrBuilder B(AttrSets[Index]);
1098  B.addAttribute(A);
1099  AttrSets[Index] = AttributeSet::get(C, B);
1100  }
1101 
1102  return getImpl(C, AttrSets);
1103 }
1104 
1106  Attribute::AttrKind Kind) const {
1107  if (!hasAttribute(Index, Kind)) return *this;
1108 
1109  Index = attrIdxToArrayIdx(Index);
1110  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1111  assert(Index < AttrSets.size());
1112 
1113  AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1114 
1115  return getImpl(C, AttrSets);
1116 }
1117 
1119  StringRef Kind) const {
1120  if (!hasAttribute(Index, Kind)) return *this;
1121 
1122  Index = attrIdxToArrayIdx(Index);
1123  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1124  assert(Index < AttrSets.size());
1125 
1126  AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1127 
1128  return getImpl(C, AttrSets);
1129 }
1130 
1133  const AttrBuilder &AttrsToRemove) const {
1134  if (!pImpl)
1135  return {};
1136 
1137  Index = attrIdxToArrayIdx(Index);
1138  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1139  if (Index >= AttrSets.size())
1140  AttrSets.resize(Index + 1);
1141 
1142  AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
1143 
1144  return getImpl(C, AttrSets);
1145 }
1146 
1148  unsigned WithoutIndex) const {
1149  if (!pImpl)
1150  return {};
1151  WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1152  if (WithoutIndex >= getNumAttrSets())
1153  return *this;
1154  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1155  AttrSets[WithoutIndex] = AttributeSet();
1156  return getImpl(C, AttrSets);
1157 }
1158 
1160  unsigned Index,
1161  uint64_t Bytes) const {
1162  AttrBuilder B;
1163  B.addDereferenceableAttr(Bytes);
1164  return addAttributes(C, Index, B);
1165 }
1166 
1169  uint64_t Bytes) const {
1170  AttrBuilder B;
1172  return addAttributes(C, Index, B);
1173 }
1174 
1177  unsigned ElemSizeArg,
1178  const Optional<unsigned> &NumElemsArg) {
1179  AttrBuilder B;
1180  B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1181  return addAttributes(C, Index, B);
1182 }
1183 
1184 //===----------------------------------------------------------------------===//
1185 // AttributeList Accessor Methods
1186 //===----------------------------------------------------------------------===//
1187 
1188 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
1189 
1191  return getAttributes(ArgNo + FirstArgIndex);
1192 }
1193 
1195  return getAttributes(ReturnIndex);
1196 }
1197 
1199  return getAttributes(FunctionIndex);
1200 }
1201 
1203  Attribute::AttrKind Kind) const {
1204  return getAttributes(Index).hasAttribute(Kind);
1205 }
1206 
1208  return getAttributes(Index).hasAttribute(Kind);
1209 }
1210 
1211 bool AttributeList::hasAttributes(unsigned Index) const {
1212  return getAttributes(Index).hasAttributes();
1213 }
1214 
1216  return pImpl && pImpl->hasFnAttribute(Kind);
1217 }
1218 
1220  return hasAttribute(AttributeList::FunctionIndex, Kind);
1221 }
1222 
1224  Attribute::AttrKind Kind) const {
1225  return hasAttribute(ArgNo + FirstArgIndex, Kind);
1226 }
1227 
1229  unsigned *Index) const {
1230  if (!pImpl) return false;
1231 
1232  for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
1233  if (hasAttribute(I, Attr)) {
1234  if (Index)
1235  *Index = I;
1236  return true;
1237  }
1238  }
1239 
1240  return false;
1241 }
1242 
1244  Attribute::AttrKind Kind) const {
1245  return getAttributes(Index).getAttribute(Kind);
1246 }
1247 
1249  return getAttributes(Index).getAttribute(Kind);
1250 }
1251 
1253  return getAttributes(ReturnIndex).getAlignment();
1254 }
1255 
1256 unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
1257  return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1258 }
1259 
1260 unsigned AttributeList::getStackAlignment(unsigned Index) const {
1261  return getAttributes(Index).getStackAlignment();
1262 }
1263 
1265  return getAttributes(Index).getDereferenceableBytes();
1266 }
1267 
1270 }
1271 
1272 std::pair<unsigned, Optional<unsigned>>
1274  return getAttributes(Index).getAllocSizeArgs();
1275 }
1276 
1277 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1278  return getAttributes(Index).getAsString(InAttrGrp);
1279 }
1280 
1282  Index = attrIdxToArrayIdx(Index);
1283  if (!pImpl || Index >= getNumAttrSets())
1284  return {};
1285  return pImpl->begin()[Index];
1286 }
1287 
1289  return pImpl ? pImpl->begin() : nullptr;
1290 }
1291 
1293  return pImpl ? pImpl->end() : nullptr;
1294 }
1295 
1296 //===----------------------------------------------------------------------===//
1297 // AttributeList Introspection Methods
1298 //===----------------------------------------------------------------------===//
1299 
1301  return pImpl ? pImpl->NumAttrSets : 0;
1302 }
1303 
1304 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1306  dbgs() << "PAL[\n";
1307 
1308  for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
1309  if (getAttributes(i).hasAttributes())
1310  dbgs() << " { " << i << " => " << getAsString(i) << " }\n";
1311  }
1312 
1313  dbgs() << "]\n";
1314 }
1315 #endif
1316 
1317 //===----------------------------------------------------------------------===//
1318 // AttrBuilder Method Implementations
1319 //===----------------------------------------------------------------------===//
1320 
1321 // FIXME: Remove this ctor, use AttributeSet.
1323  AttributeSet AS = AL.getAttributes(Index);
1324  for (const auto &A : AS)
1325  addAttribute(A);
1326 }
1327 
1329  for (const auto &A : AS)
1330  addAttribute(A);
1331 }
1332 
1334  Attrs.reset();
1335  TargetDepAttrs.clear();
1336  Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1337  AllocSizeArgs = 0;
1338 }
1339 
1341  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1344  "Adding integer attribute without adding a value!");
1345  Attrs[Val] = true;
1346  return *this;
1347 }
1348 
1350  if (Attr.isStringAttribute()) {
1351  addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1352  return *this;
1353  }
1354 
1356  Attrs[Kind] = true;
1357 
1358  if (Kind == Attribute::Alignment)
1359  Alignment = Attr.getAlignment();
1360  else if (Kind == Attribute::StackAlignment)
1361  StackAlignment = Attr.getStackAlignment();
1362  else if (Kind == Attribute::Dereferenceable)
1363  DerefBytes = Attr.getDereferenceableBytes();
1364  else if (Kind == Attribute::DereferenceableOrNull)
1365  DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1366  else if (Kind == Attribute::AllocSize)
1367  AllocSizeArgs = Attr.getValueAsInt();
1368  return *this;
1369 }
1370 
1372  TargetDepAttrs[A] = V;
1373  return *this;
1374 }
1375 
1377  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1378  Attrs[Val] = false;
1379 
1380  if (Val == Attribute::Alignment)
1381  Alignment = 0;
1382  else if (Val == Attribute::StackAlignment)
1383  StackAlignment = 0;
1384  else if (Val == Attribute::Dereferenceable)
1385  DerefBytes = 0;
1386  else if (Val == Attribute::DereferenceableOrNull)
1387  DerefOrNullBytes = 0;
1388  else if (Val == Attribute::AllocSize)
1389  AllocSizeArgs = 0;
1390 
1391  return *this;
1392 }
1393 
1395  remove(A.getAttributes(Index));
1396  return *this;
1397 }
1398 
1400  auto I = TargetDepAttrs.find(A);
1401  if (I != TargetDepAttrs.end())
1402  TargetDepAttrs.erase(I);
1403  return *this;
1404 }
1405 
1406 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1407  return unpackAllocSizeArgs(AllocSizeArgs);
1408 }
1409 
1411  if (Align == 0) return *this;
1412 
1413  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1414  assert(Align <= 0x40000000 && "Alignment too large.");
1415 
1416  Attrs[Attribute::Alignment] = true;
1417  Alignment = Align;
1418  return *this;
1419 }
1420 
1422  // Default alignment, allow the target to define how to align it.
1423  if (Align == 0) return *this;
1424 
1425  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1426  assert(Align <= 0x100 && "Alignment too large.");
1427 
1428  Attrs[Attribute::StackAlignment] = true;
1429  StackAlignment = Align;
1430  return *this;
1431 }
1432 
1434  if (Bytes == 0) return *this;
1435 
1436  Attrs[Attribute::Dereferenceable] = true;
1437  DerefBytes = Bytes;
1438  return *this;
1439 }
1440 
1442  if (Bytes == 0)
1443  return *this;
1444 
1445  Attrs[Attribute::DereferenceableOrNull] = true;
1446  DerefOrNullBytes = Bytes;
1447  return *this;
1448 }
1449 
1451  const Optional<unsigned> &NumElems) {
1452  return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1453 }
1454 
1456  // (0, 0) is our "not present" value, so we need to check for it here.
1457  assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1458 
1459  Attrs[Attribute::AllocSize] = true;
1460  // Reuse existing machinery to store this as a single 64-bit integer so we can
1461  // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1462  AllocSizeArgs = RawArgs;
1463  return *this;
1464 }
1465 
1467  // FIXME: What if both have alignments, but they don't match?!
1468  if (!Alignment)
1469  Alignment = B.Alignment;
1470 
1471  if (!StackAlignment)
1472  StackAlignment = B.StackAlignment;
1473 
1474  if (!DerefBytes)
1475  DerefBytes = B.DerefBytes;
1476 
1477  if (!DerefOrNullBytes)
1478  DerefOrNullBytes = B.DerefOrNullBytes;
1479 
1480  if (!AllocSizeArgs)
1481  AllocSizeArgs = B.AllocSizeArgs;
1482 
1483  Attrs |= B.Attrs;
1484 
1485  for (auto I : B.td_attrs())
1486  TargetDepAttrs[I.first] = I.second;
1487 
1488  return *this;
1489 }
1490 
1492  // FIXME: What if both have alignments, but they don't match?!
1493  if (B.Alignment)
1494  Alignment = 0;
1495 
1496  if (B.StackAlignment)
1497  StackAlignment = 0;
1498 
1499  if (B.DerefBytes)
1500  DerefBytes = 0;
1501 
1502  if (B.DerefOrNullBytes)
1503  DerefOrNullBytes = 0;
1504 
1505  if (B.AllocSizeArgs)
1506  AllocSizeArgs = 0;
1507 
1508  Attrs &= ~B.Attrs;
1509 
1510  for (auto I : B.td_attrs())
1511  TargetDepAttrs.erase(I.first);
1512 
1513  return *this;
1514 }
1515 
1517  // First check if any of the target independent attributes overlap.
1518  if ((Attrs & B.Attrs).any())
1519  return true;
1520 
1521  // Then check if any target dependent ones do.
1522  for (const auto &I : td_attrs())
1523  if (B.contains(I.first))
1524  return true;
1525 
1526  return false;
1527 }
1528 
1530  return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1531 }
1532 
1534  return !Attrs.none() || !TargetDepAttrs.empty();
1535 }
1536 
1538  AttributeSet AS = AL.getAttributes(Index);
1539 
1540  for (const auto Attr : AS) {
1541  if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1542  if (contains(Attr.getKindAsEnum()))
1543  return true;
1544  } else {
1545  assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1546  return contains(Attr.getKindAsString());
1547  }
1548  }
1549 
1550  return false;
1551 }
1552 
1554  return Alignment != 0;
1555 }
1556 
1558  if (Attrs != B.Attrs)
1559  return false;
1560 
1561  for (td_const_iterator I = TargetDepAttrs.begin(),
1562  E = TargetDepAttrs.end(); I != E; ++I)
1563  if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1564  return false;
1565 
1566  return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1567  DerefBytes == B.DerefBytes;
1568 }
1569 
1570 //===----------------------------------------------------------------------===//
1571 // AttributeFuncs Function Defintions
1572 //===----------------------------------------------------------------------===//
1573 
1574 /// Which attributes cannot be applied to a type.
1576  AttrBuilder Incompatible;
1577 
1578  if (!Ty->isIntegerTy())
1579  // Attribute that only apply to integers.
1580  Incompatible.addAttribute(Attribute::SExt)
1582 
1583  if (!Ty->isPointerTy())
1584  // Attribute that only apply to pointers.
1585  Incompatible.addAttribute(Attribute::ByVal)
1590  .addDereferenceableAttr(1) // the int here is ignored
1591  .addDereferenceableOrNullAttr(1) // the int here is ignored
1596 
1597  return Incompatible;
1598 }
1599 
1600 template<typename AttrClass>
1601 static bool isEqual(const Function &Caller, const Function &Callee) {
1602  return Caller.getFnAttribute(AttrClass::getKind()) ==
1603  Callee.getFnAttribute(AttrClass::getKind());
1604 }
1605 
1606 /// Compute the logical AND of the attributes of the caller and the
1607 /// callee.
1608 ///
1609 /// This function sets the caller's attribute to false if the callee's attribute
1610 /// is false.
1611 template<typename AttrClass>
1612 static void setAND(Function &Caller, const Function &Callee) {
1613  if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1614  !AttrClass::isSet(Callee, AttrClass::getKind()))
1615  AttrClass::set(Caller, AttrClass::getKind(), false);
1616 }
1617 
1618 /// Compute the logical OR of the attributes of the caller and the
1619 /// callee.
1620 ///
1621 /// This function sets the caller's attribute to true if the callee's attribute
1622 /// is true.
1623 template<typename AttrClass>
1624 static void setOR(Function &Caller, const Function &Callee) {
1625  if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1626  AttrClass::isSet(Callee, AttrClass::getKind()))
1627  AttrClass::set(Caller, AttrClass::getKind(), true);
1628 }
1629 
1630 /// If the inlined function had a higher stack protection level than the
1631 /// calling function, then bump up the caller's stack protection level.
1632 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1633  // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1634  // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1635  // clutter to the IR.
1636  AttrBuilder OldSSPAttr;
1640 
1642  Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1644  } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1646  Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1648  } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1652 }
1653 
1654 /// If the inlined function required stack probes, then ensure that
1655 /// the calling function has those too.
1656 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
1657  if (!Caller.hasFnAttribute("probe-stack") &&
1658  Callee.hasFnAttribute("probe-stack")) {
1659  Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
1660  }
1661 }
1662 
1663 /// If the inlined function defines the size of guard region
1664 /// on the stack, then ensure that the calling function defines a guard region
1665 /// that is no larger.
1666 static void
1668  if (Callee.hasFnAttribute("stack-probe-size")) {
1669  uint64_t CalleeStackProbeSize;
1670  Callee.getFnAttribute("stack-probe-size")
1671  .getValueAsString()
1672  .getAsInteger(0, CalleeStackProbeSize);
1673  if (Caller.hasFnAttribute("stack-probe-size")) {
1674  uint64_t CallerStackProbeSize;
1675  Caller.getFnAttribute("stack-probe-size")
1676  .getValueAsString()
1677  .getAsInteger(0, CallerStackProbeSize);
1678  if (CallerStackProbeSize > CalleeStackProbeSize) {
1679  Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1680  }
1681  } else {
1682  Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1683  }
1684  }
1685 }
1686 
1687 /// If the inlined function defines a min legal vector width, then ensure
1688 /// the calling function has the same or larger min legal vector width. If the
1689 /// caller has the attribute, but the callee doesn't, we need to remove the
1690 /// attribute from the caller since we can't make any guarantees about the
1691 /// caller's requirements.
1692 /// This function is called after the inlining decision has been made so we have
1693 /// to merge the attribute this way. Heuristics that would use
1694 /// min-legal-vector-width to determine inline compatibility would need to be
1695 /// handled as part of inline cost analysis.
1696 static void
1698  if (Caller.hasFnAttribute("min-legal-vector-width")) {
1699  if (Callee.hasFnAttribute("min-legal-vector-width")) {
1700  uint64_t CallerVectorWidth;
1701  Caller.getFnAttribute("min-legal-vector-width")
1702  .getValueAsString()
1703  .getAsInteger(0, CallerVectorWidth);
1704  uint64_t CalleeVectorWidth;
1705  Callee.getFnAttribute("min-legal-vector-width")
1706  .getValueAsString()
1707  .getAsInteger(0, CalleeVectorWidth);
1708  if (CallerVectorWidth < CalleeVectorWidth)
1709  Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
1710  } else {
1711  // If the callee doesn't have the attribute then we don't know anything
1712  // and must drop the attribute from the caller.
1713  Caller.removeFnAttr("min-legal-vector-width");
1714  }
1715  }
1716 }
1717 
1718 /// If the inlined function has "null-pointer-is-valid=true" attribute,
1719 /// set this attribute in the caller post inlining.
1720 static void
1722  if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
1723  Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid"));
1724  }
1725 }
1726 
1727 #define GET_ATTR_COMPAT_FUNC
1728 #include "AttributesCompatFunc.inc"
1729 
1731  const Function &Callee) {
1732  return hasCompatibleFnAttrs(Caller, Callee);
1733 }
1734 
1736  const Function &Callee) {
1737  mergeFnAttrs(Caller, Callee);
1738 }
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs() const
Retrieve the allocsize args, if the allocsize attribute exists.
uint64_t CallInst * C
unsigned getStackAlignment() const
Definition: Attributes.cpp:755
void AddPointer(const void *Ptr)
Add* - Add various data types to Bit data.
Definition: FoldingSet.cpp:52
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:259
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
static constexpr unsigned attrIdxToArrayIdx(unsigned Index)
Map from AttributeList index to the internal array index.
Definition: Attributes.cpp:802
StringRef getKindAsString() const
Return the attribute&#39;s kind as a string.
Definition: Attributes.cpp:188
bool hasAttribute(Attribute::AttrKind A) const
Definition: Attributes.cpp:453
ArrayRef< T > take_front(size_t N=1) const
Return a copy of *this with only the first N elements.
Definition: ArrayRef.h:212
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs() const
Definition: Attributes.cpp:610
LLVMContext & Context
const T & back() const
back - Get the last element.
Definition: ArrayRef.h:158
FoldingSet< AttributeImpl > AttrsSet
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
Definition: Path.cpp:250
static void adjustCallerStackProbeSize(Function &Caller, const Function &Callee)
If the inlined function defines the size of guard region on the stack, then ensure that the calling f...
static std::pair< unsigned, Optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)
Definition: Attributes.cpp:71
This class represents lattice values for constants.
Definition: AllocatorList.h:24
uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute...
Definition: Attributes.cpp:230
unsigned getStackAlignment() const
Returns the stack alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:217
static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:125
iterator begin() const
Definition: ArrayRef.h:137
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:138
unsigned getAlignment() const
Definition: Attributes.cpp:748
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION
Definition: Optional.h:172
iterator begin() const
void printEscapedString(StringRef Name, raw_ostream &Out)
Print each character of the specified string, escaping it if it is not printable or if it is an escap...
Attribute getAttribute(Attribute::AttrKind Kind) const
Definition: Attributes.cpp:732
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:321
AttrBuilder & addDereferenceableAttr(uint64_t Bytes)
This turns the number of dereferenceable bytes into the form used internally in Attribute.
static AttributeSetNode * get(LLVMContext &C, const AttrBuilder &B)
Definition: Attributes.cpp:683
AttributeListImpl(LLVMContext &C, ArrayRef< AttributeSet > Sets)
Definition: Attributes.cpp:806
unsigned getRetAlignment() const
Return the alignment of the return value.
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
std::string getAsString(bool InAttrGrp) const
Definition: Attributes.cpp:784
void reserve(size_type N)
Definition: SmallVector.h:376
uint64_t getDereferenceableBytes() const
Definition: Attributes.cpp:762
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
return AArch64::GPR64RegClass contains(Reg)
void Profile(FoldingSetNodeID &ID) const
Definition: Attributes.cpp:826
bool areInlineCompatible(const Function &Caller, const Function &Callee)
bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
Definition: Attributes.cpp:433
uint64_t getDereferenceableOrNullBytes() const
Retrieve the number of dereferenceable_or_null bytes, if the dereferenceable_or_null attribute exists...
Definition: Attributes.h:774
amdgpu Simplify well known AMD library false Value Value const Twine & Name
uint64_t getDereferenceableOrNullBytes() const
Definition: Attributes.cpp:606
bool hasAttributes() const
Return true if the builder has IR-level attributes.
bool hasAlignmentAttr() const
Return true if the builder has an alignment attribute.
uint64_t getValueAsInt() const
Return the attribute&#39;s value as an integer.
Definition: Attributes.cpp:181
AttrBuilder & addDereferenceableOrNullAttr(uint64_t Bytes)
This turns the number of dereferenceable_or_null bytes into the form used internally in Attribute...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
Definition: Attributes.cpp:170
uint64_t getDereferenceableBytes(unsigned Index) const
Get the number of dereferenceable bytes (or zero if unknown).
ArrayRef< T > makeArrayRef(const T &OneElt)
Construct an ArrayRef from a single element.
Definition: ArrayRef.h:451
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:197
static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:144
bool none_of(R &&Range, UnaryPredicate P)
Provide wrappers to std::none_of which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1200
bool isIntAttribute() const
Definition: AttributeImpl.h:58
AttrBuilder & addAllocSizeAttr(unsigned ElemSizeArg, const Optional< unsigned > &NumElemsArg)
This turns one (or two) ints into the form used internally in Attribute.
This file contains the simple types necessary to represent the attributes associated with functions a...
No attributes have been set.
Definition: Attributes.h:72
AttributeSet getRetAttributes() const
The attributes for the ret value are returned.
void AddInteger(signed I)
Definition: FoldingSet.cpp:61
iterator begin() const
#define LLVM_DUMP_METHOD
Definition: Compiler.h:74
bool hasAttributes(unsigned Index) const
Return true if attribute exists at the given index.
LLVMContext & getContext() const
Retrieve the LLVM context.
AttributeList getAttributes(LLVMContext &C, ID id)
Return the attributes for an intrinsic.
unsigned getStackAlignment() const
Definition: Attributes.cpp:598
uint64_t getStackAlignment() const
Retrieve the stack alignment attribute, if it exists.
Definition: Attributes.h:766
iterator end() const
static bool isEqual(const Function &Caller, const Function &Callee)
LLVM_NODISCARD AttributeList removeAttributes(LLVMContext &C, unsigned Index, const AttrBuilder &AttrsToRemove) const
Remove the specified attributes at the specified index from this attribute list.
iterator end() const
AttributeSet getParamAttributes(unsigned ArgNo) const
The attributes for the argument or parameter at the given index are returned.
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:133
uint64_t getDereferenceableOrNullBytes(unsigned Index) const
Get the number of dereferenceable_or_null bytes (or zero if unknown).
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs() const
Definition: Attributes.cpp:777
AttrBuilder & remove(const AttrBuilder &B)
Remove the attributes from the builder.
LLVM_NODISCARD AttributeSet addAttributes(LLVMContext &C, AttributeSet AS) const
Add attributes to the attribute set.
Definition: Attributes.cpp:536
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs() const
Returns the argument numbers for the allocsize attribute (or pair(0, 0) if not known).
Definition: Attributes.cpp:237
constexpr char Attrs[]
Key for Kernel::Metadata::mAttrs.
AttrBuilder & addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr)
Add an allocsize attribute, using the representation returned by Attribute.getIntValue().
uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
Definition: Attributes.cpp:223
amdgpu Simplify well known AMD library false Value * Callee
bool hasAttribute(Attribute::AttrKind Kind) const
Return true if the attribute exists in this set.
Definition: Attributes.cpp:578
static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align)
Definition: Attributes.cpp:131
AttributeSet getAttributes(unsigned Index) const
The attributes for the specified index are returned.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:306
bool hasAttrSomewhere(Attribute::AttrKind Kind, unsigned *Index=nullptr) const
Return true if the specified attribute is set for at least one parameter or for the return value...
unsigned getStackAlignment(unsigned Index) const
Get the stack alignment.
bool operator==(const AttrBuilder &B)
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:202
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVM_NODISCARD AttributeList addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const
Add the dereferenceable_or_null attribute to the attribute set at the given index.
static AttributeSet get(LLVMContext &C, const AttrBuilder &B)
Definition: Attributes.cpp:513
std::map< std::string, std::string >::const_iterator td_const_iterator
Definition: Attributes.h:811
constexpr bool isPowerOf2_32(uint32_t Value)
Return true if the argument is a power of two > 0.
Definition: MathExtras.h:429
LLVM_NODISCARD AttributeList addParamAttribute(LLVMContext &C, unsigned ArgNo, Attribute::AttrKind Kind) const
Add an argument attribute to the list.
Definition: Attributes.h:403
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:46
This is an important class for using LLVM in a threaded context.
Definition: LLVMContext.h:69
static void adjustCallerStackProbes(Function &Caller, const Function &Callee)
If the inlined function required stack probes, then ensure that the calling function has those too...
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:149
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
bool isStringAttribute() const
Definition: AttributeImpl.h:59
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:224
LLVM_NODISCARD AttributeSet removeAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Remove the specified attribute from this set.
Definition: Attributes.cpp:551
uint64_t getAlignment() const
Retrieve the alignment attribute, if it exists.
Definition: Attributes.h:763
LLVM_NODISCARD AttributeList addAllocSizeAttr(LLVMContext &C, unsigned Index, unsigned ElemSizeArg, const Optional< unsigned > &NumElemsArg)
Add the allocsize attribute to the attribute set at the given index.
static const unsigned AllocSizeNumElemsNotPresent
Definition: Attributes.cpp:58
unsigned getNumAttributes() const
Return the number of attributes in this set.
Definition: Attributes.cpp:574
iterator begin() const
Definition: Attributes.cpp:619
This file defines various helper methods and classes used by LLVMContextImpl for creating and managin...
Attribute::AttrKind getKindAsEnum() const
Return the attribute&#39;s kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:174
bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
Definition: Attributes.cpp:162
Attribute::AttrKind getKindAsEnum() const
Definition: Attributes.cpp:463
Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
Definition: Attributes.cpp:586
std::string getAsString(unsigned Index, bool InAttrGrp=false) const
Return the attributes at the index as a string.
Sentinal value useful for loops.
Definition: Attributes.h:596
static void setAND(Function &Caller, const Function &Callee)
Compute the logical AND of the attributes of the caller and the callee.
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
Definition: Attributes.cpp:483
uint64_t getDereferenceableBytes() const
Retrieve the number of dereferenceable bytes, if the dereferenceable attribute exists (zero is return...
Definition: Attributes.h:770
Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
uint64_t getDereferenceableBytes() const
Definition: Attributes.cpp:602
size_t size() const
Definition: SmallVector.h:53
StringRef getKindAsString() const
Definition: Attributes.cpp:473
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:71
LLVM_NODISCARD AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Definition: Attributes.cpp:521
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1116
std::enable_if< std::numeric_limits< T >::is_signed, bool >::type getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:497
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee)
If the inlined function had a higher stack protection level than the calling function, then bump up the caller&#39;s stack protection level.
std::string getAsString(bool InAttrGrp=false) const
Definition: Attributes.cpp:615
bool hasParamAttribute(unsigned ArgNo, Attribute::AttrKind Kind) const
Equivalent to hasAttribute(ArgNo + FirstArgIndex, Kind).
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
Definition: STLExtras.h:1167
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
Definition: Attributes.h:743
unsigned getAlignment() const
Definition: Attributes.cpp:594
AttrBuilder & removeAttribute(Attribute::AttrKind Val)
Remove an attribute from the builder.
AttrBuilder & removeAttributes(AttributeList A, uint64_t WithoutIndex)
Remove the attributes from the builder.
This is a &#39;vector&#39; (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:847
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs(unsigned Index) const
Get the allocsize argument numbers (or pair(0, 0) if unknown).
bool overlaps(const AttrBuilder &B) const
Return true if the builder has any attribute that&#39;s in the specified builder.
iterator end() const
Definition: ArrayRef.h:138
std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:224
static void adjustNullPointerValidAttr(Function &Caller, const Function &Callee)
If the inlined function has "null-pointer-is-valid=true" attribute, set this attribute in the caller ...
static void setOR(Function &Caller, const Function &Callee)
Compute the logical OR of the attributes of the caller and the callee.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:133
void mergeAttributesForInlining(Function &Caller, const Function &Callee)
Merge caller&#39;s and callee&#39;s attributes.
unsigned getNumAttrSets() const
bool isEnumAttribute() const
Definition: AttributeImpl.h:57
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:478
uint64_t getDereferenceableOrNullBytes() const
Definition: Attributes.cpp:769
bool isIntAttribute() const
Return true if the attribute is an integer attribute.
Definition: Attributes.cpp:166
bool hasAttribute(Attribute::AttrKind Kind) const
void removeAttributes(unsigned i, const AttrBuilder &Attrs)
removes the attributes from the list of attributes.
Definition: Function.cpp:416
bool hasValue() const
Definition: Optional.h:165
unsigned getParamAlignment(unsigned ArgNo) const
Return the alignment for the specified function parameter.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:133
LLVM_NODISCARD AttributeList addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Add an attribute to the attribute set at the given index.
iterator end() const
Definition: Attributes.cpp:623
unsigned getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:211
LLVM_NODISCARD AttributeList addDereferenceableAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const
Add the dereferenceable attribute to the attribute set at the given index.
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:652
StringRef getValueAsString() const
Return the attribute&#39;s value as a string.
Definition: Attributes.cpp:195
LLVM_NODISCARD AttributeList removeAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Remove the specified attribute at the specified index from this attribute list.
const NodeList & List
Definition: RDFGraph.cpp:210
#define I(x, y, z)
Definition: MD5.cpp:58
static Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const Optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:151
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
friend class AttributeList
void AddString(StringRef String)
Definition: FoldingSet.cpp:87
uint64_t getValueAsInt() const
Definition: Attributes.cpp:468
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:81
StringRef getValueAsString() const
Definition: Attributes.cpp:478
Attribute()=default
td_range td_attrs()
Definition: Attributes.h:821
void removeFnAttr(Attribute::AttrKind Kind)
Remove function attributes from this function.
Definition: Function.h:246
LLVM_NODISCARD AttributeSet removeAttributes(LLVMContext &C, const AttrBuilder &AttrsToRemove) const
Remove the specified attributes from this set.
Definition: Attributes.cpp:567
LLVM_NODISCARD AttributeList addAttributes(LLVMContext &C, unsigned Index, const AttrBuilder &B) const
Add attributes to the attribute set at the given index.
static void adjustMinLegalVectorWidth(Function &Caller, const Function &Callee)
If the inlined function defines a min legal vector width, then ensure the calling function has the sa...
std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
Definition: Attributes.cpp:243
AttrBuilder & merge(const AttrBuilder &B)
Add the attributes from the builder.
const unsigned Kind
bool hasFnAttribute(Attribute::AttrKind Kind) const
Equivalent to hasAttribute(AttributeList::FunctionIndex, Kind) but may be faster. ...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
bool hasAttributes() const
Return true if attributes exists in this set.
Definition: Attributes.h:265
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:483
void dump() const
Definition: Attributes.cpp:628
LLVM Value Representation.
Definition: Value.h:73
virtual ~AttributeImpl()
AttrBuilder typeIncompatible(Type *Ty)
Which attributes cannot be applied to a type.
AttributeSet getFnAttributes() const
The function attributes are returned.
AttrBuilder & addStackAlignmentAttr(unsigned Align)
This turns an int stack alignment (which must be a power of 2) into the form used internally in Attri...
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:331
FoldingSet< AttributeSetNode > AttrsSetNodes
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.h:230
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:49
AttrBuilder & addAlignmentAttr(unsigned Align)
This turns an int alignment (which must be a power of 2) into the form used internally in Attribute...
static uint64_t packAllocSizeArgs(unsigned ElemSizeArg, const Optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:60
bool nullPointerIsDefined() const
Check if null pointer dereferencing is considered undefined behavior for the function.
Definition: Function.cpp:1431
static LazyValueInfoImpl & getImpl(void *&PImpl, AssumptionCache *AC, const DataLayout *DL, DominatorTree *DT=nullptr)
This lazily constructs the LazyValueInfoImpl.
OutputIt copy(R &&Range, OutputIt Out)
Definition: STLExtras.h:1238
static AttributeList get(LLVMContext &C, ArrayRef< std::pair< unsigned, Attribute >> Attrs)
Create an AttributeList with the specified parameters in it.
Definition: Attributes.cpp:873
AttrBuilder()=default
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:144
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results...
Definition: Attributes.h:70
void resize(size_type N)
Definition: SmallVector.h:351