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