LLVM  4.0.0
Attributes.cpp
Go to the documentation of this file.
1 //===-- Attributes.cpp - Implement AttributesList -------------------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // \file
11 // \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
12 // AttributeSetImpl, and AttributeSet classes.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "llvm/IR/Attributes.h"
17 #include "llvm/IR/Function.h"
18 #include "AttributeImpl.h"
19 #include "LLVMContextImpl.h"
20 #include "llvm/ADT/STLExtras.h"
21 #include "llvm/ADT/StringExtras.h"
22 #include "llvm/IR/Type.h"
23 #include "llvm/Support/Atomic.h"
24 #include "llvm/Support/Debug.h"
26 #include "llvm/Support/Mutex.h"
28 #include <algorithm>
29 using namespace llvm;
30 
31 //===----------------------------------------------------------------------===//
32 // Attribute Construction Methods
33 //===----------------------------------------------------------------------===//
34 
35 // allocsize has two integer arguments, but because they're both 32 bits, we can
36 // pack them into one 64-bit value, at the cost of making said value
37 // nonsensical.
38 //
39 // In order to do this, we need to reserve one value of the second (optional)
40 // allocsize argument to signify "not present."
41 static const unsigned AllocSizeNumElemsNotPresent = -1;
42 
43 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
44  const Optional<unsigned> &NumElemsArg) {
45  assert((!NumElemsArg.hasValue() ||
46  *NumElemsArg != AllocSizeNumElemsNotPresent) &&
47  "Attempting to pack a reserved value");
48 
49  return uint64_t(ElemSizeArg) << 32 |
51 }
52 
53 static std::pair<unsigned, Optional<unsigned>>
54 unpackAllocSizeArgs(uint64_t Num) {
55  unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
56  unsigned ElemSizeArg = Num >> 32;
57 
58  Optional<unsigned> NumElemsArg;
59  if (NumElems != AllocSizeNumElemsNotPresent)
60  NumElemsArg = NumElems;
61  return std::make_pair(ElemSizeArg, NumElemsArg);
62 }
63 
65  uint64_t Val) {
66  LLVMContextImpl *pImpl = Context.pImpl;
68  ID.AddInteger(Kind);
69  if (Val) ID.AddInteger(Val);
70 
71  void *InsertPoint;
72  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
73 
74  if (!PA) {
75  // If we didn't find any existing attributes of the same shape then create a
76  // new one and insert it.
77  if (!Val)
78  PA = new EnumAttributeImpl(Kind);
79  else
80  PA = new IntAttributeImpl(Kind, Val);
81  pImpl->AttrsSet.InsertNode(PA, InsertPoint);
82  }
83 
84  // Return the Attribute that we found or created.
85  return Attribute(PA);
86 }
87 
89  LLVMContextImpl *pImpl = Context.pImpl;
91  ID.AddString(Kind);
92  if (!Val.empty()) ID.AddString(Val);
93 
94  void *InsertPoint;
95  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
96 
97  if (!PA) {
98  // If we didn't find any existing attributes of the same shape then create a
99  // new one and insert it.
100  PA = new StringAttributeImpl(Kind, Val);
101  pImpl->AttrsSet.InsertNode(PA, InsertPoint);
102  }
103 
104  // Return the Attribute that we found or created.
105  return Attribute(PA);
106 }
107 
109  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
110  assert(Align <= 0x40000000 && "Alignment too large.");
111  return get(Context, Alignment, Align);
112 }
113 
115  uint64_t Align) {
116  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
117  assert(Align <= 0x100 && "Alignment too large.");
118  return get(Context, StackAlignment, Align);
119 }
120 
122  uint64_t Bytes) {
123  assert(Bytes && "Bytes must be non-zero.");
124  return get(Context, Dereferenceable, Bytes);
125 }
126 
128  uint64_t Bytes) {
129  assert(Bytes && "Bytes must be non-zero.");
130  return get(Context, DereferenceableOrNull, Bytes);
131 }
132 
133 Attribute
135  const Optional<unsigned> &NumElemsArg) {
136  assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
137  "Invalid allocsize arguments -- given allocsize(0, 0)");
138  return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
139 }
140 
141 //===----------------------------------------------------------------------===//
142 // Attribute Accessor Methods
143 //===----------------------------------------------------------------------===//
144 
146  return pImpl && pImpl->isEnumAttribute();
147 }
148 
150  return pImpl && pImpl->isIntAttribute();
151 }
152 
154  return pImpl && pImpl->isStringAttribute();
155 }
156 
158  if (!pImpl) return None;
160  "Invalid attribute type to get the kind as an enum!");
161  return pImpl->getKindAsEnum();
162 }
163 
164 uint64_t Attribute::getValueAsInt() const {
165  if (!pImpl) return 0;
167  "Expected the attribute to be an integer attribute!");
168  return pImpl->getValueAsInt();
169 }
170 
172  if (!pImpl) return StringRef();
174  "Invalid attribute type to get the kind as a string!");
175  return pImpl->getKindAsString();
176 }
177 
179  if (!pImpl) return StringRef();
181  "Invalid attribute type to get the value as a string!");
182  return pImpl->getValueAsString();
183 }
184 
186  return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
187 }
188 
190  if (!isStringAttribute()) return false;
191  return pImpl && pImpl->hasAttribute(Kind);
192 }
193 
194 unsigned Attribute::getAlignment() const {
195  assert(hasAttribute(Attribute::Alignment) &&
196  "Trying to get alignment from non-alignment attribute!");
197  return pImpl->getValueAsInt();
198 }
199 
201  assert(hasAttribute(Attribute::StackAlignment) &&
202  "Trying to get alignment from non-alignment attribute!");
203  return pImpl->getValueAsInt();
204 }
205 
207  assert(hasAttribute(Attribute::Dereferenceable) &&
208  "Trying to get dereferenceable bytes from "
209  "non-dereferenceable attribute!");
210  return pImpl->getValueAsInt();
211 }
212 
214  assert(hasAttribute(Attribute::DereferenceableOrNull) &&
215  "Trying to get dereferenceable bytes from "
216  "non-dereferenceable attribute!");
217  return pImpl->getValueAsInt();
218 }
219 
220 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
221  assert(hasAttribute(Attribute::AllocSize) &&
222  "Trying to get allocsize args from non-allocsize attribute");
223  return unpackAllocSizeArgs(pImpl->getValueAsInt());
224 }
225 
226 std::string Attribute::getAsString(bool InAttrGrp) const {
227  if (!pImpl) return "";
228 
229  if (hasAttribute(Attribute::SanitizeAddress))
230  return "sanitize_address";
231  if (hasAttribute(Attribute::AlwaysInline))
232  return "alwaysinline";
233  if (hasAttribute(Attribute::ArgMemOnly))
234  return "argmemonly";
235  if (hasAttribute(Attribute::Builtin))
236  return "builtin";
237  if (hasAttribute(Attribute::ByVal))
238  return "byval";
240  return "convergent";
241  if (hasAttribute(Attribute::SwiftError))
242  return "swifterror";
243  if (hasAttribute(Attribute::SwiftSelf))
244  return "swiftself";
245  if (hasAttribute(Attribute::InaccessibleMemOnly))
246  return "inaccessiblememonly";
247  if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
248  return "inaccessiblemem_or_argmemonly";
249  if (hasAttribute(Attribute::InAlloca))
250  return "inalloca";
251  if (hasAttribute(Attribute::InlineHint))
252  return "inlinehint";
253  if (hasAttribute(Attribute::InReg))
254  return "inreg";
256  return "jumptable";
257  if (hasAttribute(Attribute::MinSize))
258  return "minsize";
259  if (hasAttribute(Attribute::Naked))
260  return "naked";
261  if (hasAttribute(Attribute::Nest))
262  return "nest";
264  return "noalias";
265  if (hasAttribute(Attribute::NoBuiltin))
266  return "nobuiltin";
267  if (hasAttribute(Attribute::NoCapture))
268  return "nocapture";
269  if (hasAttribute(Attribute::NoDuplicate))
270  return "noduplicate";
271  if (hasAttribute(Attribute::NoImplicitFloat))
272  return "noimplicitfloat";
273  if (hasAttribute(Attribute::NoInline))
274  return "noinline";
275  if (hasAttribute(Attribute::NonLazyBind))
276  return "nonlazybind";
277  if (hasAttribute(Attribute::NonNull))
278  return "nonnull";
279  if (hasAttribute(Attribute::NoRedZone))
280  return "noredzone";
281  if (hasAttribute(Attribute::NoReturn))
282  return "noreturn";
283  if (hasAttribute(Attribute::NoRecurse))
284  return "norecurse";
285  if (hasAttribute(Attribute::NoUnwind))
286  return "nounwind";
287  if (hasAttribute(Attribute::OptimizeNone))
288  return "optnone";
289  if (hasAttribute(Attribute::OptimizeForSize))
290  return "optsize";
291  if (hasAttribute(Attribute::ReadNone))
292  return "readnone";
294  return "readonly";
296  return "writeonly";
297  if (hasAttribute(Attribute::Returned))
298  return "returned";
299  if (hasAttribute(Attribute::ReturnsTwice))
300  return "returns_twice";
301  if (hasAttribute(Attribute::SExt))
302  return "signext";
303  if (hasAttribute(Attribute::StackProtect))
304  return "ssp";
305  if (hasAttribute(Attribute::StackProtectReq))
306  return "sspreq";
307  if (hasAttribute(Attribute::StackProtectStrong))
308  return "sspstrong";
309  if (hasAttribute(Attribute::SafeStack))
310  return "safestack";
311  if (hasAttribute(Attribute::StructRet))
312  return "sret";
313  if (hasAttribute(Attribute::SanitizeThread))
314  return "sanitize_thread";
315  if (hasAttribute(Attribute::SanitizeMemory))
316  return "sanitize_memory";
317  if (hasAttribute(Attribute::UWTable))
318  return "uwtable";
319  if (hasAttribute(Attribute::ZExt))
320  return "zeroext";
322  return "cold";
323 
324  // FIXME: These should be output like this:
325  //
326  // align=4
327  // alignstack=8
328  //
329  if (hasAttribute(Attribute::Alignment)) {
330  std::string Result;
331  Result += "align";
332  Result += (InAttrGrp) ? "=" : " ";
333  Result += utostr(getValueAsInt());
334  return Result;
335  }
336 
337  auto AttrWithBytesToString = [&](const char *Name) {
338  std::string Result;
339  Result += Name;
340  if (InAttrGrp) {
341  Result += "=";
342  Result += utostr(getValueAsInt());
343  } else {
344  Result += "(";
345  Result += utostr(getValueAsInt());
346  Result += ")";
347  }
348  return Result;
349  };
350 
351  if (hasAttribute(Attribute::StackAlignment))
352  return AttrWithBytesToString("alignstack");
353 
354  if (hasAttribute(Attribute::Dereferenceable))
355  return AttrWithBytesToString("dereferenceable");
356 
357  if (hasAttribute(Attribute::DereferenceableOrNull))
358  return AttrWithBytesToString("dereferenceable_or_null");
359 
360  if (hasAttribute(Attribute::AllocSize)) {
361  unsigned ElemSize;
362  Optional<unsigned> NumElems;
363  std::tie(ElemSize, NumElems) = getAllocSizeArgs();
364 
365  std::string Result = "allocsize(";
366  Result += utostr(ElemSize);
367  if (NumElems.hasValue()) {
368  Result += ',';
369  Result += utostr(*NumElems);
370  }
371  Result += ')';
372  return Result;
373  }
374 
375  // Convert target-dependent attributes to strings of the form:
376  //
377  // "kind"
378  // "kind" = "value"
379  //
380  if (isStringAttribute()) {
381  std::string Result;
382  Result += (Twine('"') + getKindAsString() + Twine('"')).str();
383 
384  std::string AttrVal = pImpl->getValueAsString();
385  if (AttrVal.empty()) return Result;
386 
387  // Since some attribute strings contain special characters that cannot be
388  // printable, those have to be escaped to make the attribute value printable
389  // as is. e.g. "\01__gnu_mcount_nc"
390  {
391  raw_string_ostream OS(Result);
392  OS << "=\"";
393  PrintEscapedString(AttrVal, OS);
394  OS << "\"";
395  }
396  return Result;
397  }
398 
399  llvm_unreachable("Unknown attribute");
400 }
401 
403  if (!pImpl && !A.pImpl) return false;
404  if (!pImpl) return true;
405  if (!A.pImpl) return false;
406  return *pImpl < *A.pImpl;
407 }
408 
409 //===----------------------------------------------------------------------===//
410 // AttributeImpl Definition
411 //===----------------------------------------------------------------------===//
412 
413 // Pin the vtables to this file.
415 void EnumAttributeImpl::anchor() {}
416 void IntAttributeImpl::anchor() {}
417 void StringAttributeImpl::anchor() {}
418 
420  if (isStringAttribute()) return false;
421  return getKindAsEnum() == A;
422 }
423 
425  if (!isStringAttribute()) return false;
426  return getKindAsString() == Kind;
427 }
428 
431  return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
432 }
433 
436  return static_cast<const IntAttributeImpl *>(this)->getValue();
437 }
438 
441  return static_cast<const StringAttributeImpl *>(this)->getStringKind();
442 }
443 
446  return static_cast<const StringAttributeImpl *>(this)->getStringValue();
447 }
448 
450  // This sorts the attributes with Attribute::AttrKinds coming first (sorted
451  // relative to their enum value) and then strings.
452  if (isEnumAttribute()) {
453  if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
454  if (AI.isIntAttribute()) return true;
455  if (AI.isStringAttribute()) return true;
456  }
457 
458  if (isIntAttribute()) {
459  if (AI.isEnumAttribute()) return false;
460  if (AI.isIntAttribute()) {
461  if (getKindAsEnum() == AI.getKindAsEnum())
462  return getValueAsInt() < AI.getValueAsInt();
463  return getKindAsEnum() < AI.getKindAsEnum();
464  }
465  if (AI.isStringAttribute()) return true;
466  }
467 
468  if (AI.isEnumAttribute()) return false;
469  if (AI.isIntAttribute()) return false;
470  if (getKindAsString() == AI.getKindAsString())
471  return getValueAsString() < AI.getValueAsString();
472  return getKindAsString() < AI.getKindAsString();
473 }
474 
475 //===----------------------------------------------------------------------===//
476 // AttributeSetNode Definition
477 //===----------------------------------------------------------------------===//
478 
480  ArrayRef<Attribute> Attrs) {
481  if (Attrs.empty())
482  return nullptr;
483 
484  // Otherwise, build a key to look up the existing attributes.
485  LLVMContextImpl *pImpl = C.pImpl;
487 
488  SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
489  std::sort(SortedAttrs.begin(), SortedAttrs.end());
490 
491  for (Attribute Attr : SortedAttrs)
492  Attr.Profile(ID);
493 
494  void *InsertPoint;
495  AttributeSetNode *PA =
496  pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
497 
498  // If we didn't find any existing attributes of the same shape then create a
499  // new one and insert it.
500  if (!PA) {
501  // Coallocate entries after the AttributeSetNode itself.
502  void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
503  PA = new (Mem) AttributeSetNode(SortedAttrs);
504  pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
505  }
506 
507  // Return the AttributesListNode that we found or created.
508  return PA;
509 }
510 
512  for (Attribute I : *this)
513  if (I.hasAttribute(Kind))
514  return true;
515  return false;
516 }
517 
519  if (hasAttribute(Kind)) {
520  for (Attribute I : *this)
521  if (I.hasAttribute(Kind))
522  return I;
523  }
524  return Attribute();
525 }
526 
528  for (Attribute I : *this)
529  if (I.hasAttribute(Kind))
530  return I;
531  return Attribute();
532 }
533 
535  for (Attribute I : *this)
536  if (I.hasAttribute(Attribute::Alignment))
537  return I.getAlignment();
538  return 0;
539 }
540 
542  for (Attribute I : *this)
543  if (I.hasAttribute(Attribute::StackAlignment))
544  return I.getStackAlignment();
545  return 0;
546 }
547 
549  for (Attribute I : *this)
550  if (I.hasAttribute(Attribute::Dereferenceable))
551  return I.getDereferenceableBytes();
552  return 0;
553 }
554 
556  for (Attribute I : *this)
557  if (I.hasAttribute(Attribute::DereferenceableOrNull))
559  return 0;
560 }
561 
562 std::pair<unsigned, Optional<unsigned>>
564  for (Attribute I : *this)
565  if (I.hasAttribute(Attribute::AllocSize))
566  return I.getAllocSizeArgs();
567  return std::make_pair(0, 0);
568 }
569 
570 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
571  std::string Str;
572  for (iterator I = begin(), E = end(); I != E; ++I) {
573  if (I != begin())
574  Str += ' ';
575  Str += I->getAsString(InAttrGrp);
576  }
577  return Str;
578 }
579 
580 //===----------------------------------------------------------------------===//
581 // AttributeSetImpl Definition
582 //===----------------------------------------------------------------------===//
583 
585  AttributeSet(const_cast<AttributeSetImpl *>(this)).dump();
586 }
587 
588 //===----------------------------------------------------------------------===//
589 // AttributeSet Construction and Mutation Methods
590 //===----------------------------------------------------------------------===//
591 
594  ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs) {
595  LLVMContextImpl *pImpl = C.pImpl;
597  AttributeSetImpl::Profile(ID, Attrs);
598 
599  void *InsertPoint;
600  AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
601 
602  // If we didn't find any existing attributes of the same shape then
603  // create a new one and insert it.
604  if (!PA) {
605  // Coallocate entries after the AttributeSetImpl itself.
606  void *Mem = ::operator new(
607  AttributeSetImpl::totalSizeToAlloc<IndexAttrPair>(Attrs.size()));
608  PA = new (Mem) AttributeSetImpl(C, Attrs);
609  pImpl->AttrsLists.InsertNode(PA, InsertPoint);
610  }
611 
612  // Return the AttributesList that we found or created.
613  return AttributeSet(PA);
614 }
615 
616 AttributeSet AttributeSet::get(LLVMContext &C,
617  ArrayRef<std::pair<unsigned, Attribute> > Attrs){
618  // If there are no attributes then return a null AttributesList pointer.
619  if (Attrs.empty())
620  return AttributeSet();
621 
622  assert(std::is_sorted(Attrs.begin(), Attrs.end(),
623  [](const std::pair<unsigned, Attribute> &LHS,
624  const std::pair<unsigned, Attribute> &RHS) {
625  return LHS.first < RHS.first;
626  }) && "Misordered Attributes list!");
627  assert(none_of(Attrs,
628  [](const std::pair<unsigned, Attribute> &Pair) {
629  return Pair.second.hasAttribute(Attribute::None);
630  }) &&
631  "Pointless attribute!");
632 
633  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
634  // list.
636  for (ArrayRef<std::pair<unsigned, Attribute> >::iterator I = Attrs.begin(),
637  E = Attrs.end(); I != E; ) {
638  unsigned Index = I->first;
640  while (I != E && I->first == Index) {
641  AttrVec.push_back(I->second);
642  ++I;
643  }
644 
645  AttrPairVec.emplace_back(Index, AttributeSetNode::get(C, AttrVec));
646  }
647 
648  return getImpl(C, AttrPairVec);
649 }
650 
651 AttributeSet AttributeSet::get(LLVMContext &C,
652  ArrayRef<std::pair<unsigned,
653  AttributeSetNode*> > Attrs) {
654  // If there are no attributes then return a null AttributesList pointer.
655  if (Attrs.empty())
656  return AttributeSet();
657 
658  return getImpl(C, Attrs);
659 }
660 
661 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
662  const AttrBuilder &B) {
663  if (!B.hasAttributes())
664  return AttributeSet();
665 
666  // Add target-independent attributes.
670  if (!B.contains(Kind))
671  continue;
672 
673  Attribute Attr;
674  switch (Kind) {
675  case Attribute::Alignment:
677  break;
678  case Attribute::StackAlignment:
680  break;
681  case Attribute::Dereferenceable:
683  C, B.getDereferenceableBytes());
684  break;
685  case Attribute::DereferenceableOrNull:
688  break;
689  case Attribute::AllocSize: {
690  auto A = B.getAllocSizeArgs();
691  Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
692  break;
693  }
694  default:
695  Attr = Attribute::get(C, Kind);
696  }
697  Attrs.emplace_back(Index, Attr);
698  }
699 
700  // Add target-dependent (string) attributes.
701  for (const auto &TDA : B.td_attrs())
702  Attrs.emplace_back(Index, Attribute::get(C, TDA.first, TDA.second));
703 
704  return get(C, Attrs);
705 }
706 
707 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
710  for (Attribute::AttrKind K : Kinds)
711  Attrs.emplace_back(Index, Attribute::get(C, K));
712  return get(C, Attrs);
713 }
714 
715 AttributeSet AttributeSet::get(LLVMContext &C, unsigned Index,
716  ArrayRef<StringRef> Kinds) {
718  for (StringRef K : Kinds)
719  Attrs.emplace_back(Index, Attribute::get(C, K));
720  return get(C, Attrs);
721 }
722 
723 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
724  if (Attrs.empty()) return AttributeSet();
725  if (Attrs.size() == 1) return Attrs[0];
726 
728  AttributeSetImpl *A0 = Attrs[0].pImpl;
729  if (A0)
730  AttrNodeVec.append(A0->getNode(0), A0->getNode(A0->getNumSlots()));
731  // Copy all attributes from Attrs into AttrNodeVec while keeping AttrNodeVec
732  // ordered by index. Because we know that each list in Attrs is ordered by
733  // index we only need to merge each successive list in rather than doing a
734  // full sort.
735  for (unsigned I = 1, E = Attrs.size(); I != E; ++I) {
736  AttributeSetImpl *AS = Attrs[I].pImpl;
737  if (!AS) continue;
739  ANVI = AttrNodeVec.begin(), ANVE;
740  for (const IndexAttrPair *AI = AS->getNode(0),
741  *AE = AS->getNode(AS->getNumSlots());
742  AI != AE; ++AI) {
743  ANVE = AttrNodeVec.end();
744  while (ANVI != ANVE && ANVI->first <= AI->first)
745  ++ANVI;
746  ANVI = AttrNodeVec.insert(ANVI, *AI) + 1;
747  }
748  }
749 
750  return getImpl(C, AttrNodeVec);
751 }
752 
754  Attribute::AttrKind Kind) const {
755  if (hasAttribute(Index, Kind)) return *this;
756  return addAttributes(C, Index, AttributeSet::get(C, Index, Kind));
757 }
758 
760  StringRef Kind, StringRef Value) const {
762  B.addAttribute(Kind, Value);
763  return addAttributes(C, Index, AttributeSet::get(C, Index, B));
764 }
765 
767  ArrayRef<unsigned> Indices,
768  Attribute A) const {
769  unsigned I = 0, E = pImpl ? pImpl->getNumSlots() : 0;
770  auto IdxI = Indices.begin(), IdxE = Indices.end();
772 
773  while (I != E && IdxI != IdxE) {
774  if (getSlotIndex(I) < *IdxI)
775  AttrSet.emplace_back(getSlotAttributes(I++));
776  else if (getSlotIndex(I) > *IdxI)
777  AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
778  else {
779  AttrBuilder B(getSlotAttributes(I), *IdxI);
780  B.addAttribute(A);
781  AttrSet.emplace_back(AttributeSet::get(C, *IdxI, B));
782  ++I;
783  ++IdxI;
784  }
785  }
786 
787  while (I != E)
788  AttrSet.emplace_back(getSlotAttributes(I++));
789 
790  while (IdxI != IdxE)
791  AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
792 
793  return get(C, AttrSet);
794 }
795 
797  AttributeSet Attrs) const {
798  if (!pImpl) return Attrs;
799  if (!Attrs.pImpl) return *this;
800 
801 #ifndef NDEBUG
802  // FIXME it is not obvious how this should work for alignment. For now, say
803  // we can't change a known alignment.
804  unsigned OldAlign = getParamAlignment(Index);
805  unsigned NewAlign = Attrs.getParamAlignment(Index);
806  assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
807  "Attempt to change alignment!");
808 #endif
809 
810  // Add the attribute slots before the one we're trying to add.
812  uint64_t NumAttrs = pImpl->getNumSlots();
813  AttributeSet AS;
814  uint64_t LastIndex = 0;
815  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
816  if (getSlotIndex(I) >= Index) {
817  if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
818  break;
819  }
820  LastIndex = I + 1;
821  AttrSet.push_back(getSlotAttributes(I));
822  }
823 
824  // Now add the attribute into the correct slot. There may already be an
825  // AttributeSet there.
826  AttrBuilder B(AS, Index);
827 
828  for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
829  if (Attrs.getSlotIndex(I) == Index) {
830  for (AttributeSetImpl::iterator II = Attrs.pImpl->begin(I),
831  IE = Attrs.pImpl->end(I); II != IE; ++II)
832  B.addAttribute(*II);
833  break;
834  }
835 
836  AttrSet.push_back(AttributeSet::get(C, Index, B));
837 
838  // Add the remaining attribute slots.
839  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
840  AttrSet.push_back(getSlotAttributes(I));
841 
842  return get(C, AttrSet);
843 }
844 
846  Attribute::AttrKind Kind) const {
847  if (!hasAttribute(Index, Kind)) return *this;
848  return removeAttributes(C, Index, AttributeSet::get(C, Index, Kind));
849 }
850 
852  StringRef Kind) const {
853  if (!hasAttribute(Index, Kind)) return *this;
854  return removeAttributes(C, Index, AttributeSet::get(C, Index, Kind));
855 }
856 
858  AttributeSet Attrs) const {
859  if (!pImpl) return AttributeSet();
860  if (!Attrs.pImpl) return *this;
861 
862  // FIXME it is not obvious how this should work for alignment.
863  // For now, say we can't pass in alignment, which no current use does.
864  assert(!Attrs.hasAttribute(Index, Attribute::Alignment) &&
865  "Attempt to change alignment!");
866 
867  // Add the attribute slots before the one we're trying to add.
869  uint64_t NumAttrs = pImpl->getNumSlots();
870  AttributeSet AS;
871  uint64_t LastIndex = 0;
872  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
873  if (getSlotIndex(I) >= Index) {
874  if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
875  break;
876  }
877  LastIndex = I + 1;
878  AttrSet.push_back(getSlotAttributes(I));
879  }
880 
881  // Now remove the attribute from the correct slot. There may already be an
882  // AttributeSet there.
883  AttrBuilder B(AS, Index);
884 
885  for (unsigned I = 0, E = Attrs.pImpl->getNumSlots(); I != E; ++I)
886  if (Attrs.getSlotIndex(I) == Index) {
887  B.removeAttributes(Attrs.pImpl->getSlotAttributes(I), Index);
888  break;
889  }
890 
891  AttrSet.push_back(AttributeSet::get(C, Index, B));
892 
893  // Add the remaining attribute slots.
894  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
895  AttrSet.push_back(getSlotAttributes(I));
896 
897  return get(C, AttrSet);
898 }
899 
901  const AttrBuilder &Attrs) const {
902  if (!pImpl) return AttributeSet();
903 
904  // FIXME it is not obvious how this should work for alignment.
905  // For now, say we can't pass in alignment, which no current use does.
906  assert(!Attrs.hasAlignmentAttr() && "Attempt to change alignment!");
907 
908  // Add the attribute slots before the one we're trying to add.
910  uint64_t NumAttrs = pImpl->getNumSlots();
911  AttributeSet AS;
912  uint64_t LastIndex = 0;
913  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
914  if (getSlotIndex(I) >= Index) {
915  if (getSlotIndex(I) == Index) AS = getSlotAttributes(LastIndex++);
916  break;
917  }
918  LastIndex = I + 1;
919  AttrSet.push_back(getSlotAttributes(I));
920  }
921 
922  // Now remove the attribute from the correct slot. There may already be an
923  // AttributeSet there.
924  AttrBuilder B(AS, Index);
925  B.remove(Attrs);
926 
927  AttrSet.push_back(AttributeSet::get(C, Index, B));
928 
929  // Add the remaining attribute slots.
930  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
931  AttrSet.push_back(getSlotAttributes(I));
932 
933  return get(C, AttrSet);
934 }
935 
937  uint64_t Bytes) const {
939  B.addDereferenceableAttr(Bytes);
940  return addAttributes(C, Index, AttributeSet::get(C, Index, B));
941 }
942 
944  unsigned Index,
945  uint64_t Bytes) const {
948  return addAttributes(C, Index, AttributeSet::get(C, Index, B));
949 }
950 
953  unsigned ElemSizeArg,
954  const Optional<unsigned> &NumElemsArg) {
956  B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
957  return addAttributes(C, Index, AttributeSet::get(C, Index, B));
958 }
959 
960 //===----------------------------------------------------------------------===//
961 // AttributeSet Accessor Methods
962 //===----------------------------------------------------------------------===//
963 
965  return pImpl->getContext();
966 }
967 
969  return pImpl && hasAttributes(Index) ?
970  AttributeSet::get(pImpl->getContext(),
972  std::make_pair(Index, getAttributes(Index)))) :
973  AttributeSet();
974 }
975 
977  return pImpl && hasAttributes(ReturnIndex) ?
978  AttributeSet::get(pImpl->getContext(),
980  std::make_pair(ReturnIndex,
982  AttributeSet();
983 }
984 
986  return pImpl && hasAttributes(FunctionIndex) ?
987  AttributeSet::get(pImpl->getContext(),
989  std::make_pair(FunctionIndex,
991  AttributeSet();
992 }
993 
995  AttributeSetNode *ASN = getAttributes(Index);
996  return ASN && ASN->hasAttribute(Kind);
997 }
998 
999 bool AttributeSet::hasAttribute(unsigned Index, StringRef Kind) const {
1000  AttributeSetNode *ASN = getAttributes(Index);
1001  return ASN && ASN->hasAttribute(Kind);
1002 }
1003 
1004 bool AttributeSet::hasAttributes(unsigned Index) const {
1005  AttributeSetNode *ASN = getAttributes(Index);
1006  return ASN && ASN->hasAttributes();
1007 }
1008 
1010  return pImpl && pImpl->hasFnAttribute(Kind);
1011 }
1012 
1015 }
1016 
1018  unsigned *Index) const {
1019  if (!pImpl) return false;
1020 
1021  for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1022  for (AttributeSetImpl::iterator II = pImpl->begin(I),
1023  IE = pImpl->end(I); II != IE; ++II)
1024  if (II->hasAttribute(Attr)) {
1025  if (Index) *Index = pImpl->getSlotIndex(I);
1026  return true;
1027  }
1028 
1029  return false;
1030 }
1031 
1033  Attribute::AttrKind Kind) const {
1034  AttributeSetNode *ASN = getAttributes(Index);
1035  return ASN ? ASN->getAttribute(Kind) : Attribute();
1036 }
1037 
1039  StringRef Kind) const {
1040  AttributeSetNode *ASN = getAttributes(Index);
1041  return ASN ? ASN->getAttribute(Kind) : Attribute();
1042 }
1043 
1044 unsigned AttributeSet::getParamAlignment(unsigned Index) const {
1045  AttributeSetNode *ASN = getAttributes(Index);
1046  return ASN ? ASN->getAlignment() : 0;
1047 }
1048 
1049 unsigned AttributeSet::getStackAlignment(unsigned Index) const {
1050  AttributeSetNode *ASN = getAttributes(Index);
1051  return ASN ? ASN->getStackAlignment() : 0;
1052 }
1053 
1054 uint64_t AttributeSet::getDereferenceableBytes(unsigned Index) const {
1055  AttributeSetNode *ASN = getAttributes(Index);
1056  return ASN ? ASN->getDereferenceableBytes() : 0;
1057 }
1058 
1059 uint64_t AttributeSet::getDereferenceableOrNullBytes(unsigned Index) const {
1060  AttributeSetNode *ASN = getAttributes(Index);
1061  return ASN ? ASN->getDereferenceableOrNullBytes() : 0;
1062 }
1063 
1064 std::pair<unsigned, Optional<unsigned>>
1065 AttributeSet::getAllocSizeArgs(unsigned Index) const {
1066  AttributeSetNode *ASN = getAttributes(Index);
1067  return ASN ? ASN->getAllocSizeArgs() : std::make_pair(0u, Optional<unsigned>(0u));
1068 }
1069 
1070 std::string AttributeSet::getAsString(unsigned Index, bool InAttrGrp) const {
1071  AttributeSetNode *ASN = getAttributes(Index);
1072  return ASN ? ASN->getAsString(InAttrGrp) : std::string("");
1073 }
1074 
1075 AttributeSetNode *AttributeSet::getAttributes(unsigned Index) const {
1076  if (!pImpl) return nullptr;
1077 
1078  // Loop through to find the attribute node we want.
1079  for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I)
1080  if (pImpl->getSlotIndex(I) == Index)
1081  return pImpl->getSlotNode(I);
1082 
1083  return nullptr;
1084 }
1085 
1087  if (!pImpl)
1088  return ArrayRef<Attribute>().begin();
1089  return pImpl->begin(Slot);
1090 }
1091 
1093  if (!pImpl)
1094  return ArrayRef<Attribute>().end();
1095  return pImpl->end(Slot);
1096 }
1097 
1098 //===----------------------------------------------------------------------===//
1099 // AttributeSet Introspection Methods
1100 //===----------------------------------------------------------------------===//
1101 
1102 unsigned AttributeSet::getNumSlots() const {
1103  return pImpl ? pImpl->getNumSlots() : 0;
1104 }
1105 
1106 unsigned AttributeSet::getSlotIndex(unsigned Slot) const {
1107  assert(pImpl && Slot < pImpl->getNumSlots() &&
1108  "Slot # out of range!");
1109  return pImpl->getSlotIndex(Slot);
1110 }
1111 
1113  assert(pImpl && Slot < pImpl->getNumSlots() &&
1114  "Slot # out of range!");
1115  return pImpl->getSlotAttributes(Slot);
1116 }
1117 
1119  dbgs() << "PAL[\n";
1120 
1121  for (unsigned i = 0, e = getNumSlots(); i < e; ++i) {
1122  uint64_t Index = getSlotIndex(i);
1123  dbgs() << " { ";
1124  if (Index == ~0U)
1125  dbgs() << "~0U";
1126  else
1127  dbgs() << Index;
1128  dbgs() << " => " << getAsString(Index) << " }\n";
1129  }
1130 
1131  dbgs() << "]\n";
1132 }
1133 
1134 //===----------------------------------------------------------------------===//
1135 // AttrBuilder Method Implementations
1136 //===----------------------------------------------------------------------===//
1137 
1139  : Attrs(0), Alignment(0), StackAlignment(0), DerefBytes(0),
1140  DerefOrNullBytes(0), AllocSizeArgs(0) {
1141  AttributeSetImpl *pImpl = AS.pImpl;
1142  if (!pImpl) return;
1143 
1144  for (unsigned I = 0, E = pImpl->getNumSlots(); I != E; ++I) {
1145  if (pImpl->getSlotIndex(I) != Index) continue;
1146 
1147  for (AttributeSetImpl::iterator II = pImpl->begin(I),
1148  IE = pImpl->end(I); II != IE; ++II)
1149  addAttribute(*II);
1150 
1151  break;
1152  }
1153 }
1154 
1156  Attrs.reset();
1157  TargetDepAttrs.clear();
1158  Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1159  AllocSizeArgs = 0;
1160 }
1161 
1163  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1164  assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1165  Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1166  "Adding integer attribute without adding a value!");
1167  Attrs[Val] = true;
1168  return *this;
1169 }
1170 
1172  if (Attr.isStringAttribute()) {
1174  return *this;
1175  }
1176 
1178  Attrs[Kind] = true;
1179 
1180  if (Kind == Attribute::Alignment)
1181  Alignment = Attr.getAlignment();
1182  else if (Kind == Attribute::StackAlignment)
1183  StackAlignment = Attr.getStackAlignment();
1184  else if (Kind == Attribute::Dereferenceable)
1185  DerefBytes = Attr.getDereferenceableBytes();
1186  else if (Kind == Attribute::DereferenceableOrNull)
1187  DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1188  else if (Kind == Attribute::AllocSize)
1189  AllocSizeArgs = Attr.getValueAsInt();
1190  return *this;
1191 }
1192 
1194  TargetDepAttrs[A] = V;
1195  return *this;
1196 }
1197 
1199  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1200  Attrs[Val] = false;
1201 
1202  if (Val == Attribute::Alignment)
1203  Alignment = 0;
1204  else if (Val == Attribute::StackAlignment)
1205  StackAlignment = 0;
1206  else if (Val == Attribute::Dereferenceable)
1207  DerefBytes = 0;
1208  else if (Val == Attribute::DereferenceableOrNull)
1209  DerefOrNullBytes = 0;
1210  else if (Val == Attribute::AllocSize)
1211  AllocSizeArgs = 0;
1212 
1213  return *this;
1214 }
1215 
1217  unsigned Slot = ~0U;
1218  for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1219  if (A.getSlotIndex(I) == Index) {
1220  Slot = I;
1221  break;
1222  }
1223 
1224  assert(Slot != ~0U && "Couldn't find index in AttributeSet!");
1225 
1226  for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
1227  Attribute Attr = *I;
1228  if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1230  } else {
1231  assert(Attr.isStringAttribute() && "Invalid attribute type!");
1233  }
1234  }
1235 
1236  return *this;
1237 }
1238 
1240  std::map<std::string, std::string>::iterator I = TargetDepAttrs.find(A);
1241  if (I != TargetDepAttrs.end())
1242  TargetDepAttrs.erase(I);
1243  return *this;
1244 }
1245 
1246 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1247  return unpackAllocSizeArgs(AllocSizeArgs);
1248 }
1249 
1251  if (Align == 0) return *this;
1252 
1253  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1254  assert(Align <= 0x40000000 && "Alignment too large.");
1255 
1256  Attrs[Attribute::Alignment] = true;
1257  Alignment = Align;
1258  return *this;
1259 }
1260 
1262  // Default alignment, allow the target to define how to align it.
1263  if (Align == 0) return *this;
1264 
1265  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1266  assert(Align <= 0x100 && "Alignment too large.");
1267 
1268  Attrs[Attribute::StackAlignment] = true;
1269  StackAlignment = Align;
1270  return *this;
1271 }
1272 
1274  if (Bytes == 0) return *this;
1275 
1276  Attrs[Attribute::Dereferenceable] = true;
1277  DerefBytes = Bytes;
1278  return *this;
1279 }
1280 
1282  if (Bytes == 0)
1283  return *this;
1284 
1285  Attrs[Attribute::DereferenceableOrNull] = true;
1286  DerefOrNullBytes = Bytes;
1287  return *this;
1288 }
1289 
1291  const Optional<unsigned> &NumElems) {
1292  return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1293 }
1294 
1296  // (0, 0) is our "not present" value, so we need to check for it here.
1297  assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1298 
1299  Attrs[Attribute::AllocSize] = true;
1300  // Reuse existing machinery to store this as a single 64-bit integer so we can
1301  // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1302  AllocSizeArgs = RawArgs;
1303  return *this;
1304 }
1305 
1307  // FIXME: What if both have alignments, but they don't match?!
1308  if (!Alignment)
1309  Alignment = B.Alignment;
1310 
1311  if (!StackAlignment)
1312  StackAlignment = B.StackAlignment;
1313 
1314  if (!DerefBytes)
1315  DerefBytes = B.DerefBytes;
1316 
1317  if (!DerefOrNullBytes)
1318  DerefOrNullBytes = B.DerefOrNullBytes;
1319 
1320  if (!AllocSizeArgs)
1321  AllocSizeArgs = B.AllocSizeArgs;
1322 
1323  Attrs |= B.Attrs;
1324 
1325  for (auto I : B.td_attrs())
1326  TargetDepAttrs[I.first] = I.second;
1327 
1328  return *this;
1329 }
1330 
1332  // FIXME: What if both have alignments, but they don't match?!
1333  if (B.Alignment)
1334  Alignment = 0;
1335 
1336  if (B.StackAlignment)
1337  StackAlignment = 0;
1338 
1339  if (B.DerefBytes)
1340  DerefBytes = 0;
1341 
1342  if (B.DerefOrNullBytes)
1343  DerefOrNullBytes = 0;
1344 
1345  if (B.AllocSizeArgs)
1346  AllocSizeArgs = 0;
1347 
1348  Attrs &= ~B.Attrs;
1349 
1350  for (auto I : B.td_attrs())
1351  TargetDepAttrs.erase(I.first);
1352 
1353  return *this;
1354 }
1355 
1357  // First check if any of the target independent attributes overlap.
1358  if ((Attrs & B.Attrs).any())
1359  return true;
1360 
1361  // Then check if any target dependent ones do.
1362  for (auto I : td_attrs())
1363  if (B.contains(I.first))
1364  return true;
1365 
1366  return false;
1367 }
1368 
1370  return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1371 }
1372 
1374  return !Attrs.none() || !TargetDepAttrs.empty();
1375 }
1376 
1377 bool AttrBuilder::hasAttributes(AttributeSet A, uint64_t Index) const {
1378  unsigned Slot = ~0U;
1379  for (unsigned I = 0, E = A.getNumSlots(); I != E; ++I)
1380  if (A.getSlotIndex(I) == Index) {
1381  Slot = I;
1382  break;
1383  }
1384 
1385  assert(Slot != ~0U && "Couldn't find the index!");
1386 
1387  for (AttributeSet::iterator I = A.begin(Slot), E = A.end(Slot); I != E; ++I) {
1388  Attribute Attr = *I;
1389  if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1390  if (Attrs[I->getKindAsEnum()])
1391  return true;
1392  } else {
1393  assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1394  return TargetDepAttrs.find(Attr.getKindAsString())!=TargetDepAttrs.end();
1395  }
1396  }
1397 
1398  return false;
1399 }
1400 
1402  return Alignment != 0;
1403 }
1404 
1406  if (Attrs != B.Attrs)
1407  return false;
1408 
1409  for (td_const_iterator I = TargetDepAttrs.begin(),
1410  E = TargetDepAttrs.end(); I != E; ++I)
1411  if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1412  return false;
1413 
1414  return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1415  DerefBytes == B.DerefBytes;
1416 }
1417 
1418 //===----------------------------------------------------------------------===//
1419 // AttributeFuncs Function Defintions
1420 //===----------------------------------------------------------------------===//
1421 
1422 /// \brief Which attributes cannot be applied to a type.
1424  AttrBuilder Incompatible;
1425 
1426  if (!Ty->isIntegerTy())
1427  // Attribute that only apply to integers.
1428  Incompatible.addAttribute(Attribute::SExt)
1429  .addAttribute(Attribute::ZExt);
1430 
1431  if (!Ty->isPointerTy())
1432  // Attribute that only apply to pointers.
1433  Incompatible.addAttribute(Attribute::ByVal)
1434  .addAttribute(Attribute::Nest)
1436  .addAttribute(Attribute::NoCapture)
1437  .addAttribute(Attribute::NonNull)
1438  .addDereferenceableAttr(1) // the int here is ignored
1439  .addDereferenceableOrNullAttr(1) // the int here is ignored
1440  .addAttribute(Attribute::ReadNone)
1442  .addAttribute(Attribute::StructRet)
1443  .addAttribute(Attribute::InAlloca);
1444 
1445  return Incompatible;
1446 }
1447 
1448 template<typename AttrClass>
1449 static bool isEqual(const Function &Caller, const Function &Callee) {
1450  return Caller.getFnAttribute(AttrClass::getKind()) ==
1451  Callee.getFnAttribute(AttrClass::getKind());
1452 }
1453 
1454 /// \brief Compute the logical AND of the attributes of the caller and the
1455 /// callee.
1456 ///
1457 /// This function sets the caller's attribute to false if the callee's attribute
1458 /// is false.
1459 template<typename AttrClass>
1460 static void setAND(Function &Caller, const Function &Callee) {
1461  if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1462  !AttrClass::isSet(Callee, AttrClass::getKind()))
1463  AttrClass::set(Caller, AttrClass::getKind(), false);
1464 }
1465 
1466 /// \brief Compute the logical OR of the attributes of the caller and the
1467 /// callee.
1468 ///
1469 /// This function sets the caller's attribute to true if the callee's attribute
1470 /// is true.
1471 template<typename AttrClass>
1472 static void setOR(Function &Caller, const Function &Callee) {
1473  if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1474  AttrClass::isSet(Callee, AttrClass::getKind()))
1475  AttrClass::set(Caller, AttrClass::getKind(), true);
1476 }
1477 
1478 /// \brief If the inlined function had a higher stack protection level than the
1479 /// calling function, then bump up the caller's stack protection level.
1480 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1481  // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1482  // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1483  // clutter to the IR.
1484  AttrBuilder B;
1485  B.addAttribute(Attribute::StackProtect)
1486  .addAttribute(Attribute::StackProtectStrong)
1487  .addAttribute(Attribute::StackProtectReq);
1488  AttributeSet OldSSPAttr = AttributeSet::get(Caller.getContext(),
1490  B);
1491 
1492  if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1493  Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
1494  Caller.addFnAttr(Attribute::StackProtectReq);
1495  } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1496  !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1497  Caller.removeAttributes(AttributeSet::FunctionIndex, OldSSPAttr);
1498  Caller.addFnAttr(Attribute::StackProtectStrong);
1499  } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1500  !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1501  !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1502  Caller.addFnAttr(Attribute::StackProtect);
1503 }
1504 
1505 #define GET_ATTR_COMPAT_FUNC
1506 #include "AttributesCompatFunc.inc"
1507 
1509  const Function &Callee) {
1510  return hasCompatibleFnAttrs(Caller, Callee);
1511 }
1512 
1513 
1515  const Function &Callee) {
1516  mergeFnAttrs(Caller, Callee);
1517 }
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs() const
Definition: Attributes.cpp:563
uint64_t getDereferenceableBytes() const
Definition: Attributes.cpp:548
std::string getAsString(bool InAttrGrp) const
Definition: Attributes.cpp:570
AttributeSet addAllocSizeAttr(LLVMContext &C, unsigned Index, unsigned ElemSizeArg, const Optional< unsigned > &NumElemsArg)
Add the allocsize attribute to the attribute set at the given index.
Definition: Attributes.cpp:952
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
Definition: Function.cpp:226
LLVMContext & Context
FoldingSet< AttributeImpl > AttrsSet
static std::pair< unsigned, Optional< unsigned > > unpackAllocSizeArgs(uint64_t Num)
Definition: Attributes.cpp:54
iterator begin() const
bool hasValue() const
Definition: Optional.h:125
AttributeSet getParamAttributes(unsigned Index) const
The attributes for the specified index are returned.
Definition: Attributes.cpp:968
size_t i
unsigned getStackAlignment(unsigned Index) const
Get the stack alignment.
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds...
Definition: Compiler.h:450
std::string getAsString(unsigned Index, bool InAttrGrp=false) const
Return the attributes at the index as a string.
static Attribute getWithAlignment(LLVMContext &Context, uint64_t Align)
Return a uniquified Attribute object that has the specific alignment set.
Definition: Attributes.cpp:108
void PrintEscapedString(StringRef Name, raw_ostream &Out)
PrintEscapedString - Print each character of the specified string, escaping it if it is not printable...
Definition: AsmWriter.cpp:341
static Attribute getWithDereferenceableBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:121
Attribute
Attributes.
Definition: Dwarf.h:94
iterator end() const
Definition: ArrayRef.h:130
constexpr T getValueOr(U &&value) const LLVM_LVALUE_FUNCTION
Definition: Optional.h:132
uint64_t getAlignment() const
Retrieve the alignment attribute, if it exists.
Definition: Attributes.h:516
uint64_t getDereferenceableOrNullBytes() const
Retrieve the number of dereferenceable_or_null bytes, if the dereferenceable_or_null attribute exists...
Definition: Attributes.h:527
uint64_t getValueAsInt() const
Return the attribute's value as an integer.
Definition: Attributes.cpp:164
AttributeSet getSlotAttributes(unsigned Slot) const
Retrieve the attributes for the given "slot" in the AttrNode list.
iterator begin(unsigned Slot) const
AttrBuilder & addDereferenceableAttr(uint64_t Bytes)
This turns the number of dereferenceable bytes into the form used internally in Attribute.
iterator end() const
unsigned getParamAlignment(unsigned Index) const
Return the alignment for the specified function parameter.
unsigned getAlignment() const
Returns the alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:194
The two locations do not alias at all.
Definition: AliasAnalysis.h:79
Attribute getFnAttribute(Attribute::AttrKind Kind) const
Return the attribute for the given attribute kind.
Definition: Function.h:234
AttrBuilder & addAttribute(Attribute::AttrKind Val)
Add an attribute to the builder.
void Profile(FoldingSetNodeID &ID) const
bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return true if the attribute exists at the given index.
Definition: Attributes.cpp:994
bool hasAlignmentAttr() const
Return true if the builder has an alignment attribute.
bool contains(Attribute::AttrKind A) const
Return true if the builder has the specified attribute.
Definition: Attributes.h:496
bool hasAttribute(AttrKind Val) const
Return true if the attribute is present.
Definition: Attributes.cpp:185
bool areInlineCompatible(const Function &Caller, const Function &Callee)
AttributeSet getRetAttributes() const
The attributes for the ret value are returned.
Definition: Attributes.cpp:976
bool hasAttributes() const
void removeAttributes(unsigned i, AttributeSet Attrs)
removes the attributes from the list of attributes.
Definition: Function.cpp:394
StringRef getKindAsString() const
Return the attribute's kind as a string.
Definition: Attributes.cpp:171
uint64_t getDereferenceableBytes(unsigned Index) const
Get the number of dereferenceable bytes (or zero if unknown).
std::string getAsString(bool InAttrGrp=false) const
The Attribute is converted to a string of equivalent mnemonic.
Definition: Attributes.cpp:226
AttrBuilder & addDereferenceableOrNullAttr(uint64_t Bytes)
This turns the number of dereferenceable_or_null bytes into the form used internally in Attribute...
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
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:220
FoldingSet< AttributeSetImpl > AttrsLists
static Attribute getWithDereferenceableOrNullBytes(LLVMContext &Context, uint64_t Bytes)
Definition: Attributes.cpp:127
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:750
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...
Attribute::AttrKind getKindAsEnum() const
Definition: Attributes.cpp:429
No attributes have been set.
Definition: Attributes.h:69
void AddInteger(signed I)
Definition: FoldingSet.cpp:61
AttributeSet addDereferenceableAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const
Add the dereferenceable attribute to the attribute set at the given index.
Definition: Attributes.cpp:936
friend class AttributeSet
bool operator<(const AttributeImpl &AI) const
Used when sorting the attributes.
Definition: Attributes.cpp:449
uint64_t getDereferenceableBytes() const
Retrieve the number of dereferenceable bytes, if the dereferenceable attribute exists (zero is return...
Definition: Attributes.h:523
static bool isEqual(const Function &Caller, const Function &Callee)
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs(unsigned Index) const
Get the allocsize argument numbers (or pair(0, 0) if unknown).
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
Definition: APInt.h:33
static std::string utostr(uint64_t X, bool isNeg=false)
Definition: StringExtras.h:79
unsigned getStackAlignment() const
Returns the stack alignment field of an attribute as a byte alignment value.
Definition: Attributes.cpp:200
iterator end(unsigned Slot) const
AttrBuilder & remove(const AttrBuilder &B)
Remove the attributes from the builder.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
AttrBuilder & addAllocSizeAttrFromRawRepr(uint64_t RawAllocSizeRepr)
Add an allocsize attribute, using the representation returned by Attribute.getIntValue().
size_t size() const
size - Get the array size.
Definition: ArrayRef.h:141
StringRef getKindAsString() const
Definition: Attributes.cpp:439
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static Attribute getWithStackAlignment(LLVMContext &Context, uint64_t Align)
Definition: Attributes.cpp:114
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:316
uint64_t getDereferenceableBytes() const
Returns the number of dereferenceable bytes from the dereferenceable attribute.
Definition: Attributes.cpp:206
unsigned getNumSlots() const
Return the number of slots used in this attribute list.
bool operator==(const AttrBuilder &B)
constexpr bool isPowerOf2_32(uint32_t Value)
isPowerOf2_32 - This function returns true if the argument is a power of two > 0. ...
Definition: MathExtras.h:399
iterator begin(unsigned Slot) const
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:48
bool isStringAttribute() const
Definition: AttributeImpl.h:62
AttributeSet getSlotAttributes(unsigned Slot) const
Return the attributes at the given slot.
AttributeSet addAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Add an attribute to the attribute set at the given index.
Definition: Attributes.cpp:753
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
Definition: SmallVector.h:115
std::pair< unsigned, Optional< unsigned > > getAllocSizeArgs() const
Retrieve the allocsize args, if the allocsize attribute exists.
unsigned getSlotIndex(unsigned Slot) const
Get the index of the given "slot" in the AttrNodes list.
static const unsigned AllocSizeNumElemsNotPresent
Definition: Attributes.cpp:41
unsigned getAlignment() const
Definition: Attributes.cpp:534
uint64_t getDereferenceableOrNullBytes(unsigned Index) const
Get the number of dereferenceable_or_null bytes (or zero if unknown).
This file defines various helper methods and classes used by LLVMContextImpl for creating and managin...
iterator begin() const
Definition: ArrayRef.h:129
void dump() const
bool overlaps(const AttrBuilder &B) const
Return true if the builder has any attribute that's in the specified builder.
bool isEnumAttribute() const
Return true if the attribute is an Attribute::AttrKind type.
Definition: Attributes.cpp:145
bool empty() const
empty - Check if the array is empty.
Definition: ArrayRef.h:136
Sentinal value useful for loops.
Definition: Attributes.h:72
static void setAND(Function &Caller, const Function &Callee)
Compute the logical AND of the attributes of the caller and the callee.
StringRef getValueAsString() const
Definition: Attributes.cpp:444
void append(in_iter in_start, in_iter in_end)
Add the specified range to the end of the SmallVector.
Definition: SmallVector.h:392
bool isPointerTy() const
True if this is an instance of PointerType.
Definition: Type.h:213
uint64_t getDereferenceableOrNullBytes() const
Returns the number of dereferenceable_or_null bytes from the dereferenceable_or_null attribute...
Definition: Attributes.cpp:213
bool isIntAttribute() const
Definition: AttributeImpl.h:61
bool hasAttribute(Attribute::AttrKind Kind) const
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
LLVMContextImpl *const pImpl
Definition: LLVMContext.h:50
bool hasAttribute(Attribute::AttrKind A) const
Definition: Attributes.cpp:419
bool hasFnAttribute(Attribute::AttrKind Kind) const
Equivalent to hasAttribute(AttributeSet::FunctionIndex, Kind) but may be faster.
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's stack protection level.
LLVMContext & getContext() const
Retrieve the LLVM context.
Definition: Attributes.cpp:964
uint64_t getValueAsInt() const
Definition: Attributes.cpp:434
AttrBuilder & removeAttribute(Attribute::AttrKind Val)
Remove an attribute from the builder.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
Definition: SmallVector.h:843
Attribute::AttrKind getKindAsEnum() const
Return the attribute's kind as an enum (Attribute::AttrKind).
Definition: Attributes.cpp:157
iterator end(unsigned Slot) const
bool isIntAttribute() const
Return true if the attribute is an integer attribute.
Definition: Attributes.cpp:149
static void setOR(Function &Caller, const Function &Callee)
Compute the logical OR of the attributes of the caller and the callee.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
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's and callee's attributes.
AttributeSet removeAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const
Remove the specified attributes at the specified index from this attribute list.
Definition: Attributes.cpp:857
friend class AttributeSetImpl
Definition: Attributes.h:212
bool isIntegerTy() const
True if this is an instance of IntegerType.
Definition: Type.h:195
static AttributeSetNode * get(LLVMContext &C, ArrayRef< Attribute > Attrs)
Definition: Attributes.cpp:479
std::map< std::string, std::string >::const_iterator td_const_iterator
Definition: Attributes.h:564
unsigned getStackAlignment() const
Definition: Attributes.cpp:541
LLVM_NODISCARD LLVM_ATTRIBUTE_ALWAYS_INLINE bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:130
iterator insert(iterator I, T &&Elt)
Definition: SmallVector.h:464
bool operator<(Attribute A) const
Less-than operator. Useful for sorting the attributes list.
Definition: Attributes.cpp:402
AttributeSet removeAttribute(LLVMContext &C, unsigned Index, Attribute::AttrKind Kind) const
Remove the specified attribute at the specified index from this attribute list.
Definition: Attributes.cpp:845
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
Definition: SmallVector.h:119
void emplace_back(ArgTypes &&...Args)
Definition: SmallVector.h:635
bool hasFnAttribute(Attribute::AttrKind Kind) const
Return true if the function has the attribute.
Definition: Function.h:226
unsigned getSlotIndex(unsigned Slot) const
Return the index for the given slot.
AttributeSet addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index, uint64_t Bytes) const
Add the dereferenceable_or_null attribute to the attribute set at the given index.
Definition: Attributes.cpp:943
bool hasAttributes(unsigned Index) const
Return true if attribute exists at the given index.
ArrayRef< Attribute >::iterator iterator
Definition: Attributes.h:377
#define I(x, y, z)
Definition: MD5.cpp:54
static Attribute getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg, const Optional< unsigned > &NumElemsArg)
Definition: Attributes.cpp:134
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...
bool isEnumAttribute() const
Definition: AttributeImpl.h:60
void AddString(StringRef String)
Definition: FoldingSet.cpp:87
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
Definition: Attributes.cpp:153
static Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
Definition: Attributes.cpp:64
uint64_t getDereferenceableOrNullBytes() const
Definition: Attributes.cpp:555
td_range td_attrs()
Definition: Attributes.h:574
AttributeSet getAttributes(LLVMContext &C, ID id)
Return the attributes for an intrinsic.
AttrBuilder & removeAttributes(AttributeSet A, uint64_t Index)
Remove the attributes from the builder.
Attribute getAttribute(unsigned Index, Attribute::AttrKind Kind) const
Return the attribute object that exists at the given index.
AttrBuilder & merge(const AttrBuilder &B)
Add the attributes from the builder.
const unsigned Kind
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition: Attributes.cpp:178
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:463
LLVM Value Representation.
Definition: Value.h:71
bool hasAttributes() const
Return true if the builder has IR-level attributes.
virtual ~AttributeImpl()
Definition: Attributes.cpp:414
AttrBuilder typeIncompatible(Type *Ty)
Which attributes cannot be applied to a type.
AttrBuilder & addStackAlignmentAttr(unsigned Align)
This turns an int stack alignment (which must be a power of 2) into the form used internally in Attri...
FoldingSet< AttributeSetNode > AttrsSetNodes
void addFnAttr(Attribute::AttrKind Kind)
Add function attributes to this function.
Definition: Function.h:182
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:47
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:43
Attribute getAttribute(Attribute::AttrKind Kind) const
Definition: Attributes.cpp:518
unsigned getNumSlots() const
Return the number of slots used in this attribute list.
static LazyValueInfoImpl & getImpl(void *&PImpl, AssumptionCache *AC, const DataLayout *DL, DominatorTree *DT=nullptr)
This lazily constructs the LazyValueInfoImpl.
AttributeSet addAttributes(LLVMContext &C, unsigned Index, AttributeSet Attrs) const
Add attributes to the attribute set at the given index.
Definition: Attributes.cpp:796
std::pair< unsigned, AttributeSetNode * > IndexAttrPair
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
uint64_t getStackAlignment() const
Retrieve the stack alignment attribute, if it exists.
Definition: Attributes.h:519
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results...
Definition: Attributes.h:67
AttributeSet getFnAttributes() const
The function attributes are returned.
Definition: Attributes.cpp:985