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 
354  // FIXME: These should be output like this:
355  //
356  // align=4
357  // alignstack=8
358  //
359  if (hasAttribute(Attribute::Alignment)) {
360  std::string Result;
361  Result += "align";
362  Result += (InAttrGrp) ? "=" : " ";
363  Result += utostr(getValueAsInt());
364  return Result;
365  }
366 
367  auto AttrWithBytesToString = [&](const char *Name) {
368  std::string Result;
369  Result += Name;
370  if (InAttrGrp) {
371  Result += "=";
372  Result += utostr(getValueAsInt());
373  } else {
374  Result += "(";
375  Result += utostr(getValueAsInt());
376  Result += ")";
377  }
378  return Result;
379  };
380 
381  if (hasAttribute(Attribute::StackAlignment))
382  return AttrWithBytesToString("alignstack");
383 
384  if (hasAttribute(Attribute::Dereferenceable))
385  return AttrWithBytesToString("dereferenceable");
386 
387  if (hasAttribute(Attribute::DereferenceableOrNull))
388  return AttrWithBytesToString("dereferenceable_or_null");
389 
390  if (hasAttribute(Attribute::AllocSize)) {
391  unsigned ElemSize;
392  Optional<unsigned> NumElems;
393  std::tie(ElemSize, NumElems) = getAllocSizeArgs();
394 
395  std::string Result = "allocsize(";
396  Result += utostr(ElemSize);
397  if (NumElems.hasValue()) {
398  Result += ',';
399  Result += utostr(*NumElems);
400  }
401  Result += ')';
402  return Result;
403  }
404 
405  // Convert target-dependent attributes to strings of the form:
406  //
407  // "kind"
408  // "kind" = "value"
409  //
410  if (isStringAttribute()) {
411  std::string Result;
412  Result += (Twine('"') + getKindAsString() + Twine('"')).str();
413 
414  std::string AttrVal = pImpl->getValueAsString();
415  if (AttrVal.empty()) return Result;
416 
417  // Since some attribute strings contain special characters that cannot be
418  // printable, those have to be escaped to make the attribute value printable
419  // as is. e.g. "\01__gnu_mcount_nc"
420  {
421  raw_string_ostream OS(Result);
422  OS << "=\"";
423  printEscapedString(AttrVal, OS);
424  OS << "\"";
425  }
426  return Result;
427  }
428 
429  llvm_unreachable("Unknown attribute");
430 }
431 
433  if (!pImpl && !A.pImpl) return false;
434  if (!pImpl) return true;
435  if (!A.pImpl) return false;
436  return *pImpl < *A.pImpl;
437 }
438 
439 //===----------------------------------------------------------------------===//
440 // AttributeImpl Definition
441 //===----------------------------------------------------------------------===//
442 
443 // Pin the vtables to this file.
445 
446 void EnumAttributeImpl::anchor() {}
447 
448 void IntAttributeImpl::anchor() {}
449 
450 void StringAttributeImpl::anchor() {}
451 
453  if (isStringAttribute()) return false;
454  return getKindAsEnum() == A;
455 }
456 
458  if (!isStringAttribute()) return false;
459  return getKindAsString() == Kind;
460 }
461 
464  return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
465 }
466 
469  return static_cast<const IntAttributeImpl *>(this)->getValue();
470 }
471 
474  return static_cast<const StringAttributeImpl *>(this)->getStringKind();
475 }
476 
479  return static_cast<const StringAttributeImpl *>(this)->getStringValue();
480 }
481 
483  // This sorts the attributes with Attribute::AttrKinds coming first (sorted
484  // relative to their enum value) and then strings.
485  if (isEnumAttribute()) {
486  if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
487  if (AI.isIntAttribute()) return true;
488  if (AI.isStringAttribute()) return true;
489  }
490 
491  if (isIntAttribute()) {
492  if (AI.isEnumAttribute()) return false;
493  if (AI.isIntAttribute()) {
494  if (getKindAsEnum() == AI.getKindAsEnum())
495  return getValueAsInt() < AI.getValueAsInt();
496  return getKindAsEnum() < AI.getKindAsEnum();
497  }
498  if (AI.isStringAttribute()) return true;
499  }
500 
501  if (AI.isEnumAttribute()) return false;
502  if (AI.isIntAttribute()) return false;
503  if (getKindAsString() == AI.getKindAsString())
504  return getValueAsString() < AI.getValueAsString();
505  return getKindAsString() < AI.getKindAsString();
506 }
507 
508 //===----------------------------------------------------------------------===//
509 // AttributeSet Definition
510 //===----------------------------------------------------------------------===//
511 
513  return AttributeSet(AttributeSetNode::get(C, B));
514 }
515 
517  return AttributeSet(AttributeSetNode::get(C, Attrs));
518 }
519 
521  Attribute::AttrKind Kind) const {
522  if (hasAttribute(Kind)) return *this;
523  AttrBuilder B;
524  B.addAttribute(Kind);
525  return addAttributes(C, AttributeSet::get(C, B));
526 }
527 
529  StringRef Value) const {
530  AttrBuilder B;
531  B.addAttribute(Kind, Value);
532  return addAttributes(C, AttributeSet::get(C, B));
533 }
534 
536  const AttributeSet AS) const {
537  if (!hasAttributes())
538  return AS;
539 
540  if (!AS.hasAttributes())
541  return *this;
542 
543  AttrBuilder B(AS);
544  for (const auto I : *this)
545  B.addAttribute(I);
546 
547  return get(C, B);
548 }
549 
551  Attribute::AttrKind Kind) const {
552  if (!hasAttribute(Kind)) return *this;
553  AttrBuilder B(*this);
554  B.removeAttribute(Kind);
555  return get(C, B);
556 }
557 
559  StringRef Kind) const {
560  if (!hasAttribute(Kind)) return *this;
561  AttrBuilder B(*this);
562  B.removeAttribute(Kind);
563  return get(C, B);
564 }
565 
567  const AttrBuilder &Attrs) const {
568  AttrBuilder B(*this);
569  B.remove(Attrs);
570  return get(C, B);
571 }
572 
574  return SetNode ? SetNode->getNumAttributes() : 0;
575 }
576 
578  return SetNode ? SetNode->hasAttribute(Kind) : false;
579 }
580 
582  return SetNode ? SetNode->hasAttribute(Kind) : false;
583 }
584 
586  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
587 }
588 
590  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
591 }
592 
593 unsigned AttributeSet::getAlignment() const {
594  return SetNode ? SetNode->getAlignment() : 0;
595 }
596 
598  return SetNode ? SetNode->getStackAlignment() : 0;
599 }
600 
602  return SetNode ? SetNode->getDereferenceableBytes() : 0;
603 }
604 
606  return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
607 }
608 
609 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
610  return SetNode ? SetNode->getAllocSizeArgs()
611  : std::pair<unsigned, Optional<unsigned>>(0, 0);
612 }
613 
614 std::string AttributeSet::getAsString(bool InAttrGrp) const {
615  return SetNode ? SetNode->getAsString(InAttrGrp) : "";
616 }
617 
619  return SetNode ? SetNode->begin() : nullptr;
620 }
621 
623  return SetNode ? SetNode->end() : nullptr;
624 }
625 
626 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
628  dbgs() << "AS =\n";
629  dbgs() << " { ";
630  dbgs() << getAsString(true) << " }\n";
631 }
632 #endif
633 
634 //===----------------------------------------------------------------------===//
635 // AttributeSetNode Definition
636 //===----------------------------------------------------------------------===//
637 
638 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
639  : AvailableAttrs(0), NumAttrs(Attrs.size()) {
640  // There's memory after the node where we can store the entries in.
641  llvm::copy(Attrs, getTrailingObjects<Attribute>());
642 
643  for (const auto I : *this) {
644  if (!I.isStringAttribute()) {
645  AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
646  }
647  }
648 }
649 
651  ArrayRef<Attribute> Attrs) {
652  if (Attrs.empty())
653  return nullptr;
654 
655  // Otherwise, build a key to look up the existing attributes.
656  LLVMContextImpl *pImpl = C.pImpl;
658 
659  SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
660  llvm::sort(SortedAttrs);
661 
662  for (const auto Attr : SortedAttrs)
663  Attr.Profile(ID);
664 
665  void *InsertPoint;
666  AttributeSetNode *PA =
667  pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
668 
669  // If we didn't find any existing attributes of the same shape then create a
670  // new one and insert it.
671  if (!PA) {
672  // Coallocate entries after the AttributeSetNode itself.
673  void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
674  PA = new (Mem) AttributeSetNode(SortedAttrs);
675  pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
676  }
677 
678  // Return the AttributeSetNode that we found or created.
679  return PA;
680 }
681 
683  // Add target-independent attributes.
687  if (!B.contains(Kind))
688  continue;
689 
690  Attribute Attr;
691  switch (Kind) {
692  case Attribute::Alignment:
694  break;
695  case Attribute::StackAlignment:
697  break;
698  case Attribute::Dereferenceable:
700  C, B.getDereferenceableBytes());
701  break;
702  case Attribute::DereferenceableOrNull:
705  break;
706  case Attribute::AllocSize: {
707  auto A = B.getAllocSizeArgs();
708  Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
709  break;
710  }
711  default:
712  Attr = Attribute::get(C, Kind);
713  }
714  Attrs.push_back(Attr);
715  }
716 
717  // Add target-dependent (string) attributes.
718  for (const auto &TDA : B.td_attrs())
719  Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
720 
721  return get(C, Attrs);
722 }
723 
725  for (const auto I : *this)
726  if (I.hasAttribute(Kind))
727  return true;
728  return false;
729 }
730 
732  if (hasAttribute(Kind)) {
733  for (const auto I : *this)
734  if (I.hasAttribute(Kind))
735  return I;
736  }
737  return {};
738 }
739 
741  for (const auto I : *this)
742  if (I.hasAttribute(Kind))
743  return I;
744  return {};
745 }
746 
748  for (const auto I : *this)
749  if (I.hasAttribute(Attribute::Alignment))
750  return I.getAlignment();
751  return 0;
752 }
753 
755  for (const auto I : *this)
756  if (I.hasAttribute(Attribute::StackAlignment))
757  return I.getStackAlignment();
758  return 0;
759 }
760 
762  for (const auto I : *this)
763  if (I.hasAttribute(Attribute::Dereferenceable))
764  return I.getDereferenceableBytes();
765  return 0;
766 }
767 
769  for (const auto I : *this)
770  if (I.hasAttribute(Attribute::DereferenceableOrNull))
771  return I.getDereferenceableOrNullBytes();
772  return 0;
773 }
774 
775 std::pair<unsigned, Optional<unsigned>>
777  for (const auto I : *this)
778  if (I.hasAttribute(Attribute::AllocSize))
779  return I.getAllocSizeArgs();
780  return std::make_pair(0, 0);
781 }
782 
783 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
784  std::string Str;
785  for (iterator I = begin(), E = end(); I != E; ++I) {
786  if (I != begin())
787  Str += ' ';
788  Str += I->getAsString(InAttrGrp);
789  }
790  return Str;
791 }
792 
793 //===----------------------------------------------------------------------===//
794 // AttributeListImpl Definition
795 //===----------------------------------------------------------------------===//
796 
797 /// Map from AttributeList index to the internal array index. Adding one happens
798 /// to work, but it relies on unsigned integer wrapping. MSVC warns about
799 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
800 /// folds it to add anyway.
801 static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
802  return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
803 }
804 
807  : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) {
808  assert(!Sets.empty() && "pointless AttributeListImpl");
809 
810  // There's memory after the node where we can store the entries in.
811  llvm::copy(Sets, getTrailingObjects<AttributeSet>());
812 
813  // Initialize AvailableFunctionAttrs summary bitset.
814  static_assert(Attribute::EndAttrKinds <=
815  sizeof(AvailableFunctionAttrs) * CHAR_BIT,
816  "Too many attributes");
817  static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
818  "function should be stored in slot 0");
819  for (const auto I : Sets[0]) {
820  if (!I.isStringAttribute())
821  AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum();
822  }
823 }
824 
826  Profile(ID, makeArrayRef(begin(), end()));
827 }
828 
830  ArrayRef<AttributeSet> Sets) {
831  for (const auto &Set : Sets)
832  ID.AddPointer(Set.SetNode);
833 }
834 
835 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
837  AttributeList(const_cast<AttributeListImpl *>(this)).dump();
838 }
839 #endif
840 
841 //===----------------------------------------------------------------------===//
842 // AttributeList Construction and Mutation Methods
843 //===----------------------------------------------------------------------===//
844 
846  ArrayRef<AttributeSet> AttrSets) {
847  assert(!AttrSets.empty() && "pointless AttributeListImpl");
848 
849  LLVMContextImpl *pImpl = C.pImpl;
851  AttributeListImpl::Profile(ID, AttrSets);
852 
853  void *InsertPoint;
854  AttributeListImpl *PA =
855  pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
856 
857  // If we didn't find any existing attributes of the same shape then
858  // create a new one and insert it.
859  if (!PA) {
860  // Coallocate entries after the AttributeListImpl itself.
861  void *Mem = ::operator new(
862  AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
863  PA = new (Mem) AttributeListImpl(C, AttrSets);
864  pImpl->AttrsLists.InsertNode(PA, InsertPoint);
865  }
866 
867  // Return the AttributesList that we found or created.
868  return AttributeList(PA);
869 }
870 
873  ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
874  // If there are no attributes then return a null AttributesList pointer.
875  if (Attrs.empty())
876  return {};
877 
878  assert(std::is_sorted(Attrs.begin(), Attrs.end(),
879  [](const std::pair<unsigned, Attribute> &LHS,
880  const std::pair<unsigned, Attribute> &RHS) {
881  return LHS.first < RHS.first;
882  }) && "Misordered Attributes list!");
883  assert(llvm::none_of(Attrs,
884  [](const std::pair<unsigned, Attribute> &Pair) {
885  return Pair.second.hasAttribute(Attribute::None);
886  }) &&
887  "Pointless attribute!");
888 
889  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
890  // list.
892  for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
893  E = Attrs.end(); I != E; ) {
894  unsigned Index = I->first;
896  while (I != E && I->first == Index) {
897  AttrVec.push_back(I->second);
898  ++I;
899  }
900 
901  AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
902  }
903 
904  return get(C, AttrPairVec);
905 }
906 
909  ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
910  // If there are no attributes then return a null AttributesList pointer.
911  if (Attrs.empty())
912  return {};
913 
914  assert(std::is_sorted(Attrs.begin(), Attrs.end(),
915  [](const std::pair<unsigned, AttributeSet> &LHS,
916  const std::pair<unsigned, AttributeSet> &RHS) {
917  return LHS.first < RHS.first;
918  }) &&
919  "Misordered Attributes list!");
920  assert(llvm::none_of(Attrs,
921  [](const std::pair<unsigned, AttributeSet> &Pair) {
922  return !Pair.second.hasAttributes();
923  }) &&
924  "Pointless attribute!");
925 
926  unsigned MaxIndex = Attrs.back().first;
927  // If the MaxIndex is FunctionIndex and there are other indices in front
928  // of it, we need to use the largest of those to get the right size.
929  if (MaxIndex == FunctionIndex && Attrs.size() > 1)
930  MaxIndex = Attrs[Attrs.size() - 2].first;
931 
932  SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
933  for (const auto Pair : Attrs)
934  AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
935 
936  return getImpl(C, AttrVec);
937 }
938 
940  AttributeSet RetAttrs,
941  ArrayRef<AttributeSet> ArgAttrs) {
942  // Scan from the end to find the last argument with attributes. Most
943  // arguments don't have attributes, so it's nice if we can have fewer unique
944  // AttributeListImpls by dropping empty attribute sets at the end of the list.
945  unsigned NumSets = 0;
946  for (size_t I = ArgAttrs.size(); I != 0; --I) {
947  if (ArgAttrs[I - 1].hasAttributes()) {
948  NumSets = I + 2;
949  break;
950  }
951  }
952  if (NumSets == 0) {
953  // Check function and return attributes if we didn't have argument
954  // attributes.
955  if (RetAttrs.hasAttributes())
956  NumSets = 2;
957  else if (FnAttrs.hasAttributes())
958  NumSets = 1;
959  }
960 
961  // If all attribute sets were empty, we can use the empty attribute list.
962  if (NumSets == 0)
963  return {};
964 
966  AttrSets.reserve(NumSets);
967  // If we have any attributes, we always have function attributes.
968  AttrSets.push_back(FnAttrs);
969  if (NumSets > 1)
970  AttrSets.push_back(RetAttrs);
971  if (NumSets > 2) {
972  // Drop the empty argument attribute sets at the end.
973  ArgAttrs = ArgAttrs.take_front(NumSets - 2);
974  AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
975  }
976 
977  return getImpl(C, AttrSets);
978 }
979 
981  const AttrBuilder &B) {
982  if (!B.hasAttributes())
983  return {};
984  Index = attrIdxToArrayIdx(Index);
985  SmallVector<AttributeSet, 8> AttrSets(Index + 1);
986  AttrSets[Index] = AttributeSet::get(C, B);
987  return getImpl(C, AttrSets);
988 }
989 
993  for (const auto K : Kinds)
994  Attrs.emplace_back(Index, Attribute::get(C, K));
995  return get(C, Attrs);
996 }
997 
999  ArrayRef<StringRef> Kinds) {
1001  for (const auto K : Kinds)
1002  Attrs.emplace_back(Index, Attribute::get(C, K));
1003  return get(C, Attrs);
1004 }
1005 
1007  ArrayRef<AttributeList> Attrs) {
1008  if (Attrs.empty())
1009  return {};
1010  if (Attrs.size() == 1)
1011  return Attrs[0];
1012 
1013  unsigned MaxSize = 0;
1014  for (const auto List : Attrs)
1015  MaxSize = std::max(MaxSize, List.getNumAttrSets());
1016 
1017  // If every list was empty, there is no point in merging the lists.
1018  if (MaxSize == 0)
1019  return {};
1020 
1021  SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1022  for (unsigned I = 0; I < MaxSize; ++I) {
1023  AttrBuilder CurBuilder;
1024  for (const auto List : Attrs)
1025  CurBuilder.merge(List.getAttributes(I - 1));
1026  NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1027  }
1028 
1029  return getImpl(C, NewAttrSets);
1030 }
1031 
1033  Attribute::AttrKind Kind) const {
1034  if (hasAttribute(Index, Kind)) return *this;
1035  AttrBuilder B;
1036  B.addAttribute(Kind);
1037  return addAttributes(C, Index, B);
1038 }
1039 
1041  StringRef Kind,
1042  StringRef Value) const {
1043  AttrBuilder B;
1044  B.addAttribute(Kind, Value);
1045  return addAttributes(C, Index, B);
1046 }
1047 
1049  Attribute A) const {
1050  AttrBuilder B;
1051  B.addAttribute(A);
1052  return addAttributes(C, Index, B);
1053 }
1054 
1056  const AttrBuilder &B) const {
1057  if (!B.hasAttributes())
1058  return *this;
1059 
1060  if (!pImpl)
1061  return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1062 
1063 #ifndef NDEBUG
1064  // FIXME it is not obvious how this should work for alignment. For now, say
1065  // we can't change a known alignment.
1066  unsigned OldAlign = getAttributes(Index).getAlignment();
1067  unsigned NewAlign = B.getAlignment();
1068  assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1069  "Attempt to change alignment!");
1070 #endif
1071 
1072  Index = attrIdxToArrayIdx(Index);
1073  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1074  if (Index >= AttrSets.size())
1075  AttrSets.resize(Index + 1);
1076 
1077  AttrBuilder Merged(AttrSets[Index]);
1078  Merged.merge(B);
1079  AttrSets[Index] = AttributeSet::get(C, Merged);
1080 
1081  return getImpl(C, AttrSets);
1082 }
1083 
1085  ArrayRef<unsigned> ArgNos,
1086  Attribute A) const {
1087  assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
1088 
1089  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1090  unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1091  if (MaxIndex >= AttrSets.size())
1092  AttrSets.resize(MaxIndex + 1);
1093 
1094  for (unsigned ArgNo : ArgNos) {
1095  unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1096  AttrBuilder B(AttrSets[Index]);
1097  B.addAttribute(A);
1098  AttrSets[Index] = AttributeSet::get(C, B);
1099  }
1100 
1101  return getImpl(C, AttrSets);
1102 }
1103 
1105  Attribute::AttrKind Kind) const {
1106  if (!hasAttribute(Index, Kind)) return *this;
1107 
1108  Index = attrIdxToArrayIdx(Index);
1109  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1110  assert(Index < AttrSets.size());
1111 
1112  AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1113 
1114  return getImpl(C, AttrSets);
1115 }
1116 
1118  StringRef Kind) const {
1119  if (!hasAttribute(Index, Kind)) return *this;
1120 
1121  Index = attrIdxToArrayIdx(Index);
1122  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1123  assert(Index < AttrSets.size());
1124 
1125  AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1126 
1127  return getImpl(C, AttrSets);
1128 }
1129 
1132  const AttrBuilder &AttrsToRemove) const {
1133  if (!pImpl)
1134  return {};
1135 
1136  Index = attrIdxToArrayIdx(Index);
1137  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1138  if (Index >= AttrSets.size())
1139  AttrSets.resize(Index + 1);
1140 
1141  AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
1142 
1143  return getImpl(C, AttrSets);
1144 }
1145 
1147  unsigned WithoutIndex) const {
1148  if (!pImpl)
1149  return {};
1150  WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1151  if (WithoutIndex >= getNumAttrSets())
1152  return *this;
1153  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1154  AttrSets[WithoutIndex] = AttributeSet();
1155  return getImpl(C, AttrSets);
1156 }
1157 
1159  unsigned Index,
1160  uint64_t Bytes) const {
1161  AttrBuilder B;
1162  B.addDereferenceableAttr(Bytes);
1163  return addAttributes(C, Index, B);
1164 }
1165 
1168  uint64_t Bytes) const {
1169  AttrBuilder B;
1171  return addAttributes(C, Index, B);
1172 }
1173 
1176  unsigned ElemSizeArg,
1177  const Optional<unsigned> &NumElemsArg) {
1178  AttrBuilder B;
1179  B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1180  return addAttributes(C, Index, B);
1181 }
1182 
1183 //===----------------------------------------------------------------------===//
1184 // AttributeList Accessor Methods
1185 //===----------------------------------------------------------------------===//
1186 
1187 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
1188 
1190  return getAttributes(ArgNo + FirstArgIndex);
1191 }
1192 
1194  return getAttributes(ReturnIndex);
1195 }
1196 
1198  return getAttributes(FunctionIndex);
1199 }
1200 
1202  Attribute::AttrKind Kind) const {
1203  return getAttributes(Index).hasAttribute(Kind);
1204 }
1205 
1207  return getAttributes(Index).hasAttribute(Kind);
1208 }
1209 
1210 bool AttributeList::hasAttributes(unsigned Index) const {
1211  return getAttributes(Index).hasAttributes();
1212 }
1213 
1215  return pImpl && pImpl->hasFnAttribute(Kind);
1216 }
1217 
1219  return hasAttribute(AttributeList::FunctionIndex, Kind);
1220 }
1221 
1223  Attribute::AttrKind Kind) const {
1224  return hasAttribute(ArgNo + FirstArgIndex, Kind);
1225 }
1226 
1228  unsigned *Index) const {
1229  if (!pImpl) return false;
1230 
1231  for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
1232  if (hasAttribute(I, Attr)) {
1233  if (Index)
1234  *Index = I;
1235  return true;
1236  }
1237  }
1238 
1239  return false;
1240 }
1241 
1243  Attribute::AttrKind Kind) const {
1244  return getAttributes(Index).getAttribute(Kind);
1245 }
1246 
1248  return getAttributes(Index).getAttribute(Kind);
1249 }
1250 
1252  return getAttributes(ReturnIndex).getAlignment();
1253 }
1254 
1255 unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
1256  return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1257 }
1258 
1259 unsigned AttributeList::getStackAlignment(unsigned Index) const {
1260  return getAttributes(Index).getStackAlignment();
1261 }
1262 
1264  return getAttributes(Index).getDereferenceableBytes();
1265 }
1266 
1269 }
1270 
1271 std::pair<unsigned, Optional<unsigned>>
1273  return getAttributes(Index).getAllocSizeArgs();
1274 }
1275 
1276 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1277  return getAttributes(Index).getAsString(InAttrGrp);
1278 }
1279 
1281  Index = attrIdxToArrayIdx(Index);
1282  if (!pImpl || Index >= getNumAttrSets())
1283  return {};
1284  return pImpl->begin()[Index];
1285 }
1286 
1288  return pImpl ? pImpl->begin() : nullptr;
1289 }
1290 
1292  return pImpl ? pImpl->end() : nullptr;
1293 }
1294 
1295 //===----------------------------------------------------------------------===//
1296 // AttributeList Introspection Methods
1297 //===----------------------------------------------------------------------===//
1298 
1300  return pImpl ? pImpl->NumAttrSets : 0;
1301 }
1302 
1303 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1305  dbgs() << "PAL[\n";
1306 
1307  for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
1308  if (getAttributes(i).hasAttributes())
1309  dbgs() << " { " << i << " => " << getAsString(i) << " }\n";
1310  }
1311 
1312  dbgs() << "]\n";
1313 }
1314 #endif
1315 
1316 //===----------------------------------------------------------------------===//
1317 // AttrBuilder Method Implementations
1318 //===----------------------------------------------------------------------===//
1319 
1320 // FIXME: Remove this ctor, use AttributeSet.
1322  AttributeSet AS = AL.getAttributes(Index);
1323  for (const auto &A : AS)
1324  addAttribute(A);
1325 }
1326 
1328  for (const auto &A : AS)
1329  addAttribute(A);
1330 }
1331 
1333  Attrs.reset();
1334  TargetDepAttrs.clear();
1335  Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1336  AllocSizeArgs = 0;
1337 }
1338 
1340  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1341  assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1342  Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1343  "Adding integer attribute without adding a value!");
1344  Attrs[Val] = true;
1345  return *this;
1346 }
1347 
1349  if (Attr.isStringAttribute()) {
1350  addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1351  return *this;
1352  }
1353 
1355  Attrs[Kind] = true;
1356 
1357  if (Kind == Attribute::Alignment)
1358  Alignment = Attr.getAlignment();
1359  else if (Kind == Attribute::StackAlignment)
1360  StackAlignment = Attr.getStackAlignment();
1361  else if (Kind == Attribute::Dereferenceable)
1362  DerefBytes = Attr.getDereferenceableBytes();
1363  else if (Kind == Attribute::DereferenceableOrNull)
1364  DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1365  else if (Kind == Attribute::AllocSize)
1366  AllocSizeArgs = Attr.getValueAsInt();
1367  return *this;
1368 }
1369 
1371  TargetDepAttrs[A] = V;
1372  return *this;
1373 }
1374 
1376  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1377  Attrs[Val] = false;
1378 
1379  if (Val == Attribute::Alignment)
1380  Alignment = 0;
1381  else if (Val == Attribute::StackAlignment)
1382  StackAlignment = 0;
1383  else if (Val == Attribute::Dereferenceable)
1384  DerefBytes = 0;
1385  else if (Val == Attribute::DereferenceableOrNull)
1386  DerefOrNullBytes = 0;
1387  else if (Val == Attribute::AllocSize)
1388  AllocSizeArgs = 0;
1389 
1390  return *this;
1391 }
1392 
1394  remove(A.getAttributes(Index));
1395  return *this;
1396 }
1397 
1399  auto I = TargetDepAttrs.find(A);
1400  if (I != TargetDepAttrs.end())
1401  TargetDepAttrs.erase(I);
1402  return *this;
1403 }
1404 
1405 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1406  return unpackAllocSizeArgs(AllocSizeArgs);
1407 }
1408 
1410  if (Align == 0) return *this;
1411 
1412  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1413  assert(Align <= 0x40000000 && "Alignment too large.");
1414 
1415  Attrs[Attribute::Alignment] = true;
1416  Alignment = Align;
1417  return *this;
1418 }
1419 
1421  // Default alignment, allow the target to define how to align it.
1422  if (Align == 0) return *this;
1423 
1424  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1425  assert(Align <= 0x100 && "Alignment too large.");
1426 
1427  Attrs[Attribute::StackAlignment] = true;
1428  StackAlignment = Align;
1429  return *this;
1430 }
1431 
1433  if (Bytes == 0) return *this;
1434 
1435  Attrs[Attribute::Dereferenceable] = true;
1436  DerefBytes = Bytes;
1437  return *this;
1438 }
1439 
1441  if (Bytes == 0)
1442  return *this;
1443 
1444  Attrs[Attribute::DereferenceableOrNull] = true;
1445  DerefOrNullBytes = Bytes;
1446  return *this;
1447 }
1448 
1450  const Optional<unsigned> &NumElems) {
1451  return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1452 }
1453 
1455  // (0, 0) is our "not present" value, so we need to check for it here.
1456  assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1457 
1458  Attrs[Attribute::AllocSize] = true;
1459  // Reuse existing machinery to store this as a single 64-bit integer so we can
1460  // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1461  AllocSizeArgs = RawArgs;
1462  return *this;
1463 }
1464 
1466  // FIXME: What if both have alignments, but they don't match?!
1467  if (!Alignment)
1468  Alignment = B.Alignment;
1469 
1470  if (!StackAlignment)
1471  StackAlignment = B.StackAlignment;
1472 
1473  if (!DerefBytes)
1474  DerefBytes = B.DerefBytes;
1475 
1476  if (!DerefOrNullBytes)
1477  DerefOrNullBytes = B.DerefOrNullBytes;
1478 
1479  if (!AllocSizeArgs)
1480  AllocSizeArgs = B.AllocSizeArgs;
1481 
1482  Attrs |= B.Attrs;
1483 
1484  for (auto I : B.td_attrs())
1485  TargetDepAttrs[I.first] = I.second;
1486 
1487  return *this;
1488 }
1489 
1491  // FIXME: What if both have alignments, but they don't match?!
1492  if (B.Alignment)
1493  Alignment = 0;
1494 
1495  if (B.StackAlignment)
1496  StackAlignment = 0;
1497 
1498  if (B.DerefBytes)
1499  DerefBytes = 0;
1500 
1501  if (B.DerefOrNullBytes)
1502  DerefOrNullBytes = 0;
1503 
1504  if (B.AllocSizeArgs)
1505  AllocSizeArgs = 0;
1506 
1507  Attrs &= ~B.Attrs;
1508 
1509  for (auto I : B.td_attrs())
1510  TargetDepAttrs.erase(I.first);
1511 
1512  return *this;
1513 }
1514 
1516  // First check if any of the target independent attributes overlap.
1517  if ((Attrs & B.Attrs).any())
1518  return true;
1519 
1520  // Then check if any target dependent ones do.
1521  for (const auto &I : td_attrs())
1522  if (B.contains(I.first))
1523  return true;
1524 
1525  return false;
1526 }
1527 
1529  return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1530 }
1531 
1533  return !Attrs.none() || !TargetDepAttrs.empty();
1534 }
1535 
1537  AttributeSet AS = AL.getAttributes(Index);
1538 
1539  for (const auto Attr : AS) {
1540  if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1541  if (contains(Attr.getKindAsEnum()))
1542  return true;
1543  } else {
1544  assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1545  return contains(Attr.getKindAsString());
1546  }
1547  }
1548 
1549  return false;
1550 }
1551 
1553  return Alignment != 0;
1554 }
1555 
1557  if (Attrs != B.Attrs)
1558  return false;
1559 
1560  for (td_const_iterator I = TargetDepAttrs.begin(),
1561  E = TargetDepAttrs.end(); I != E; ++I)
1562  if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1563  return false;
1564 
1565  return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1566  DerefBytes == B.DerefBytes;
1567 }
1568 
1569 //===----------------------------------------------------------------------===//
1570 // AttributeFuncs Function Defintions
1571 //===----------------------------------------------------------------------===//
1572 
1573 /// Which attributes cannot be applied to a type.
1575  AttrBuilder Incompatible;
1576 
1577  if (!Ty->isIntegerTy())
1578  // Attribute that only apply to integers.
1579  Incompatible.addAttribute(Attribute::SExt)
1580  .addAttribute(Attribute::ZExt);
1581 
1582  if (!Ty->isPointerTy())
1583  // Attribute that only apply to pointers.
1584  Incompatible.addAttribute(Attribute::ByVal)
1585  .addAttribute(Attribute::Nest)
1587  .addAttribute(Attribute::NoCapture)
1588  .addAttribute(Attribute::NonNull)
1589  .addDereferenceableAttr(1) // the int here is ignored
1590  .addDereferenceableOrNullAttr(1) // the int here is ignored
1591  .addAttribute(Attribute::ReadNone)
1592  .addAttribute(Attribute::ReadOnly)
1593  .addAttribute(Attribute::StructRet)
1594  .addAttribute(Attribute::InAlloca);
1595 
1596  return Incompatible;
1597 }
1598 
1599 template<typename AttrClass>
1600 static bool isEqual(const Function &Caller, const Function &Callee) {
1601  return Caller.getFnAttribute(AttrClass::getKind()) ==
1602  Callee.getFnAttribute(AttrClass::getKind());
1603 }
1604 
1605 /// Compute the logical AND of the attributes of the caller and the
1606 /// callee.
1607 ///
1608 /// This function sets the caller's attribute to false if the callee's attribute
1609 /// is false.
1610 template<typename AttrClass>
1611 static void setAND(Function &Caller, const Function &Callee) {
1612  if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1613  !AttrClass::isSet(Callee, AttrClass::getKind()))
1614  AttrClass::set(Caller, AttrClass::getKind(), false);
1615 }
1616 
1617 /// Compute the logical OR of the attributes of the caller and the
1618 /// callee.
1619 ///
1620 /// This function sets the caller's attribute to true if the callee's attribute
1621 /// is true.
1622 template<typename AttrClass>
1623 static void setOR(Function &Caller, const Function &Callee) {
1624  if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1625  AttrClass::isSet(Callee, AttrClass::getKind()))
1626  AttrClass::set(Caller, AttrClass::getKind(), true);
1627 }
1628 
1629 /// If the inlined function had a higher stack protection level than the
1630 /// calling function, then bump up the caller's stack protection level.
1631 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1632  // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1633  // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1634  // clutter to the IR.
1635  AttrBuilder OldSSPAttr;
1636  OldSSPAttr.addAttribute(Attribute::StackProtect)
1637  .addAttribute(Attribute::StackProtectStrong)
1638  .addAttribute(Attribute::StackProtectReq);
1639 
1640  if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1641  Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1642  Caller.addFnAttr(Attribute::StackProtectReq);
1643  } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1644  !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1645  Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1646  Caller.addFnAttr(Attribute::StackProtectStrong);
1647  } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1648  !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1649  !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1650  Caller.addFnAttr(Attribute::StackProtect);
1651 }
1652 
1653 /// If the inlined function required stack probes, then ensure that
1654 /// the calling function has those too.
1655 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
1656  if (!Caller.hasFnAttribute("probe-stack") &&
1657  Callee.hasFnAttribute("probe-stack")) {
1658  Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
1659  }
1660 }
1661 
1662 /// If the inlined function defines the size of guard region
1663 /// on the stack, then ensure that the calling function defines a guard region
1664 /// that is no larger.
1665 static void
1667  if (Callee.hasFnAttribute("stack-probe-size")) {
1668  uint64_t CalleeStackProbeSize;
1669  Callee.getFnAttribute("stack-probe-size")
1670  .getValueAsString()
1671  .getAsInteger(0, CalleeStackProbeSize);
1672  if (Caller.hasFnAttribute("stack-probe-size")) {
1673  uint64_t CallerStackProbeSize;
1674  Caller.getFnAttribute("stack-probe-size")
1675  .getValueAsString()
1676  .getAsInteger(0, CallerStackProbeSize);
1677  if (CallerStackProbeSize > CalleeStackProbeSize) {
1678  Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1679  }
1680  } else {
1681  Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1682  }
1683  }
1684 }
1685 
1686 /// If the inlined function defines a min legal vector width, then ensure
1687 /// the calling function has the same or larger min legal vector width. If the
1688 /// caller has the attribute, but the callee doesn't, we need to remove the
1689 /// attribute from the caller since we can't make any guarantees about the
1690 /// caller's requirements.
1691 /// This function is called after the inlining decision has been made so we have
1692 /// to merge the attribute this way. Heuristics that would use
1693 /// min-legal-vector-width to determine inline compatibility would need to be
1694 /// handled as part of inline cost analysis.
1695 static void
1697  if (Caller.hasFnAttribute("min-legal-vector-width")) {
1698  if (Callee.hasFnAttribute("min-legal-vector-width")) {
1699  uint64_t CallerVectorWidth;
1700  Caller.getFnAttribute("min-legal-vector-width")
1701  .getValueAsString()
1702  .getAsInteger(0, CallerVectorWidth);
1703  uint64_t CalleeVectorWidth;
1704  Callee.getFnAttribute("min-legal-vector-width")
1705  .getValueAsString()
1706  .getAsInteger(0, CalleeVectorWidth);
1707  if (CallerVectorWidth < CalleeVectorWidth)
1708  Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
1709  } else {
1710  // If the callee doesn't have the attribute then we don't know anything
1711  // and must drop the attribute from the caller.
1712  Caller.removeFnAttr("min-legal-vector-width");
1713  }
1714  }
1715 }
1716 
1717 /// If the inlined function has "null-pointer-is-valid=true" attribute,
1718 /// set this attribute in the caller post inlining.
1719 static void
1721  if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
1722  Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid"));
1723  }
1724 }
1725 
1726 #define GET_ATTR_COMPAT_FUNC
1727 #include "AttributesCompatFunc.inc"
1728 
1730  const Function &Callee) {
1731  return hasCompatibleFnAttrs(Caller, Callee);
1732 }
1733 
1735  const Function &Callee) {
1736  mergeFnAttrs(Caller, Callee);
1737 }
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:754
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:258
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:801
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:452
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:609
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:249
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:464
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:747
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:83
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:731
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:682
AttributeListImpl(LLVMContext &C, ArrayRef< AttributeSet > Sets)
Definition: Attributes.cpp:805
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:783
void reserve(size_type N)
Definition: SmallVector.h:368
uint64_t getDereferenceableBytes() const
Definition: Attributes.cpp:761
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:825
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:432
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:605
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:597
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:776
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:535
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:577
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:512
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:68
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:550
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:573
iterator begin() const
Definition: Attributes.cpp:618
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:462
Attribute getAttribute(Attribute::AttrKind Kind) const
Return the attribute object.
Definition: Attributes.cpp:585
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:482
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:601
size_t size() const
Definition: SmallVector.h:52
StringRef getKindAsString() const
Definition: Attributes.cpp:472
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:70
LLVM_NODISCARD AttributeSet addAttribute(LLVMContext &C, Attribute::AttrKind Kind) const
Add an argument attribute.
Definition: Attributes.cpp:520
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:614
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:593
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:839
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:470
uint64_t getDereferenceableOrNullBytes() const
Definition: Attributes.cpp:768
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:622
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.
void emplace_back(ArgTypes &&... Args)
Definition: SmallVector.h:644
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:209
#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:467
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:477
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:566
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.
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:264
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:482
void dump() const
Definition: Attributes.cpp:627
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:872
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:343