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/StringSwitch.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"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include <algorithm>
35 #include <cassert>
36 #include <cstddef>
37 #include <cstdint>
38 #include <limits>
39 #include <string>
40 #include <tuple>
41 #include <utility>
42 
43 using namespace llvm;
44 
45 //===----------------------------------------------------------------------===//
46 // Attribute Construction Methods
47 //===----------------------------------------------------------------------===//
48 
49 // allocsize has two integer arguments, but because they're both 32 bits, we can
50 // pack them into one 64-bit value, at the cost of making said value
51 // nonsensical.
52 //
53 // In order to do this, we need to reserve one value of the second (optional)
54 // allocsize argument to signify "not present."
55 static const unsigned AllocSizeNumElemsNotPresent = -1;
56 
57 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
58                                   const Optional<unsigned> &NumElemsArg) {
59   assert((!NumElemsArg.hasValue() ||
60           *NumElemsArg != AllocSizeNumElemsNotPresent) &&
61          "Attempting to pack a reserved value");
62 
63   return uint64_t(ElemSizeArg) << 32 |
64          NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
65 }
66 
67 static std::pair<unsigned, Optional<unsigned>>
68 unpackAllocSizeArgs(uint64_t Num) {
69   unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
70   unsigned ElemSizeArg = Num >> 32;
71 
72   Optional<unsigned> NumElemsArg;
73   if (NumElems != AllocSizeNumElemsNotPresent)
74     NumElemsArg = NumElems;
75   return std::make_pair(ElemSizeArg, NumElemsArg);
76 }
77 
78 static uint64_t packVScaleRangeArgs(unsigned MinValue,
79                                     Optional<unsigned> MaxValue) {
80   return uint64_t(MinValue) << 32 | MaxValue.getValueOr(0);
81 }
82 
83 static std::pair<unsigned, Optional<unsigned>>
84 unpackVScaleRangeArgs(uint64_t Value) {
85   unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
86   unsigned MinValue = Value >> 32;
87 
88   return std::make_pair(MinValue,
89                         MaxValue > 0 ? MaxValue : Optional<unsigned>());
90 }
91 
92 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
93                          uint64_t Val) {
94   if (Val)
95     assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
96   else
97     assert(Attribute::isEnumAttrKind(Kind) && "Not an enum attribute");
98 
99   LLVMContextImpl *pImpl = Context.pImpl;
100   FoldingSetNodeID ID;
101   ID.AddInteger(Kind);
102   if (Val) ID.AddInteger(Val);
103 
104   void *InsertPoint;
105   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
106 
107   if (!PA) {
108     // If we didn't find any existing attributes of the same shape then create a
109     // new one and insert it.
110     if (!Val)
111       PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
112     else
113       PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
114     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
115   }
116 
117   // Return the Attribute that we found or created.
118   return Attribute(PA);
119 }
120 
121 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
122   LLVMContextImpl *pImpl = Context.pImpl;
123   FoldingSetNodeID ID;
124   ID.AddString(Kind);
125   if (!Val.empty()) ID.AddString(Val);
126 
127   void *InsertPoint;
128   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
129 
130   if (!PA) {
131     // If we didn't find any existing attributes of the same shape then create a
132     // new one and insert it.
133     void *Mem =
134         pImpl->Alloc.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind, Val),
135                               alignof(StringAttributeImpl));
136     PA = new (Mem) StringAttributeImpl(Kind, Val);
137     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
138   }
139 
140   // Return the Attribute that we found or created.
141   return Attribute(PA);
142 }
143 
144 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
145                          Type *Ty) {
146   assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
147   LLVMContextImpl *pImpl = Context.pImpl;
148   FoldingSetNodeID ID;
149   ID.AddInteger(Kind);
150   ID.AddPointer(Ty);
151 
152   void *InsertPoint;
153   AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
154 
155   if (!PA) {
156     // If we didn't find any existing attributes of the same shape then create a
157     // new one and insert it.
158     PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
159     pImpl->AttrsSet.InsertNode(PA, InsertPoint);
160   }
161 
162   // Return the Attribute that we found or created.
163   return Attribute(PA);
164 }
165 
166 Attribute Attribute::getWithAlignment(LLVMContext &Context, Align A) {
167   assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
168   return get(Context, Alignment, A.value());
169 }
170 
171 Attribute Attribute::getWithStackAlignment(LLVMContext &Context, Align A) {
172   assert(A <= 0x100 && "Alignment too large.");
173   return get(Context, StackAlignment, A.value());
174 }
175 
176 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
177                                                 uint64_t Bytes) {
178   assert(Bytes && "Bytes must be non-zero.");
179   return get(Context, Dereferenceable, Bytes);
180 }
181 
182 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
183                                                        uint64_t Bytes) {
184   assert(Bytes && "Bytes must be non-zero.");
185   return get(Context, DereferenceableOrNull, Bytes);
186 }
187 
188 Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
189   return get(Context, ByVal, Ty);
190 }
191 
192 Attribute Attribute::getWithStructRetType(LLVMContext &Context, Type *Ty) {
193   return get(Context, StructRet, Ty);
194 }
195 
196 Attribute Attribute::getWithByRefType(LLVMContext &Context, Type *Ty) {
197   return get(Context, ByRef, Ty);
198 }
199 
200 Attribute Attribute::getWithPreallocatedType(LLVMContext &Context, Type *Ty) {
201   return get(Context, Preallocated, Ty);
202 }
203 
204 Attribute Attribute::getWithInAllocaType(LLVMContext &Context, Type *Ty) {
205   return get(Context, InAlloca, Ty);
206 }
207 
208 Attribute Attribute::getWithUWTableKind(LLVMContext &Context,
209                                         UWTableKind Kind) {
210   return get(Context, UWTable, uint64_t(Kind));
211 }
212 
213 Attribute
214 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
215                                 const Optional<unsigned> &NumElemsArg) {
216   assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
217          "Invalid allocsize arguments -- given allocsize(0, 0)");
218   return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
219 }
220 
221 Attribute Attribute::getWithVScaleRangeArgs(LLVMContext &Context,
222                                             unsigned MinValue,
223                                             unsigned MaxValue) {
224   return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
225 }
226 
227 Attribute::AttrKind Attribute::getAttrKindFromName(StringRef AttrName) {
228   return StringSwitch<Attribute::AttrKind>(AttrName)
229 #define GET_ATTR_NAMES
230 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
231   .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
232 #include "llvm/IR/Attributes.inc"
233       .Default(Attribute::None);
234 }
235 
236 StringRef Attribute::getNameFromAttrKind(Attribute::AttrKind AttrKind) {
237   switch (AttrKind) {
238 #define GET_ATTR_NAMES
239 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
240   case Attribute::ENUM_NAME:                                                   \
241     return #DISPLAY_NAME;
242 #include "llvm/IR/Attributes.inc"
243   case Attribute::None:
244     return "none";
245   default:
246     llvm_unreachable("invalid Kind");
247   }
248 }
249 
250 bool Attribute::isExistingAttribute(StringRef Name) {
251   return StringSwitch<bool>(Name)
252 #define GET_ATTR_NAMES
253 #define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
254 #include "llvm/IR/Attributes.inc"
255       .Default(false);
256 }
257 
258 //===----------------------------------------------------------------------===//
259 // Attribute Accessor Methods
260 //===----------------------------------------------------------------------===//
261 
262 bool Attribute::isEnumAttribute() const {
263   return pImpl && pImpl->isEnumAttribute();
264 }
265 
266 bool Attribute::isIntAttribute() const {
267   return pImpl && pImpl->isIntAttribute();
268 }
269 
270 bool Attribute::isStringAttribute() const {
271   return pImpl && pImpl->isStringAttribute();
272 }
273 
274 bool Attribute::isTypeAttribute() const {
275   return pImpl && pImpl->isTypeAttribute();
276 }
277 
278 Attribute::AttrKind Attribute::getKindAsEnum() const {
279   if (!pImpl) return None;
280   assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
281          "Invalid attribute type to get the kind as an enum!");
282   return pImpl->getKindAsEnum();
283 }
284 
285 uint64_t Attribute::getValueAsInt() const {
286   if (!pImpl) return 0;
287   assert(isIntAttribute() &&
288          "Expected the attribute to be an integer attribute!");
289   return pImpl->getValueAsInt();
290 }
291 
292 bool Attribute::getValueAsBool() const {
293   if (!pImpl) return false;
294   assert(isStringAttribute() &&
295          "Expected the attribute to be a string attribute!");
296   return pImpl->getValueAsBool();
297 }
298 
299 StringRef Attribute::getKindAsString() const {
300   if (!pImpl) return {};
301   assert(isStringAttribute() &&
302          "Invalid attribute type to get the kind as a string!");
303   return pImpl->getKindAsString();
304 }
305 
306 StringRef Attribute::getValueAsString() const {
307   if (!pImpl) return {};
308   assert(isStringAttribute() &&
309          "Invalid attribute type to get the value as a string!");
310   return pImpl->getValueAsString();
311 }
312 
313 Type *Attribute::getValueAsType() const {
314   if (!pImpl) return {};
315   assert(isTypeAttribute() &&
316          "Invalid attribute type to get the value as a type!");
317   return pImpl->getValueAsType();
318 }
319 
320 
321 bool Attribute::hasAttribute(AttrKind Kind) const {
322   return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
323 }
324 
325 bool Attribute::hasAttribute(StringRef Kind) const {
326   if (!isStringAttribute()) return false;
327   return pImpl && pImpl->hasAttribute(Kind);
328 }
329 
330 MaybeAlign Attribute::getAlignment() const {
331   assert(hasAttribute(Attribute::Alignment) &&
332          "Trying to get alignment from non-alignment attribute!");
333   return MaybeAlign(pImpl->getValueAsInt());
334 }
335 
336 MaybeAlign Attribute::getStackAlignment() const {
337   assert(hasAttribute(Attribute::StackAlignment) &&
338          "Trying to get alignment from non-alignment attribute!");
339   return MaybeAlign(pImpl->getValueAsInt());
340 }
341 
342 uint64_t Attribute::getDereferenceableBytes() const {
343   assert(hasAttribute(Attribute::Dereferenceable) &&
344          "Trying to get dereferenceable bytes from "
345          "non-dereferenceable attribute!");
346   return pImpl->getValueAsInt();
347 }
348 
349 uint64_t Attribute::getDereferenceableOrNullBytes() const {
350   assert(hasAttribute(Attribute::DereferenceableOrNull) &&
351          "Trying to get dereferenceable bytes from "
352          "non-dereferenceable attribute!");
353   return pImpl->getValueAsInt();
354 }
355 
356 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
357   assert(hasAttribute(Attribute::AllocSize) &&
358          "Trying to get allocsize args from non-allocsize attribute");
359   return unpackAllocSizeArgs(pImpl->getValueAsInt());
360 }
361 
362 unsigned Attribute::getVScaleRangeMin() const {
363   assert(hasAttribute(Attribute::VScaleRange) &&
364          "Trying to get vscale args from non-vscale attribute");
365   return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
366 }
367 
368 Optional<unsigned> Attribute::getVScaleRangeMax() const {
369   assert(hasAttribute(Attribute::VScaleRange) &&
370          "Trying to get vscale args from non-vscale attribute");
371   return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
372 }
373 
374 UWTableKind Attribute::getUWTableKind() const {
375   assert(hasAttribute(Attribute::UWTable) &&
376          "Trying to get unwind table kind from non-uwtable attribute");
377   return UWTableKind(pImpl->getValueAsInt());
378 }
379 
380 std::string Attribute::getAsString(bool InAttrGrp) const {
381   if (!pImpl) return {};
382 
383   if (isEnumAttribute())
384     return getNameFromAttrKind(getKindAsEnum()).str();
385 
386   if (isTypeAttribute()) {
387     std::string Result = getNameFromAttrKind(getKindAsEnum()).str();
388     Result += '(';
389     raw_string_ostream OS(Result);
390     getValueAsType()->print(OS, false, true);
391     OS.flush();
392     Result += ')';
393     return Result;
394   }
395 
396   // FIXME: These should be output like this:
397   //
398   //   align=4
399   //   alignstack=8
400   //
401   if (hasAttribute(Attribute::Alignment))
402     return (InAttrGrp ? "align=" + Twine(getValueAsInt())
403                       : "align " + Twine(getValueAsInt()))
404         .str();
405 
406   auto AttrWithBytesToString = [&](const char *Name) {
407     return (InAttrGrp ? Name + ("=" + Twine(getValueAsInt()))
408                       : Name + ("(" + Twine(getValueAsInt())) + ")")
409         .str();
410   };
411 
412   if (hasAttribute(Attribute::StackAlignment))
413     return AttrWithBytesToString("alignstack");
414 
415   if (hasAttribute(Attribute::Dereferenceable))
416     return AttrWithBytesToString("dereferenceable");
417 
418   if (hasAttribute(Attribute::DereferenceableOrNull))
419     return AttrWithBytesToString("dereferenceable_or_null");
420 
421   if (hasAttribute(Attribute::AllocSize)) {
422     unsigned ElemSize;
423     Optional<unsigned> NumElems;
424     std::tie(ElemSize, NumElems) = getAllocSizeArgs();
425 
426     return (NumElems
427                 ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
428                 : "allocsize(" + Twine(ElemSize) + ")")
429         .str();
430   }
431 
432   if (hasAttribute(Attribute::VScaleRange)) {
433     unsigned MinValue = getVScaleRangeMin();
434     Optional<unsigned> MaxValue = getVScaleRangeMax();
435     return ("vscale_range(" + Twine(MinValue) + "," +
436             Twine(MaxValue.getValueOr(0)) + ")")
437         .str();
438   }
439 
440   if (hasAttribute(Attribute::UWTable)) {
441     UWTableKind Kind = getUWTableKind();
442     if (Kind != UWTableKind::None) {
443       return Kind == UWTableKind::Default
444                  ? "uwtable"
445                  : ("uwtable(" +
446                     Twine(Kind == UWTableKind::Sync ? "sync" : "async") + ")")
447                        .str();
448     }
449   }
450 
451   // Convert target-dependent attributes to strings of the form:
452   //
453   //   "kind"
454   //   "kind" = "value"
455   //
456   if (isStringAttribute()) {
457     std::string Result;
458     {
459       raw_string_ostream OS(Result);
460       OS << '"' << getKindAsString() << '"';
461 
462       // Since some attribute strings contain special characters that cannot be
463       // printable, those have to be escaped to make the attribute value
464       // printable as is.  e.g. "\01__gnu_mcount_nc"
465       const auto &AttrVal = pImpl->getValueAsString();
466       if (!AttrVal.empty()) {
467         OS << "=\"";
468         printEscapedString(AttrVal, OS);
469         OS << "\"";
470       }
471     }
472     return Result;
473   }
474 
475   llvm_unreachable("Unknown attribute");
476 }
477 
478 bool Attribute::hasParentContext(LLVMContext &C) const {
479   assert(isValid() && "invalid Attribute doesn't refer to any context");
480   FoldingSetNodeID ID;
481   pImpl->Profile(ID);
482   void *Unused;
483   return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
484 }
485 
486 bool Attribute::operator<(Attribute A) const {
487   if (!pImpl && !A.pImpl) return false;
488   if (!pImpl) return true;
489   if (!A.pImpl) return false;
490   return *pImpl < *A.pImpl;
491 }
492 
493 void Attribute::Profile(FoldingSetNodeID &ID) const {
494   ID.AddPointer(pImpl);
495 }
496 
497 enum AttributeProperty {
498   FnAttr = (1 << 0),
499   ParamAttr = (1 << 1),
500   RetAttr = (1 << 2),
501 };
502 
503 #define GET_ATTR_PROP_TABLE
504 #include "llvm/IR/Attributes.inc"
505 
506 static bool hasAttributeProperty(Attribute::AttrKind Kind,
507                                  AttributeProperty Prop) {
508   unsigned Index = Kind - 1;
509   assert(Index < sizeof(AttrPropTable) / sizeof(AttrPropTable[0]) &&
510          "Invalid attribute kind");
511   return AttrPropTable[Index] & Prop;
512 }
513 
514 bool Attribute::canUseAsFnAttr(AttrKind Kind) {
515   return hasAttributeProperty(Kind, AttributeProperty::FnAttr);
516 }
517 
518 bool Attribute::canUseAsParamAttr(AttrKind Kind) {
519   return hasAttributeProperty(Kind, AttributeProperty::ParamAttr);
520 }
521 
522 bool Attribute::canUseAsRetAttr(AttrKind Kind) {
523   return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
524 }
525 
526 //===----------------------------------------------------------------------===//
527 // AttributeImpl Definition
528 //===----------------------------------------------------------------------===//
529 
530 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
531   if (isStringAttribute()) return false;
532   return getKindAsEnum() == A;
533 }
534 
535 bool AttributeImpl::hasAttribute(StringRef Kind) const {
536   if (!isStringAttribute()) return false;
537   return getKindAsString() == Kind;
538 }
539 
540 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
541   assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
542   return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
543 }
544 
545 uint64_t AttributeImpl::getValueAsInt() const {
546   assert(isIntAttribute());
547   return static_cast<const IntAttributeImpl *>(this)->getValue();
548 }
549 
550 bool AttributeImpl::getValueAsBool() const {
551   assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
552   return getValueAsString() == "true";
553 }
554 
555 StringRef AttributeImpl::getKindAsString() const {
556   assert(isStringAttribute());
557   return static_cast<const StringAttributeImpl *>(this)->getStringKind();
558 }
559 
560 StringRef AttributeImpl::getValueAsString() const {
561   assert(isStringAttribute());
562   return static_cast<const StringAttributeImpl *>(this)->getStringValue();
563 }
564 
565 Type *AttributeImpl::getValueAsType() const {
566   assert(isTypeAttribute());
567   return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
568 }
569 
570 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
571   if (this == &AI)
572     return false;
573 
574   // This sorts the attributes with Attribute::AttrKinds coming first (sorted
575   // relative to their enum value) and then strings.
576   if (!isStringAttribute()) {
577     if (AI.isStringAttribute())
578       return true;
579     if (getKindAsEnum() != AI.getKindAsEnum())
580       return getKindAsEnum() < AI.getKindAsEnum();
581     assert(!AI.isEnumAttribute() && "Non-unique attribute");
582     assert(!AI.isTypeAttribute() && "Comparison of types would be unstable");
583     // TODO: Is this actually needed?
584     assert(AI.isIntAttribute() && "Only possibility left");
585     return getValueAsInt() < AI.getValueAsInt();
586   }
587 
588   if (!AI.isStringAttribute())
589     return false;
590   if (getKindAsString() == AI.getKindAsString())
591     return getValueAsString() < AI.getValueAsString();
592   return getKindAsString() < AI.getKindAsString();
593 }
594 
595 //===----------------------------------------------------------------------===//
596 // AttributeSet Definition
597 //===----------------------------------------------------------------------===//
598 
599 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
600   return AttributeSet(AttributeSetNode::get(C, B));
601 }
602 
603 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
604   return AttributeSet(AttributeSetNode::get(C, Attrs));
605 }
606 
607 AttributeSet AttributeSet::addAttribute(LLVMContext &C,
608                                         Attribute::AttrKind Kind) const {
609   if (hasAttribute(Kind)) return *this;
610   AttrBuilder B(C);
611   B.addAttribute(Kind);
612   return addAttributes(C, AttributeSet::get(C, B));
613 }
614 
615 AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
616                                         StringRef Value) const {
617   AttrBuilder B(C);
618   B.addAttribute(Kind, Value);
619   return addAttributes(C, AttributeSet::get(C, B));
620 }
621 
622 AttributeSet AttributeSet::addAttributes(LLVMContext &C,
623                                          const AttributeSet AS) const {
624   if (!hasAttributes())
625     return AS;
626 
627   if (!AS.hasAttributes())
628     return *this;
629 
630   AttrBuilder B(C, *this);
631   B.merge(AttrBuilder(C, AS));
632   return get(C, B);
633 }
634 
635 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
636                                              Attribute::AttrKind Kind) const {
637   if (!hasAttribute(Kind)) return *this;
638   AttrBuilder B(C, *this);
639   B.removeAttribute(Kind);
640   return get(C, B);
641 }
642 
643 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
644                                              StringRef Kind) const {
645   if (!hasAttribute(Kind)) return *this;
646   AttrBuilder B(C, *this);
647   B.removeAttribute(Kind);
648   return get(C, B);
649 }
650 
651 AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
652                                             const AttributeMask &Attrs) const {
653   AttrBuilder B(C, *this);
654   // If there is nothing to remove, directly return the original set.
655   if (!B.overlaps(Attrs))
656     return *this;
657 
658   B.remove(Attrs);
659   return get(C, B);
660 }
661 
662 unsigned AttributeSet::getNumAttributes() const {
663   return SetNode ? SetNode->getNumAttributes() : 0;
664 }
665 
666 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
667   return SetNode ? SetNode->hasAttribute(Kind) : false;
668 }
669 
670 bool AttributeSet::hasAttribute(StringRef Kind) const {
671   return SetNode ? SetNode->hasAttribute(Kind) : false;
672 }
673 
674 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
675   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
676 }
677 
678 Attribute AttributeSet::getAttribute(StringRef Kind) const {
679   return SetNode ? SetNode->getAttribute(Kind) : Attribute();
680 }
681 
682 MaybeAlign AttributeSet::getAlignment() const {
683   return SetNode ? SetNode->getAlignment() : None;
684 }
685 
686 MaybeAlign AttributeSet::getStackAlignment() const {
687   return SetNode ? SetNode->getStackAlignment() : None;
688 }
689 
690 uint64_t AttributeSet::getDereferenceableBytes() const {
691   return SetNode ? SetNode->getDereferenceableBytes() : 0;
692 }
693 
694 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
695   return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
696 }
697 
698 Type *AttributeSet::getByRefType() const {
699   return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
700 }
701 
702 Type *AttributeSet::getByValType() const {
703   return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
704 }
705 
706 Type *AttributeSet::getStructRetType() const {
707   return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
708 }
709 
710 Type *AttributeSet::getPreallocatedType() const {
711   return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
712 }
713 
714 Type *AttributeSet::getInAllocaType() const {
715   return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
716 }
717 
718 Type *AttributeSet::getElementType() const {
719   return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
720 }
721 
722 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
723   return SetNode ? SetNode->getAllocSizeArgs()
724                  : std::pair<unsigned, Optional<unsigned>>(0, 0);
725 }
726 
727 unsigned AttributeSet::getVScaleRangeMin() const {
728   return SetNode ? SetNode->getVScaleRangeMin() : 1;
729 }
730 
731 Optional<unsigned> AttributeSet::getVScaleRangeMax() const {
732   return SetNode ? SetNode->getVScaleRangeMax() : None;
733 }
734 
735 UWTableKind AttributeSet::getUWTableKind() const {
736   return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
737 }
738 
739 std::string AttributeSet::getAsString(bool InAttrGrp) const {
740   return SetNode ? SetNode->getAsString(InAttrGrp) : "";
741 }
742 
743 bool AttributeSet::hasParentContext(LLVMContext &C) const {
744   assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
745   FoldingSetNodeID ID;
746   SetNode->Profile(ID);
747   void *Unused;
748   return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
749 }
750 
751 AttributeSet::iterator AttributeSet::begin() const {
752   return SetNode ? SetNode->begin() : nullptr;
753 }
754 
755 AttributeSet::iterator AttributeSet::end() const {
756   return SetNode ? SetNode->end() : nullptr;
757 }
758 
759 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
760 LLVM_DUMP_METHOD void AttributeSet::dump() const {
761   dbgs() << "AS =\n";
762     dbgs() << "  { ";
763     dbgs() << getAsString(true) << " }\n";
764 }
765 #endif
766 
767 //===----------------------------------------------------------------------===//
768 // AttributeSetNode Definition
769 //===----------------------------------------------------------------------===//
770 
771 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
772     : NumAttrs(Attrs.size()) {
773   // There's memory after the node where we can store the entries in.
774   llvm::copy(Attrs, getTrailingObjects<Attribute>());
775 
776   for (const auto &I : *this) {
777     if (I.isStringAttribute())
778       StringAttrs.insert({ I.getKindAsString(), I });
779     else
780       AvailableAttrs.addAttribute(I.getKindAsEnum());
781   }
782 }
783 
784 AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
785                                         ArrayRef<Attribute> Attrs) {
786   SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
787   llvm::sort(SortedAttrs);
788   return getSorted(C, SortedAttrs);
789 }
790 
791 AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
792                                               ArrayRef<Attribute> SortedAttrs) {
793   if (SortedAttrs.empty())
794     return nullptr;
795 
796   // Build a key to look up the existing attributes.
797   LLVMContextImpl *pImpl = C.pImpl;
798   FoldingSetNodeID ID;
799 
800   assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
801   for (const auto &Attr : SortedAttrs)
802     Attr.Profile(ID);
803 
804   void *InsertPoint;
805   AttributeSetNode *PA =
806     pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
807 
808   // If we didn't find any existing attributes of the same shape then create a
809   // new one and insert it.
810   if (!PA) {
811     // Coallocate entries after the AttributeSetNode itself.
812     void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
813     PA = new (Mem) AttributeSetNode(SortedAttrs);
814     pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
815   }
816 
817   // Return the AttributeSetNode that we found or created.
818   return PA;
819 }
820 
821 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
822   return getSorted(C, B.attrs());
823 }
824 
825 bool AttributeSetNode::hasAttribute(StringRef Kind) const {
826   return StringAttrs.count(Kind);
827 }
828 
829 Optional<Attribute>
830 AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
831   // Do a quick presence check.
832   if (!hasAttribute(Kind))
833     return None;
834 
835   // Attributes in a set are sorted by enum value, followed by string
836   // attributes. Binary search the one we want.
837   const Attribute *I =
838       std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
839                        [](Attribute A, Attribute::AttrKind Kind) {
840                          return A.getKindAsEnum() < Kind;
841                        });
842   assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
843   return *I;
844 }
845 
846 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
847   if (auto A = findEnumAttribute(Kind))
848     return *A;
849   return {};
850 }
851 
852 Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
853   return StringAttrs.lookup(Kind);
854 }
855 
856 MaybeAlign AttributeSetNode::getAlignment() const {
857   if (auto A = findEnumAttribute(Attribute::Alignment))
858     return A->getAlignment();
859   return None;
860 }
861 
862 MaybeAlign AttributeSetNode::getStackAlignment() const {
863   if (auto A = findEnumAttribute(Attribute::StackAlignment))
864     return A->getStackAlignment();
865   return None;
866 }
867 
868 Type *AttributeSetNode::getAttributeType(Attribute::AttrKind Kind) const {
869   if (auto A = findEnumAttribute(Kind))
870     return A->getValueAsType();
871   return nullptr;
872 }
873 
874 uint64_t AttributeSetNode::getDereferenceableBytes() const {
875   if (auto A = findEnumAttribute(Attribute::Dereferenceable))
876     return A->getDereferenceableBytes();
877   return 0;
878 }
879 
880 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
881   if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
882     return A->getDereferenceableOrNullBytes();
883   return 0;
884 }
885 
886 std::pair<unsigned, Optional<unsigned>>
887 AttributeSetNode::getAllocSizeArgs() const {
888   if (auto A = findEnumAttribute(Attribute::AllocSize))
889     return A->getAllocSizeArgs();
890   return std::make_pair(0, 0);
891 }
892 
893 unsigned AttributeSetNode::getVScaleRangeMin() const {
894   if (auto A = findEnumAttribute(Attribute::VScaleRange))
895     return A->getVScaleRangeMin();
896   return 1;
897 }
898 
899 Optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
900   if (auto A = findEnumAttribute(Attribute::VScaleRange))
901     return A->getVScaleRangeMax();
902   return None;
903 }
904 
905 UWTableKind AttributeSetNode::getUWTableKind() const {
906   if (auto A = findEnumAttribute(Attribute::UWTable))
907     return A->getUWTableKind();
908   return UWTableKind::None;
909 }
910 
911 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
912   std::string Str;
913   for (iterator I = begin(), E = end(); I != E; ++I) {
914     if (I != begin())
915       Str += ' ';
916     Str += I->getAsString(InAttrGrp);
917   }
918   return Str;
919 }
920 
921 //===----------------------------------------------------------------------===//
922 // AttributeListImpl Definition
923 //===----------------------------------------------------------------------===//
924 
925 /// Map from AttributeList index to the internal array index. Adding one happens
926 /// to work, because -1 wraps around to 0.
927 static unsigned attrIdxToArrayIdx(unsigned Index) {
928   return Index + 1;
929 }
930 
931 AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
932     : NumAttrSets(Sets.size()) {
933   assert(!Sets.empty() && "pointless AttributeListImpl");
934 
935   // There's memory after the node where we can store the entries in.
936   llvm::copy(Sets, getTrailingObjects<AttributeSet>());
937 
938   // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
939   // summary bitsets.
940   for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
941     if (!I.isStringAttribute())
942       AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
943 
944   for (const auto &Set : Sets)
945     for (const auto &I : Set)
946       if (!I.isStringAttribute())
947         AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
948 }
949 
950 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
951   Profile(ID, makeArrayRef(begin(), end()));
952 }
953 
954 void AttributeListImpl::Profile(FoldingSetNodeID &ID,
955                                 ArrayRef<AttributeSet> Sets) {
956   for (const auto &Set : Sets)
957     ID.AddPointer(Set.SetNode);
958 }
959 
960 bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind,
961                                         unsigned *Index) const {
962   if (!AvailableSomewhereAttrs.hasAttribute(Kind))
963     return false;
964 
965   if (Index) {
966     for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
967       if (begin()[I].hasAttribute(Kind)) {
968         *Index = I - 1;
969         break;
970       }
971     }
972   }
973 
974   return true;
975 }
976 
977 
978 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
979 LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
980   AttributeList(const_cast<AttributeListImpl *>(this)).dump();
981 }
982 #endif
983 
984 //===----------------------------------------------------------------------===//
985 // AttributeList Construction and Mutation Methods
986 //===----------------------------------------------------------------------===//
987 
988 AttributeList AttributeList::getImpl(LLVMContext &C,
989                                      ArrayRef<AttributeSet> AttrSets) {
990   assert(!AttrSets.empty() && "pointless AttributeListImpl");
991 
992   LLVMContextImpl *pImpl = C.pImpl;
993   FoldingSetNodeID ID;
994   AttributeListImpl::Profile(ID, AttrSets);
995 
996   void *InsertPoint;
997   AttributeListImpl *PA =
998       pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
999 
1000   // If we didn't find any existing attributes of the same shape then
1001   // create a new one and insert it.
1002   if (!PA) {
1003     // Coallocate entries after the AttributeListImpl itself.
1004     void *Mem = pImpl->Alloc.Allocate(
1005         AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1006         alignof(AttributeListImpl));
1007     PA = new (Mem) AttributeListImpl(AttrSets);
1008     pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1009   }
1010 
1011   // Return the AttributesList that we found or created.
1012   return AttributeList(PA);
1013 }
1014 
1015 AttributeList
1016 AttributeList::get(LLVMContext &C,
1017                    ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1018   // If there are no attributes then return a null AttributesList pointer.
1019   if (Attrs.empty())
1020     return {};
1021 
1022   assert(llvm::is_sorted(Attrs,
1023                          [](const std::pair<unsigned, Attribute> &LHS,
1024                             const std::pair<unsigned, Attribute> &RHS) {
1025                            return LHS.first < RHS.first;
1026                          }) &&
1027          "Misordered Attributes list!");
1028   assert(llvm::all_of(Attrs,
1029                       [](const std::pair<unsigned, Attribute> &Pair) {
1030                         return Pair.second.isValid();
1031                       }) &&
1032          "Pointless attribute!");
1033 
1034   // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1035   // list.
1036   SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
1037   for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1038          E = Attrs.end(); I != E; ) {
1039     unsigned Index = I->first;
1040     SmallVector<Attribute, 4> AttrVec;
1041     while (I != E && I->first == Index) {
1042       AttrVec.push_back(I->second);
1043       ++I;
1044     }
1045 
1046     AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1047   }
1048 
1049   return get(C, AttrPairVec);
1050 }
1051 
1052 AttributeList
1053 AttributeList::get(LLVMContext &C,
1054                    ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1055   // If there are no attributes then return a null AttributesList pointer.
1056   if (Attrs.empty())
1057     return {};
1058 
1059   assert(llvm::is_sorted(Attrs,
1060                          [](const std::pair<unsigned, AttributeSet> &LHS,
1061                             const std::pair<unsigned, AttributeSet> &RHS) {
1062                            return LHS.first < RHS.first;
1063                          }) &&
1064          "Misordered Attributes list!");
1065   assert(llvm::none_of(Attrs,
1066                        [](const std::pair<unsigned, AttributeSet> &Pair) {
1067                          return !Pair.second.hasAttributes();
1068                        }) &&
1069          "Pointless attribute!");
1070 
1071   unsigned MaxIndex = Attrs.back().first;
1072   // If the MaxIndex is FunctionIndex and there are other indices in front
1073   // of it, we need to use the largest of those to get the right size.
1074   if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1075     MaxIndex = Attrs[Attrs.size() - 2].first;
1076 
1077   SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1078   for (const auto &Pair : Attrs)
1079     AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1080 
1081   return getImpl(C, AttrVec);
1082 }
1083 
1084 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
1085                                  AttributeSet RetAttrs,
1086                                  ArrayRef<AttributeSet> ArgAttrs) {
1087   // Scan from the end to find the last argument with attributes.  Most
1088   // arguments don't have attributes, so it's nice if we can have fewer unique
1089   // AttributeListImpls by dropping empty attribute sets at the end of the list.
1090   unsigned NumSets = 0;
1091   for (size_t I = ArgAttrs.size(); I != 0; --I) {
1092     if (ArgAttrs[I - 1].hasAttributes()) {
1093       NumSets = I + 2;
1094       break;
1095     }
1096   }
1097   if (NumSets == 0) {
1098     // Check function and return attributes if we didn't have argument
1099     // attributes.
1100     if (RetAttrs.hasAttributes())
1101       NumSets = 2;
1102     else if (FnAttrs.hasAttributes())
1103       NumSets = 1;
1104   }
1105 
1106   // If all attribute sets were empty, we can use the empty attribute list.
1107   if (NumSets == 0)
1108     return {};
1109 
1110   SmallVector<AttributeSet, 8> AttrSets;
1111   AttrSets.reserve(NumSets);
1112   // If we have any attributes, we always have function attributes.
1113   AttrSets.push_back(FnAttrs);
1114   if (NumSets > 1)
1115     AttrSets.push_back(RetAttrs);
1116   if (NumSets > 2) {
1117     // Drop the empty argument attribute sets at the end.
1118     ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1119     llvm::append_range(AttrSets, ArgAttrs);
1120   }
1121 
1122   return getImpl(C, AttrSets);
1123 }
1124 
1125 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1126                                  AttributeSet Attrs) {
1127   if (!Attrs.hasAttributes())
1128     return {};
1129   Index = attrIdxToArrayIdx(Index);
1130   SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1131   AttrSets[Index] = Attrs;
1132   return getImpl(C, AttrSets);
1133 }
1134 
1135 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1136                                  const AttrBuilder &B) {
1137   return get(C, Index, AttributeSet::get(C, B));
1138 }
1139 
1140 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1141                                  ArrayRef<Attribute::AttrKind> Kinds) {
1142   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1143   for (const auto K : Kinds)
1144     Attrs.emplace_back(Index, Attribute::get(C, K));
1145   return get(C, Attrs);
1146 }
1147 
1148 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1149                                  ArrayRef<Attribute::AttrKind> Kinds,
1150                                  ArrayRef<uint64_t> Values) {
1151   assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1152   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1153   auto VI = Values.begin();
1154   for (const auto K : Kinds)
1155     Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
1156   return get(C, Attrs);
1157 }
1158 
1159 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1160                                  ArrayRef<StringRef> Kinds) {
1161   SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1162   for (const auto &K : Kinds)
1163     Attrs.emplace_back(Index, Attribute::get(C, K));
1164   return get(C, Attrs);
1165 }
1166 
1167 AttributeList AttributeList::get(LLVMContext &C,
1168                                  ArrayRef<AttributeList> Attrs) {
1169   if (Attrs.empty())
1170     return {};
1171   if (Attrs.size() == 1)
1172     return Attrs[0];
1173 
1174   unsigned MaxSize = 0;
1175   for (const auto &List : Attrs)
1176     MaxSize = std::max(MaxSize, List.getNumAttrSets());
1177 
1178   // If every list was empty, there is no point in merging the lists.
1179   if (MaxSize == 0)
1180     return {};
1181 
1182   SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1183   for (unsigned I = 0; I < MaxSize; ++I) {
1184     AttrBuilder CurBuilder(C);
1185     for (const auto &List : Attrs)
1186       CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
1187     NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1188   }
1189 
1190   return getImpl(C, NewAttrSets);
1191 }
1192 
1193 AttributeList
1194 AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1195                                    Attribute::AttrKind Kind) const {
1196   if (hasAttributeAtIndex(Index, Kind))
1197     return *this;
1198   AttributeSet Attrs = getAttributes(Index);
1199   // TODO: Insert at correct position and avoid sort.
1200   SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
1201   NewAttrs.push_back(Attribute::get(C, Kind));
1202   return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs));
1203 }
1204 
1205 AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1206                                                  StringRef Kind,
1207                                                  StringRef Value) const {
1208   AttrBuilder B(C);
1209   B.addAttribute(Kind, Value);
1210   return addAttributesAtIndex(C, Index, B);
1211 }
1212 
1213 AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1214                                                  Attribute A) const {
1215   AttrBuilder B(C);
1216   B.addAttribute(A);
1217   return addAttributesAtIndex(C, Index, B);
1218 }
1219 
1220 AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
1221                                                   unsigned Index,
1222                                                   AttributeSet Attrs) const {
1223   Index = attrIdxToArrayIdx(Index);
1224   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1225   if (Index >= AttrSets.size())
1226     AttrSets.resize(Index + 1);
1227   AttrSets[Index] = Attrs;
1228   return AttributeList::getImpl(C, AttrSets);
1229 }
1230 
1231 AttributeList AttributeList::addAttributesAtIndex(LLVMContext &C,
1232                                                   unsigned Index,
1233                                                   const AttrBuilder &B) const {
1234   if (!B.hasAttributes())
1235     return *this;
1236 
1237   if (!pImpl)
1238     return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1239 
1240   AttrBuilder Merged(C, getAttributes(Index));
1241   Merged.merge(B);
1242   return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
1243 }
1244 
1245 AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1246                                                ArrayRef<unsigned> ArgNos,
1247                                                Attribute A) const {
1248   assert(llvm::is_sorted(ArgNos));
1249 
1250   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1251   unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1252   if (MaxIndex >= AttrSets.size())
1253     AttrSets.resize(MaxIndex + 1);
1254 
1255   for (unsigned ArgNo : ArgNos) {
1256     unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1257     AttrBuilder B(C, AttrSets[Index]);
1258     B.addAttribute(A);
1259     AttrSets[Index] = AttributeSet::get(C, B);
1260   }
1261 
1262   return getImpl(C, AttrSets);
1263 }
1264 
1265 AttributeList
1266 AttributeList::removeAttributeAtIndex(LLVMContext &C, unsigned Index,
1267                                       Attribute::AttrKind Kind) const {
1268   if (!hasAttributeAtIndex(Index, Kind))
1269     return *this;
1270 
1271   Index = attrIdxToArrayIdx(Index);
1272   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1273   assert(Index < AttrSets.size());
1274 
1275   AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1276 
1277   return getImpl(C, AttrSets);
1278 }
1279 
1280 AttributeList AttributeList::removeAttributeAtIndex(LLVMContext &C,
1281                                                     unsigned Index,
1282                                                     StringRef Kind) const {
1283   if (!hasAttributeAtIndex(Index, Kind))
1284     return *this;
1285 
1286   Index = attrIdxToArrayIdx(Index);
1287   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1288   assert(Index < AttrSets.size());
1289 
1290   AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1291 
1292   return getImpl(C, AttrSets);
1293 }
1294 
1295 AttributeList AttributeList::removeAttributesAtIndex(
1296     LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
1297   AttributeSet Attrs = getAttributes(Index);
1298   AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
1299   // If nothing was removed, return the original list.
1300   if (Attrs == NewAttrs)
1301     return *this;
1302   return setAttributesAtIndex(C, Index, NewAttrs);
1303 }
1304 
1305 AttributeList
1306 AttributeList::removeAttributesAtIndex(LLVMContext &C,
1307                                        unsigned WithoutIndex) const {
1308   if (!pImpl)
1309     return {};
1310   WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1311   if (WithoutIndex >= getNumAttrSets())
1312     return *this;
1313   SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1314   AttrSets[WithoutIndex] = AttributeSet();
1315   return getImpl(C, AttrSets);
1316 }
1317 
1318 AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C,
1319                                                        uint64_t Bytes) const {
1320   AttrBuilder B(C);
1321   B.addDereferenceableAttr(Bytes);
1322   return addRetAttributes(C, B);
1323 }
1324 
1325 AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
1326                                                          unsigned Index,
1327                                                          uint64_t Bytes) const {
1328   AttrBuilder B(C);
1329   B.addDereferenceableAttr(Bytes);
1330   return addParamAttributes(C, Index, B);
1331 }
1332 
1333 AttributeList
1334 AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,
1335                                                  uint64_t Bytes) const {
1336   AttrBuilder B(C);
1337   B.addDereferenceableOrNullAttr(Bytes);
1338   return addParamAttributes(C, Index, B);
1339 }
1340 
1341 AttributeList
1342 AttributeList::addAllocSizeParamAttr(LLVMContext &C, unsigned Index,
1343                                      unsigned ElemSizeArg,
1344                                      const Optional<unsigned> &NumElemsArg) {
1345   AttrBuilder B(C);
1346   B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1347   return addParamAttributes(C, Index, B);
1348 }
1349 
1350 //===----------------------------------------------------------------------===//
1351 // AttributeList Accessor Methods
1352 //===----------------------------------------------------------------------===//
1353 
1354 AttributeSet AttributeList::getParamAttrs(unsigned ArgNo) const {
1355   return getAttributes(ArgNo + FirstArgIndex);
1356 }
1357 
1358 AttributeSet AttributeList::getRetAttrs() const {
1359   return getAttributes(ReturnIndex);
1360 }
1361 
1362 AttributeSet AttributeList::getFnAttrs() const {
1363   return getAttributes(FunctionIndex);
1364 }
1365 
1366 bool AttributeList::hasAttributeAtIndex(unsigned Index,
1367                                         Attribute::AttrKind Kind) const {
1368   return getAttributes(Index).hasAttribute(Kind);
1369 }
1370 
1371 bool AttributeList::hasAttributeAtIndex(unsigned Index, StringRef Kind) const {
1372   return getAttributes(Index).hasAttribute(Kind);
1373 }
1374 
1375 bool AttributeList::hasAttributesAtIndex(unsigned Index) const {
1376   return getAttributes(Index).hasAttributes();
1377 }
1378 
1379 bool AttributeList::hasFnAttr(Attribute::AttrKind Kind) const {
1380   return pImpl && pImpl->hasFnAttribute(Kind);
1381 }
1382 
1383 bool AttributeList::hasFnAttr(StringRef Kind) const {
1384   return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1385 }
1386 
1387 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1388                                      unsigned *Index) const {
1389   return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1390 }
1391 
1392 Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1393                                              Attribute::AttrKind Kind) const {
1394   return getAttributes(Index).getAttribute(Kind);
1395 }
1396 
1397 Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1398                                              StringRef Kind) const {
1399   return getAttributes(Index).getAttribute(Kind);
1400 }
1401 
1402 MaybeAlign AttributeList::getRetAlignment() const {
1403   return getAttributes(ReturnIndex).getAlignment();
1404 }
1405 
1406 MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
1407   return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1408 }
1409 
1410 MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const {
1411   return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1412 }
1413 
1414 Type *AttributeList::getParamByValType(unsigned Index) const {
1415   return getAttributes(Index+FirstArgIndex).getByValType();
1416 }
1417 
1418 Type *AttributeList::getParamStructRetType(unsigned Index) const {
1419   return getAttributes(Index + FirstArgIndex).getStructRetType();
1420 }
1421 
1422 Type *AttributeList::getParamByRefType(unsigned Index) const {
1423   return getAttributes(Index + FirstArgIndex).getByRefType();
1424 }
1425 
1426 Type *AttributeList::getParamPreallocatedType(unsigned Index) const {
1427   return getAttributes(Index + FirstArgIndex).getPreallocatedType();
1428 }
1429 
1430 Type *AttributeList::getParamInAllocaType(unsigned Index) const {
1431   return getAttributes(Index + FirstArgIndex).getInAllocaType();
1432 }
1433 
1434 Type *AttributeList::getParamElementType(unsigned Index) const {
1435   return getAttributes(Index + FirstArgIndex).getElementType();
1436 }
1437 
1438 MaybeAlign AttributeList::getFnStackAlignment() const {
1439   return getFnAttrs().getStackAlignment();
1440 }
1441 
1442 MaybeAlign AttributeList::getRetStackAlignment() const {
1443   return getRetAttrs().getStackAlignment();
1444 }
1445 
1446 uint64_t AttributeList::getRetDereferenceableBytes() const {
1447   return getRetAttrs().getDereferenceableBytes();
1448 }
1449 
1450 uint64_t AttributeList::getParamDereferenceableBytes(unsigned Index) const {
1451   return getParamAttrs(Index).getDereferenceableBytes();
1452 }
1453 
1454 uint64_t AttributeList::getRetDereferenceableOrNullBytes() const {
1455   return getRetAttrs().getDereferenceableOrNullBytes();
1456 }
1457 
1458 uint64_t
1459 AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const {
1460   return getParamAttrs(Index).getDereferenceableOrNullBytes();
1461 }
1462 
1463 UWTableKind AttributeList::getUWTableKind() const {
1464   return getFnAttrs().getUWTableKind();
1465 }
1466 
1467 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1468   return getAttributes(Index).getAsString(InAttrGrp);
1469 }
1470 
1471 AttributeSet AttributeList::getAttributes(unsigned Index) const {
1472   Index = attrIdxToArrayIdx(Index);
1473   if (!pImpl || Index >= getNumAttrSets())
1474     return {};
1475   return pImpl->begin()[Index];
1476 }
1477 
1478 bool AttributeList::hasParentContext(LLVMContext &C) const {
1479   assert(!isEmpty() && "an empty attribute list has no parent context");
1480   FoldingSetNodeID ID;
1481   pImpl->Profile(ID);
1482   void *Unused;
1483   return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
1484 }
1485 
1486 AttributeList::iterator AttributeList::begin() const {
1487   return pImpl ? pImpl->begin() : nullptr;
1488 }
1489 
1490 AttributeList::iterator AttributeList::end() const {
1491   return pImpl ? pImpl->end() : nullptr;
1492 }
1493 
1494 //===----------------------------------------------------------------------===//
1495 // AttributeList Introspection Methods
1496 //===----------------------------------------------------------------------===//
1497 
1498 unsigned AttributeList::getNumAttrSets() const {
1499   return pImpl ? pImpl->NumAttrSets : 0;
1500 }
1501 
1502 void AttributeList::print(raw_ostream &O) const {
1503   O << "AttributeList[\n";
1504 
1505   for (unsigned i : indexes()) {
1506     if (!getAttributes(i).hasAttributes())
1507       continue;
1508     O << "  { ";
1509     switch (i) {
1510     case AttrIndex::ReturnIndex:
1511       O << "return";
1512       break;
1513     case AttrIndex::FunctionIndex:
1514       O << "function";
1515       break;
1516     default:
1517       O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
1518     }
1519     O << " => " << getAsString(i) << " }\n";
1520   }
1521 
1522   O << "]\n";
1523 }
1524 
1525 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1526 LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); }
1527 #endif
1528 
1529 //===----------------------------------------------------------------------===//
1530 // AttrBuilder Method Implementations
1531 //===----------------------------------------------------------------------===//
1532 
1533 AttrBuilder::AttrBuilder(LLVMContext &Ctx, AttributeSet AS) : Ctx(Ctx) {
1534   append_range(Attrs, AS);
1535   assert(is_sorted(Attrs) && "AttributeSet should be sorted");
1536 }
1537 
1538 void AttrBuilder::clear() { Attrs.clear(); }
1539 
1540 /// Attribute comparator that only compares attribute keys. Enum attributes are
1541 /// sorted before string attributes.
1542 struct AttributeComparator {
1543   bool operator()(Attribute A0, Attribute A1) const {
1544     bool A0IsString = A0.isStringAttribute();
1545     bool A1IsString = A1.isStringAttribute();
1546     if (A0IsString) {
1547       if (A1IsString)
1548         return A0.getKindAsString() < A1.getKindAsString();
1549       else
1550         return false;
1551     }
1552     if (A1IsString)
1553       return true;
1554     return A0.getKindAsEnum() < A1.getKindAsEnum();
1555   }
1556   bool operator()(Attribute A0, Attribute::AttrKind Kind) const {
1557     if (A0.isStringAttribute())
1558       return false;
1559     return A0.getKindAsEnum() < Kind;
1560   }
1561   bool operator()(Attribute A0, StringRef Kind) const {
1562     if (A0.isStringAttribute())
1563       return A0.getKindAsString() < Kind;
1564     return true;
1565   }
1566 };
1567 
1568 template <typename K>
1569 static void addAttributeImpl(SmallVectorImpl<Attribute> &Attrs, K Kind,
1570                              Attribute Attr) {
1571   auto It = lower_bound(Attrs, Kind, AttributeComparator());
1572   if (It != Attrs.end() && It->hasAttribute(Kind))
1573     std::swap(*It, Attr);
1574   else
1575     Attrs.insert(It, Attr);
1576 }
1577 
1578 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1579   if (Attr.isStringAttribute())
1580     addAttributeImpl(Attrs, Attr.getKindAsString(), Attr);
1581   else
1582     addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr);
1583   return *this;
1584 }
1585 
1586 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Kind) {
1587   addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind));
1588   return *this;
1589 }
1590 
1591 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1592   addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V));
1593   return *this;
1594 }
1595 
1596 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1597   assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1598   auto It = lower_bound(Attrs, Val, AttributeComparator());
1599   if (It != Attrs.end() && It->hasAttribute(Val))
1600     Attrs.erase(It);
1601   return *this;
1602 }
1603 
1604 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1605   auto It = lower_bound(Attrs, A, AttributeComparator());
1606   if (It != Attrs.end() && It->hasAttribute(A))
1607     Attrs.erase(It);
1608   return *this;
1609 }
1610 
1611 uint64_t AttrBuilder::getRawIntAttr(Attribute::AttrKind Kind) const {
1612   assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
1613   Attribute A = getAttribute(Kind);
1614   return A.isValid() ? A.getValueAsInt() : 0;
1615 }
1616 
1617 AttrBuilder &AttrBuilder::addRawIntAttr(Attribute::AttrKind Kind,
1618                                         uint64_t Value) {
1619   return addAttribute(Attribute::get(Ctx, Kind, Value));
1620 }
1621 
1622 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1623   return unpackAllocSizeArgs(getRawIntAttr(Attribute::AllocSize));
1624 }
1625 
1626 unsigned AttrBuilder::getVScaleRangeMin() const {
1627   return unpackVScaleRangeArgs(getRawIntAttr(Attribute::VScaleRange)).first;
1628 }
1629 
1630 Optional<unsigned> AttrBuilder::getVScaleRangeMax() const {
1631   return unpackVScaleRangeArgs(getRawIntAttr(Attribute::VScaleRange)).second;
1632 }
1633 
1634 AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
1635   if (!Align)
1636     return *this;
1637 
1638   assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
1639   return addRawIntAttr(Attribute::Alignment, Align->value());
1640 }
1641 
1642 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
1643   // Default alignment, allow the target to define how to align it.
1644   if (!Align)
1645     return *this;
1646 
1647   assert(*Align <= 0x100 && "Alignment too large.");
1648   return addRawIntAttr(Attribute::StackAlignment, Align->value());
1649 }
1650 
1651 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1652   if (Bytes == 0) return *this;
1653 
1654   return addRawIntAttr(Attribute::Dereferenceable, Bytes);
1655 }
1656 
1657 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1658   if (Bytes == 0)
1659     return *this;
1660 
1661   return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
1662 }
1663 
1664 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1665                                            const Optional<unsigned> &NumElems) {
1666   return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1667 }
1668 
1669 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1670   // (0, 0) is our "not present" value, so we need to check for it here.
1671   assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1672   return addRawIntAttr(Attribute::AllocSize, RawArgs);
1673 }
1674 
1675 AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
1676                                              Optional<unsigned> MaxValue) {
1677   return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
1678 }
1679 
1680 AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
1681   // (0, 0) is not present hence ignore this case
1682   if (RawArgs == 0)
1683     return *this;
1684 
1685   return addRawIntAttr(Attribute::VScaleRange, RawArgs);
1686 }
1687 
1688 AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) {
1689   if (Kind == UWTableKind::None)
1690     return *this;
1691   return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
1692 }
1693 
1694 Type *AttrBuilder::getTypeAttr(Attribute::AttrKind Kind) const {
1695   assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
1696   Attribute A = getAttribute(Kind);
1697   return A.isValid() ? A.getValueAsType() : nullptr;
1698 }
1699 
1700 AttrBuilder &AttrBuilder::addTypeAttr(Attribute::AttrKind Kind, Type *Ty) {
1701   return addAttribute(Attribute::get(Ctx, Kind, Ty));
1702 }
1703 
1704 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1705   return addTypeAttr(Attribute::ByVal, Ty);
1706 }
1707 
1708 AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
1709   return addTypeAttr(Attribute::StructRet, Ty);
1710 }
1711 
1712 AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
1713   return addTypeAttr(Attribute::ByRef, Ty);
1714 }
1715 
1716 AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) {
1717   return addTypeAttr(Attribute::Preallocated, Ty);
1718 }
1719 
1720 AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) {
1721   return addTypeAttr(Attribute::InAlloca, Ty);
1722 }
1723 
1724 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1725   // TODO: Could make this O(n) as we're merging two sorted lists.
1726   for (const auto &I : B.attrs())
1727     addAttribute(I);
1728 
1729   return *this;
1730 }
1731 
1732 AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
1733   erase_if(Attrs, [&](Attribute A) { return AM.contains(A); });
1734   return *this;
1735 }
1736 
1737 bool AttrBuilder::overlaps(const AttributeMask &AM) const {
1738   return any_of(Attrs, [&](Attribute A) { return AM.contains(A); });
1739 }
1740 
1741 Attribute AttrBuilder::getAttribute(Attribute::AttrKind A) const {
1742   assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
1743   auto It = lower_bound(Attrs, A, AttributeComparator());
1744   if (It != Attrs.end() && It->hasAttribute(A))
1745     return *It;
1746   return {};
1747 }
1748 
1749 Attribute AttrBuilder::getAttribute(StringRef A) const {
1750   auto It = lower_bound(Attrs, A, AttributeComparator());
1751   if (It != Attrs.end() && It->hasAttribute(A))
1752     return *It;
1753   return {};
1754 }
1755 
1756 bool AttrBuilder::contains(Attribute::AttrKind A) const {
1757   return getAttribute(A).isValid();
1758 }
1759 
1760 bool AttrBuilder::contains(StringRef A) const {
1761   return getAttribute(A).isValid();
1762 }
1763 
1764 bool AttrBuilder::hasAlignmentAttr() const {
1765   return getRawIntAttr(Attribute::Alignment) != 0;
1766 }
1767 
1768 bool AttrBuilder::operator==(const AttrBuilder &B) const {
1769   return Attrs == B.Attrs;
1770 }
1771 
1772 //===----------------------------------------------------------------------===//
1773 // AttributeFuncs Function Defintions
1774 //===----------------------------------------------------------------------===//
1775 
1776 /// Which attributes cannot be applied to a type.
1777 AttributeMask AttributeFuncs::typeIncompatible(Type *Ty) {
1778   AttributeMask Incompatible;
1779 
1780   if (!Ty->isIntegerTy())
1781     // Attributes that only apply to integers.
1782     Incompatible.addAttribute(Attribute::SExt)
1783       .addAttribute(Attribute::ZExt);
1784 
1785   if (!Ty->isPointerTy())
1786     // Attributes that only apply to pointers.
1787     Incompatible.addAttribute(Attribute::Nest)
1788         .addAttribute(Attribute::NoAlias)
1789         .addAttribute(Attribute::NoCapture)
1790         .addAttribute(Attribute::NonNull)
1791         .addAttribute(Attribute::ReadNone)
1792         .addAttribute(Attribute::ReadOnly)
1793         .addAttribute(Attribute::SwiftError)
1794         .addAttribute(Attribute::Dereferenceable)
1795         .addAttribute(Attribute::DereferenceableOrNull)
1796         .addAttribute(Attribute::Preallocated)
1797         .addAttribute(Attribute::InAlloca)
1798         .addAttribute(Attribute::ByVal)
1799         .addAttribute(Attribute::StructRet)
1800         .addAttribute(Attribute::ByRef)
1801         .addAttribute(Attribute::ElementType);
1802 
1803   if (!Ty->isPtrOrPtrVectorTy())
1804     // Attributes that only apply to pointers or vectors of pointers.
1805     Incompatible.addAttribute(Attribute::Alignment);
1806 
1807   // Some attributes can apply to all "values" but there are no `void` values.
1808   if (Ty->isVoidTy())
1809     Incompatible.addAttribute(Attribute::NoUndef);
1810 
1811   return Incompatible;
1812 }
1813 
1814 AttributeMask AttributeFuncs::getUBImplyingAttributes() {
1815   AttributeMask AM;
1816   AM.addAttribute(Attribute::NoUndef);
1817   AM.addAttribute(Attribute::Dereferenceable);
1818   AM.addAttribute(Attribute::DereferenceableOrNull);
1819   return AM;
1820 }
1821 
1822 template<typename AttrClass>
1823 static bool isEqual(const Function &Caller, const Function &Callee) {
1824   return Caller.getFnAttribute(AttrClass::getKind()) ==
1825          Callee.getFnAttribute(AttrClass::getKind());
1826 }
1827 
1828 /// Compute the logical AND of the attributes of the caller and the
1829 /// callee.
1830 ///
1831 /// This function sets the caller's attribute to false if the callee's attribute
1832 /// is false.
1833 template<typename AttrClass>
1834 static void setAND(Function &Caller, const Function &Callee) {
1835   if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1836       !AttrClass::isSet(Callee, AttrClass::getKind()))
1837     AttrClass::set(Caller, AttrClass::getKind(), false);
1838 }
1839 
1840 /// Compute the logical OR of the attributes of the caller and the
1841 /// callee.
1842 ///
1843 /// This function sets the caller's attribute to true if the callee's attribute
1844 /// is true.
1845 template<typename AttrClass>
1846 static void setOR(Function &Caller, const Function &Callee) {
1847   if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1848       AttrClass::isSet(Callee, AttrClass::getKind()))
1849     AttrClass::set(Caller, AttrClass::getKind(), true);
1850 }
1851 
1852 /// If the inlined function had a higher stack protection level than the
1853 /// calling function, then bump up the caller's stack protection level.
1854 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1855   // If the calling function has *no* stack protection level (e.g. it was built
1856   // with Clang's -fno-stack-protector or no_stack_protector attribute), don't
1857   // change it as that could change the program's semantics.
1858   if (!Caller.hasStackProtectorFnAttr())
1859     return;
1860 
1861   // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1862   // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1863   // clutter to the IR.
1864   AttributeMask OldSSPAttr;
1865   OldSSPAttr.addAttribute(Attribute::StackProtect)
1866       .addAttribute(Attribute::StackProtectStrong)
1867       .addAttribute(Attribute::StackProtectReq);
1868 
1869   if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1870     Caller.removeFnAttrs(OldSSPAttr);
1871     Caller.addFnAttr(Attribute::StackProtectReq);
1872   } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1873              !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1874     Caller.removeFnAttrs(OldSSPAttr);
1875     Caller.addFnAttr(Attribute::StackProtectStrong);
1876   } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1877              !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1878              !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1879     Caller.addFnAttr(Attribute::StackProtect);
1880 }
1881 
1882 /// If the inlined function required stack probes, then ensure that
1883 /// the calling function has those too.
1884 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
1885   if (!Caller.hasFnAttribute("probe-stack") &&
1886       Callee.hasFnAttribute("probe-stack")) {
1887     Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
1888   }
1889 }
1890 
1891 /// If the inlined function defines the size of guard region
1892 /// on the stack, then ensure that the calling function defines a guard region
1893 /// that is no larger.
1894 static void
1895 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
1896   Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
1897   if (CalleeAttr.isValid()) {
1898     Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
1899     if (CallerAttr.isValid()) {
1900       uint64_t CallerStackProbeSize, CalleeStackProbeSize;
1901       CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
1902       CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
1903 
1904       if (CallerStackProbeSize > CalleeStackProbeSize) {
1905         Caller.addFnAttr(CalleeAttr);
1906       }
1907     } else {
1908       Caller.addFnAttr(CalleeAttr);
1909     }
1910   }
1911 }
1912 
1913 /// If the inlined function defines a min legal vector width, then ensure
1914 /// the calling function has the same or larger min legal vector width. If the
1915 /// caller has the attribute, but the callee doesn't, we need to remove the
1916 /// attribute from the caller since we can't make any guarantees about the
1917 /// caller's requirements.
1918 /// This function is called after the inlining decision has been made so we have
1919 /// to merge the attribute this way. Heuristics that would use
1920 /// min-legal-vector-width to determine inline compatibility would need to be
1921 /// handled as part of inline cost analysis.
1922 static void
1923 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
1924   Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
1925   if (CallerAttr.isValid()) {
1926     Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
1927     if (CalleeAttr.isValid()) {
1928       uint64_t CallerVectorWidth, CalleeVectorWidth;
1929       CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
1930       CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
1931       if (CallerVectorWidth < CalleeVectorWidth)
1932         Caller.addFnAttr(CalleeAttr);
1933     } else {
1934       // If the callee doesn't have the attribute then we don't know anything
1935       // and must drop the attribute from the caller.
1936       Caller.removeFnAttr("min-legal-vector-width");
1937     }
1938   }
1939 }
1940 
1941 /// If the inlined function has null_pointer_is_valid attribute,
1942 /// set this attribute in the caller post inlining.
1943 static void
1944 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
1945   if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
1946     Caller.addFnAttr(Attribute::NullPointerIsValid);
1947   }
1948 }
1949 
1950 struct EnumAttr {
1951   static bool isSet(const Function &Fn,
1952                     Attribute::AttrKind Kind) {
1953     return Fn.hasFnAttribute(Kind);
1954   }
1955 
1956   static void set(Function &Fn,
1957                   Attribute::AttrKind Kind, bool Val) {
1958     if (Val)
1959       Fn.addFnAttr(Kind);
1960     else
1961       Fn.removeFnAttr(Kind);
1962   }
1963 };
1964 
1965 struct StrBoolAttr {
1966   static bool isSet(const Function &Fn,
1967                     StringRef Kind) {
1968     auto A = Fn.getFnAttribute(Kind);
1969     return A.getValueAsString().equals("true");
1970   }
1971 
1972   static void set(Function &Fn,
1973                   StringRef Kind, bool Val) {
1974     Fn.addFnAttr(Kind, Val ? "true" : "false");
1975   }
1976 };
1977 
1978 #define GET_ATTR_NAMES
1979 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
1980   struct ENUM_NAME##Attr : EnumAttr {                                          \
1981     static enum Attribute::AttrKind getKind() {                                \
1982       return llvm::Attribute::ENUM_NAME;                                       \
1983     }                                                                          \
1984   };
1985 #define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME)                             \
1986   struct ENUM_NAME##Attr : StrBoolAttr {                                       \
1987     static StringRef getKind() { return #DISPLAY_NAME; }                       \
1988   };
1989 #include "llvm/IR/Attributes.inc"
1990 
1991 #define GET_ATTR_COMPAT_FUNC
1992 #include "llvm/IR/Attributes.inc"
1993 
1994 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1995                                          const Function &Callee) {
1996   return hasCompatibleFnAttrs(Caller, Callee);
1997 }
1998 
1999 bool AttributeFuncs::areOutlineCompatible(const Function &A,
2000                                           const Function &B) {
2001   return hasCompatibleFnAttrs(A, B);
2002 }
2003 
2004 void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
2005                                                 const Function &Callee) {
2006   mergeFnAttrs(Caller, Callee);
2007 }
2008 
2009 void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
2010                                                 const Function &ToMerge) {
2011 
2012   // We merge functions so that they meet the most general case.
2013   // For example, if the NoNansFPMathAttr is set in one function, but not in
2014   // the other, in the merged function we can say that the NoNansFPMathAttr
2015   // is not set.
2016   // However if we have the SpeculativeLoadHardeningAttr set true in one
2017   // function, but not the other, we make sure that the function retains
2018   // that aspect in the merged function.
2019   mergeFnAttrs(Base, ToMerge);
2020 }
2021