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