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 LLVMContextImpl *pImpl = Context.pImpl;
95 FoldingSetNodeID ID;
96 ID.AddInteger(Kind);
97 if (Val) ID.AddInteger(Val);
98
99 void *InsertPoint;
100 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
101
102 if (!PA) {
103 // If we didn't find any existing attributes of the same shape then create a
104 // new one and insert it.
105 if (!Val)
106 PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
107 else
108 PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
109 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
110 }
111
112 // Return the Attribute that we found or created.
113 return Attribute(PA);
114 }
115
get(LLVMContext & Context,StringRef Kind,StringRef Val)116 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
117 LLVMContextImpl *pImpl = Context.pImpl;
118 FoldingSetNodeID ID;
119 ID.AddString(Kind);
120 if (!Val.empty()) ID.AddString(Val);
121
122 void *InsertPoint;
123 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
124
125 if (!PA) {
126 // If we didn't find any existing attributes of the same shape then create a
127 // new one and insert it.
128 void *Mem =
129 pImpl->Alloc.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind, Val),
130 alignof(StringAttributeImpl));
131 PA = new (Mem) StringAttributeImpl(Kind, Val);
132 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
133 }
134
135 // Return the Attribute that we found or created.
136 return Attribute(PA);
137 }
138
get(LLVMContext & Context,Attribute::AttrKind Kind,Type * Ty)139 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
140 Type *Ty) {
141 LLVMContextImpl *pImpl = Context.pImpl;
142 FoldingSetNodeID ID;
143 ID.AddInteger(Kind);
144 ID.AddPointer(Ty);
145
146 void *InsertPoint;
147 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
148
149 if (!PA) {
150 // If we didn't find any existing attributes of the same shape then create a
151 // new one and insert it.
152 PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
153 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
154 }
155
156 // Return the Attribute that we found or created.
157 return Attribute(PA);
158 }
159
getWithAlignment(LLVMContext & Context,Align A)160 Attribute Attribute::getWithAlignment(LLVMContext &Context, Align A) {
161 assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
162 return get(Context, Alignment, A.value());
163 }
164
getWithStackAlignment(LLVMContext & Context,Align A)165 Attribute Attribute::getWithStackAlignment(LLVMContext &Context, Align A) {
166 assert(A <= 0x100 && "Alignment too large.");
167 return get(Context, StackAlignment, A.value());
168 }
169
getWithDereferenceableBytes(LLVMContext & Context,uint64_t Bytes)170 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
171 uint64_t Bytes) {
172 assert(Bytes && "Bytes must be non-zero.");
173 return get(Context, Dereferenceable, Bytes);
174 }
175
getWithDereferenceableOrNullBytes(LLVMContext & Context,uint64_t Bytes)176 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
177 uint64_t Bytes) {
178 assert(Bytes && "Bytes must be non-zero.");
179 return get(Context, DereferenceableOrNull, Bytes);
180 }
181
getWithByValType(LLVMContext & Context,Type * Ty)182 Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
183 return get(Context, ByVal, Ty);
184 }
185
getWithStructRetType(LLVMContext & Context,Type * Ty)186 Attribute Attribute::getWithStructRetType(LLVMContext &Context, Type *Ty) {
187 return get(Context, StructRet, Ty);
188 }
189
getWithByRefType(LLVMContext & Context,Type * Ty)190 Attribute Attribute::getWithByRefType(LLVMContext &Context, Type *Ty) {
191 return get(Context, ByRef, Ty);
192 }
193
getWithPreallocatedType(LLVMContext & Context,Type * Ty)194 Attribute Attribute::getWithPreallocatedType(LLVMContext &Context, Type *Ty) {
195 return get(Context, Preallocated, Ty);
196 }
197
getWithInAllocaType(LLVMContext & Context,Type * Ty)198 Attribute Attribute::getWithInAllocaType(LLVMContext &Context, Type *Ty) {
199 return get(Context, InAlloca, Ty);
200 }
201
202 Attribute
getWithAllocSizeArgs(LLVMContext & Context,unsigned ElemSizeArg,const Optional<unsigned> & NumElemsArg)203 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
204 const Optional<unsigned> &NumElemsArg) {
205 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
206 "Invalid allocsize arguments -- given allocsize(0, 0)");
207 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
208 }
209
getWithVScaleRangeArgs(LLVMContext & Context,unsigned MinValue,unsigned MaxValue)210 Attribute Attribute::getWithVScaleRangeArgs(LLVMContext &Context,
211 unsigned MinValue,
212 unsigned MaxValue) {
213 return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
214 }
215
getAttrKindFromName(StringRef AttrName)216 Attribute::AttrKind Attribute::getAttrKindFromName(StringRef AttrName) {
217 return StringSwitch<Attribute::AttrKind>(AttrName)
218 #define GET_ATTR_NAMES
219 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
220 .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
221 #include "llvm/IR/Attributes.inc"
222 .Default(Attribute::None);
223 }
224
getNameFromAttrKind(Attribute::AttrKind AttrKind)225 StringRef Attribute::getNameFromAttrKind(Attribute::AttrKind AttrKind) {
226 switch (AttrKind) {
227 #define GET_ATTR_NAMES
228 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
229 case Attribute::ENUM_NAME: \
230 return #DISPLAY_NAME;
231 #include "llvm/IR/Attributes.inc"
232 case Attribute::None:
233 return "none";
234 default:
235 llvm_unreachable("invalid Kind");
236 }
237 }
238
doesAttrKindHaveArgument(Attribute::AttrKind AttrKind)239 bool Attribute::doesAttrKindHaveArgument(Attribute::AttrKind AttrKind) {
240 return AttrKind == Attribute::Alignment ||
241 AttrKind == Attribute::StackAlignment ||
242 AttrKind == Attribute::Dereferenceable ||
243 AttrKind == Attribute::AllocSize ||
244 AttrKind == Attribute::DereferenceableOrNull ||
245 AttrKind == Attribute::VScaleRange;
246 }
247
isExistingAttribute(StringRef Name)248 bool Attribute::isExistingAttribute(StringRef Name) {
249 return StringSwitch<bool>(Name)
250 #define GET_ATTR_NAMES
251 #define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
252 #include "llvm/IR/Attributes.inc"
253 .Default(false);
254 }
255
256 //===----------------------------------------------------------------------===//
257 // Attribute Accessor Methods
258 //===----------------------------------------------------------------------===//
259
isEnumAttribute() const260 bool Attribute::isEnumAttribute() const {
261 return pImpl && pImpl->isEnumAttribute();
262 }
263
isIntAttribute() const264 bool Attribute::isIntAttribute() const {
265 return pImpl && pImpl->isIntAttribute();
266 }
267
isStringAttribute() const268 bool Attribute::isStringAttribute() const {
269 return pImpl && pImpl->isStringAttribute();
270 }
271
isTypeAttribute() const272 bool Attribute::isTypeAttribute() const {
273 return pImpl && pImpl->isTypeAttribute();
274 }
275
getKindAsEnum() const276 Attribute::AttrKind Attribute::getKindAsEnum() const {
277 if (!pImpl) return None;
278 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
279 "Invalid attribute type to get the kind as an enum!");
280 return pImpl->getKindAsEnum();
281 }
282
getValueAsInt() const283 uint64_t Attribute::getValueAsInt() const {
284 if (!pImpl) return 0;
285 assert(isIntAttribute() &&
286 "Expected the attribute to be an integer attribute!");
287 return pImpl->getValueAsInt();
288 }
289
getValueAsBool() const290 bool Attribute::getValueAsBool() const {
291 if (!pImpl) return false;
292 assert(isStringAttribute() &&
293 "Expected the attribute to be a string attribute!");
294 return pImpl->getValueAsBool();
295 }
296
getKindAsString() const297 StringRef Attribute::getKindAsString() const {
298 if (!pImpl) return {};
299 assert(isStringAttribute() &&
300 "Invalid attribute type to get the kind as a string!");
301 return pImpl->getKindAsString();
302 }
303
getValueAsString() const304 StringRef Attribute::getValueAsString() const {
305 if (!pImpl) return {};
306 assert(isStringAttribute() &&
307 "Invalid attribute type to get the value as a string!");
308 return pImpl->getValueAsString();
309 }
310
getValueAsType() const311 Type *Attribute::getValueAsType() const {
312 if (!pImpl) return {};
313 assert(isTypeAttribute() &&
314 "Invalid attribute type to get the value as a type!");
315 return pImpl->getValueAsType();
316 }
317
318
hasAttribute(AttrKind Kind) const319 bool Attribute::hasAttribute(AttrKind Kind) const {
320 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
321 }
322
hasAttribute(StringRef Kind) const323 bool Attribute::hasAttribute(StringRef Kind) const {
324 if (!isStringAttribute()) return false;
325 return pImpl && pImpl->hasAttribute(Kind);
326 }
327
getAlignment() const328 MaybeAlign Attribute::getAlignment() const {
329 assert(hasAttribute(Attribute::Alignment) &&
330 "Trying to get alignment from non-alignment attribute!");
331 return MaybeAlign(pImpl->getValueAsInt());
332 }
333
getStackAlignment() const334 MaybeAlign Attribute::getStackAlignment() const {
335 assert(hasAttribute(Attribute::StackAlignment) &&
336 "Trying to get alignment from non-alignment attribute!");
337 return MaybeAlign(pImpl->getValueAsInt());
338 }
339
getDereferenceableBytes() const340 uint64_t Attribute::getDereferenceableBytes() const {
341 assert(hasAttribute(Attribute::Dereferenceable) &&
342 "Trying to get dereferenceable bytes from "
343 "non-dereferenceable attribute!");
344 return pImpl->getValueAsInt();
345 }
346
getDereferenceableOrNullBytes() const347 uint64_t Attribute::getDereferenceableOrNullBytes() const {
348 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
349 "Trying to get dereferenceable bytes from "
350 "non-dereferenceable attribute!");
351 return pImpl->getValueAsInt();
352 }
353
getAllocSizeArgs() const354 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
355 assert(hasAttribute(Attribute::AllocSize) &&
356 "Trying to get allocsize args from non-allocsize attribute");
357 return unpackAllocSizeArgs(pImpl->getValueAsInt());
358 }
359
getVScaleRangeArgs() const360 std::pair<unsigned, unsigned> Attribute::getVScaleRangeArgs() const {
361 assert(hasAttribute(Attribute::VScaleRange) &&
362 "Trying to get vscale args from non-vscale attribute");
363 return unpackVScaleRangeArgs(pImpl->getValueAsInt());
364 }
365
getAsString(bool InAttrGrp) const366 std::string Attribute::getAsString(bool InAttrGrp) const {
367 if (!pImpl) return {};
368
369 if (hasAttribute(Attribute::SanitizeAddress))
370 return "sanitize_address";
371 if (hasAttribute(Attribute::SanitizeHWAddress))
372 return "sanitize_hwaddress";
373 if (hasAttribute(Attribute::SanitizeMemTag))
374 return "sanitize_memtag";
375 if (hasAttribute(Attribute::AlwaysInline))
376 return "alwaysinline";
377 if (hasAttribute(Attribute::ArgMemOnly))
378 return "argmemonly";
379 if (hasAttribute(Attribute::Builtin))
380 return "builtin";
381 if (hasAttribute(Attribute::Convergent))
382 return "convergent";
383 if (hasAttribute(Attribute::SwiftError))
384 return "swifterror";
385 if (hasAttribute(Attribute::SwiftSelf))
386 return "swiftself";
387 if (hasAttribute(Attribute::SwiftAsync))
388 return "swiftasync";
389 if (hasAttribute(Attribute::InaccessibleMemOnly))
390 return "inaccessiblememonly";
391 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
392 return "inaccessiblemem_or_argmemonly";
393 if (hasAttribute(Attribute::InlineHint))
394 return "inlinehint";
395 if (hasAttribute(Attribute::InReg))
396 return "inreg";
397 if (hasAttribute(Attribute::JumpTable))
398 return "jumptable";
399 if (hasAttribute(Attribute::MinSize))
400 return "minsize";
401 if (hasAttribute(Attribute::Naked))
402 return "naked";
403 if (hasAttribute(Attribute::Nest))
404 return "nest";
405 if (hasAttribute(Attribute::NoAlias))
406 return "noalias";
407 if (hasAttribute(Attribute::NoBuiltin))
408 return "nobuiltin";
409 if (hasAttribute(Attribute::NoCallback))
410 return "nocallback";
411 if (hasAttribute(Attribute::NoCapture))
412 return "nocapture";
413 if (hasAttribute(Attribute::NoDuplicate))
414 return "noduplicate";
415 if (hasAttribute(Attribute::NoFree))
416 return "nofree";
417 if (hasAttribute(Attribute::NoImplicitFloat))
418 return "noimplicitfloat";
419 if (hasAttribute(Attribute::NoInline))
420 return "noinline";
421 if (hasAttribute(Attribute::NonLazyBind))
422 return "nonlazybind";
423 if (hasAttribute(Attribute::NoMerge))
424 return "nomerge";
425 if (hasAttribute(Attribute::NonNull))
426 return "nonnull";
427 if (hasAttribute(Attribute::NoRedZone))
428 return "noredzone";
429 if (hasAttribute(Attribute::NoReturn))
430 return "noreturn";
431 if (hasAttribute(Attribute::NoSync))
432 return "nosync";
433 if (hasAttribute(Attribute::NullPointerIsValid))
434 return "null_pointer_is_valid";
435 if (hasAttribute(Attribute::WillReturn))
436 return "willreturn";
437 if (hasAttribute(Attribute::NoCfCheck))
438 return "nocf_check";
439 if (hasAttribute(Attribute::NoRecurse))
440 return "norecurse";
441 if (hasAttribute(Attribute::NoProfile))
442 return "noprofile";
443 if (hasAttribute(Attribute::NoUnwind))
444 return "nounwind";
445 if (hasAttribute(Attribute::OptForFuzzing))
446 return "optforfuzzing";
447 if (hasAttribute(Attribute::OptimizeNone))
448 return "optnone";
449 if (hasAttribute(Attribute::OptimizeForSize))
450 return "optsize";
451 if (hasAttribute(Attribute::ReadNone))
452 return "readnone";
453 if (hasAttribute(Attribute::ReadOnly))
454 return "readonly";
455 if (hasAttribute(Attribute::WriteOnly))
456 return "writeonly";
457 if (hasAttribute(Attribute::Returned))
458 return "returned";
459 if (hasAttribute(Attribute::ReturnsTwice))
460 return "returns_twice";
461 if (hasAttribute(Attribute::SExt))
462 return "signext";
463 if (hasAttribute(Attribute::SpeculativeLoadHardening))
464 return "speculative_load_hardening";
465 if (hasAttribute(Attribute::Speculatable))
466 return "speculatable";
467 if (hasAttribute(Attribute::StackProtect))
468 return "ssp";
469 if (hasAttribute(Attribute::StackProtectReq))
470 return "sspreq";
471 if (hasAttribute(Attribute::StackProtectStrong))
472 return "sspstrong";
473 if (hasAttribute(Attribute::SafeStack))
474 return "safestack";
475 if (hasAttribute(Attribute::ShadowCallStack))
476 return "shadowcallstack";
477 if (hasAttribute(Attribute::StrictFP))
478 return "strictfp";
479 if (hasAttribute(Attribute::SanitizeThread))
480 return "sanitize_thread";
481 if (hasAttribute(Attribute::SanitizeMemory))
482 return "sanitize_memory";
483 if (hasAttribute(Attribute::UWTable))
484 return "uwtable";
485 if (hasAttribute(Attribute::ZExt))
486 return "zeroext";
487 if (hasAttribute(Attribute::Cold))
488 return "cold";
489 if (hasAttribute(Attribute::Hot))
490 return "hot";
491 if (hasAttribute(Attribute::ImmArg))
492 return "immarg";
493 if (hasAttribute(Attribute::NoUndef))
494 return "noundef";
495 if (hasAttribute(Attribute::MustProgress))
496 return "mustprogress";
497
498 if (isTypeAttribute()) {
499 std::string Result;
500 raw_string_ostream OS(Result);
501
502 switch (getKindAsEnum()) {
503 case Attribute::ByVal:
504 Result += "byval";
505 break;
506 case Attribute::StructRet:
507 Result += "sret";
508 break;
509 case Attribute::ByRef:
510 Result += "byref";
511 break;
512 case Attribute::Preallocated:
513 Result += "preallocated";
514 break;
515 case Attribute::InAlloca:
516 Result += "inalloca";
517 break;
518 default:
519 llvm_unreachable("unhandled type attribute");
520 }
521
522 Result += '(';
523 getValueAsType()->print(OS, false, true);
524 OS.flush();
525 Result += ')';
526 return Result;
527 }
528
529 // FIXME: These should be output like this:
530 //
531 // align=4
532 // alignstack=8
533 //
534 if (hasAttribute(Attribute::Alignment)) {
535 std::string Result;
536 Result += "align";
537 Result += (InAttrGrp) ? "=" : " ";
538 Result += utostr(getValueAsInt());
539 return Result;
540 }
541
542 auto AttrWithBytesToString = [&](const char *Name) {
543 std::string Result;
544 Result += Name;
545 if (InAttrGrp) {
546 Result += "=";
547 Result += utostr(getValueAsInt());
548 } else {
549 Result += "(";
550 Result += utostr(getValueAsInt());
551 Result += ")";
552 }
553 return Result;
554 };
555
556 if (hasAttribute(Attribute::StackAlignment))
557 return AttrWithBytesToString("alignstack");
558
559 if (hasAttribute(Attribute::Dereferenceable))
560 return AttrWithBytesToString("dereferenceable");
561
562 if (hasAttribute(Attribute::DereferenceableOrNull))
563 return AttrWithBytesToString("dereferenceable_or_null");
564
565 if (hasAttribute(Attribute::AllocSize)) {
566 unsigned ElemSize;
567 Optional<unsigned> NumElems;
568 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
569
570 std::string Result = "allocsize(";
571 Result += utostr(ElemSize);
572 if (NumElems.hasValue()) {
573 Result += ',';
574 Result += utostr(*NumElems);
575 }
576 Result += ')';
577 return Result;
578 }
579
580 if (hasAttribute(Attribute::VScaleRange)) {
581 unsigned MinValue, MaxValue;
582 std::tie(MinValue, MaxValue) = getVScaleRangeArgs();
583
584 std::string Result = "vscale_range(";
585 Result += utostr(MinValue);
586 Result += ',';
587 Result += utostr(MaxValue);
588 Result += ')';
589 return Result;
590 }
591
592 // Convert target-dependent attributes to strings of the form:
593 //
594 // "kind"
595 // "kind" = "value"
596 //
597 if (isStringAttribute()) {
598 std::string Result;
599 {
600 raw_string_ostream OS(Result);
601 OS << '"' << getKindAsString() << '"';
602
603 // Since some attribute strings contain special characters that cannot be
604 // printable, those have to be escaped to make the attribute value
605 // printable as is. e.g. "\01__gnu_mcount_nc"
606 const auto &AttrVal = pImpl->getValueAsString();
607 if (!AttrVal.empty()) {
608 OS << "=\"";
609 printEscapedString(AttrVal, OS);
610 OS << "\"";
611 }
612 }
613 return Result;
614 }
615
616 llvm_unreachable("Unknown attribute");
617 }
618
hasParentContext(LLVMContext & C) const619 bool Attribute::hasParentContext(LLVMContext &C) const {
620 assert(isValid() && "invalid Attribute doesn't refer to any context");
621 FoldingSetNodeID ID;
622 pImpl->Profile(ID);
623 void *Unused;
624 return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
625 }
626
operator <(Attribute A) const627 bool Attribute::operator<(Attribute A) const {
628 if (!pImpl && !A.pImpl) return false;
629 if (!pImpl) return true;
630 if (!A.pImpl) return false;
631 return *pImpl < *A.pImpl;
632 }
633
Profile(FoldingSetNodeID & ID) const634 void Attribute::Profile(FoldingSetNodeID &ID) const {
635 ID.AddPointer(pImpl);
636 }
637
638 //===----------------------------------------------------------------------===//
639 // AttributeImpl Definition
640 //===----------------------------------------------------------------------===//
641
hasAttribute(Attribute::AttrKind A) const642 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
643 if (isStringAttribute()) return false;
644 return getKindAsEnum() == A;
645 }
646
hasAttribute(StringRef Kind) const647 bool AttributeImpl::hasAttribute(StringRef Kind) const {
648 if (!isStringAttribute()) return false;
649 return getKindAsString() == Kind;
650 }
651
getKindAsEnum() const652 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
653 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
654 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
655 }
656
getValueAsInt() const657 uint64_t AttributeImpl::getValueAsInt() const {
658 assert(isIntAttribute());
659 return static_cast<const IntAttributeImpl *>(this)->getValue();
660 }
661
getValueAsBool() const662 bool AttributeImpl::getValueAsBool() const {
663 assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
664 return getValueAsString() == "true";
665 }
666
getKindAsString() const667 StringRef AttributeImpl::getKindAsString() const {
668 assert(isStringAttribute());
669 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
670 }
671
getValueAsString() const672 StringRef AttributeImpl::getValueAsString() const {
673 assert(isStringAttribute());
674 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
675 }
676
getValueAsType() const677 Type *AttributeImpl::getValueAsType() const {
678 assert(isTypeAttribute());
679 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
680 }
681
operator <(const AttributeImpl & AI) const682 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
683 if (this == &AI)
684 return false;
685 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
686 // relative to their enum value) and then strings.
687 if (isEnumAttribute()) {
688 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
689 if (AI.isIntAttribute()) return true;
690 if (AI.isStringAttribute()) return true;
691 if (AI.isTypeAttribute()) return true;
692 }
693
694 if (isTypeAttribute()) {
695 if (AI.isEnumAttribute()) return false;
696 if (AI.isTypeAttribute()) {
697 assert(getKindAsEnum() != AI.getKindAsEnum() &&
698 "Comparison of types would be unstable");
699 return getKindAsEnum() < AI.getKindAsEnum();
700 }
701 if (AI.isIntAttribute()) return true;
702 if (AI.isStringAttribute()) return true;
703 }
704
705 if (isIntAttribute()) {
706 if (AI.isEnumAttribute()) return false;
707 if (AI.isTypeAttribute()) return false;
708 if (AI.isIntAttribute()) {
709 if (getKindAsEnum() == AI.getKindAsEnum())
710 return getValueAsInt() < AI.getValueAsInt();
711 return getKindAsEnum() < AI.getKindAsEnum();
712 }
713 if (AI.isStringAttribute()) return true;
714 }
715
716 assert(isStringAttribute());
717 if (AI.isEnumAttribute()) return false;
718 if (AI.isTypeAttribute()) return false;
719 if (AI.isIntAttribute()) return false;
720 if (getKindAsString() == AI.getKindAsString())
721 return getValueAsString() < AI.getValueAsString();
722 return getKindAsString() < AI.getKindAsString();
723 }
724
725 //===----------------------------------------------------------------------===//
726 // AttributeSet Definition
727 //===----------------------------------------------------------------------===//
728
get(LLVMContext & C,const AttrBuilder & B)729 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
730 return AttributeSet(AttributeSetNode::get(C, B));
731 }
732
get(LLVMContext & C,ArrayRef<Attribute> Attrs)733 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
734 return AttributeSet(AttributeSetNode::get(C, Attrs));
735 }
736
addAttribute(LLVMContext & C,Attribute::AttrKind Kind) const737 AttributeSet AttributeSet::addAttribute(LLVMContext &C,
738 Attribute::AttrKind Kind) const {
739 if (hasAttribute(Kind)) return *this;
740 AttrBuilder B;
741 B.addAttribute(Kind);
742 return addAttributes(C, AttributeSet::get(C, B));
743 }
744
addAttribute(LLVMContext & C,StringRef Kind,StringRef Value) const745 AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
746 StringRef Value) const {
747 AttrBuilder B;
748 B.addAttribute(Kind, Value);
749 return addAttributes(C, AttributeSet::get(C, B));
750 }
751
addAttributes(LLVMContext & C,const AttributeSet AS) const752 AttributeSet AttributeSet::addAttributes(LLVMContext &C,
753 const AttributeSet AS) const {
754 if (!hasAttributes())
755 return AS;
756
757 if (!AS.hasAttributes())
758 return *this;
759
760 AttrBuilder B(AS);
761 for (const auto &I : *this)
762 B.addAttribute(I);
763
764 return get(C, B);
765 }
766
removeAttribute(LLVMContext & C,Attribute::AttrKind Kind) const767 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
768 Attribute::AttrKind Kind) const {
769 if (!hasAttribute(Kind)) return *this;
770 AttrBuilder B(*this);
771 B.removeAttribute(Kind);
772 return get(C, B);
773 }
774
removeAttribute(LLVMContext & C,StringRef Kind) const775 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
776 StringRef Kind) const {
777 if (!hasAttribute(Kind)) return *this;
778 AttrBuilder B(*this);
779 B.removeAttribute(Kind);
780 return get(C, B);
781 }
782
removeAttributes(LLVMContext & C,const AttrBuilder & Attrs) const783 AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
784 const AttrBuilder &Attrs) const {
785 AttrBuilder B(*this);
786 // If there is nothing to remove, directly return the original set.
787 if (!B.overlaps(Attrs))
788 return *this;
789
790 B.remove(Attrs);
791 return get(C, B);
792 }
793
getNumAttributes() const794 unsigned AttributeSet::getNumAttributes() const {
795 return SetNode ? SetNode->getNumAttributes() : 0;
796 }
797
hasAttribute(Attribute::AttrKind Kind) const798 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
799 return SetNode ? SetNode->hasAttribute(Kind) : false;
800 }
801
hasAttribute(StringRef Kind) const802 bool AttributeSet::hasAttribute(StringRef Kind) const {
803 return SetNode ? SetNode->hasAttribute(Kind) : false;
804 }
805
getAttribute(Attribute::AttrKind Kind) const806 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
807 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
808 }
809
getAttribute(StringRef Kind) const810 Attribute AttributeSet::getAttribute(StringRef Kind) const {
811 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
812 }
813
getAlignment() const814 MaybeAlign AttributeSet::getAlignment() const {
815 return SetNode ? SetNode->getAlignment() : None;
816 }
817
getStackAlignment() const818 MaybeAlign AttributeSet::getStackAlignment() const {
819 return SetNode ? SetNode->getStackAlignment() : None;
820 }
821
getDereferenceableBytes() const822 uint64_t AttributeSet::getDereferenceableBytes() const {
823 return SetNode ? SetNode->getDereferenceableBytes() : 0;
824 }
825
getDereferenceableOrNullBytes() const826 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
827 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
828 }
829
getByRefType() const830 Type *AttributeSet::getByRefType() const {
831 return SetNode ? SetNode->getByRefType() : nullptr;
832 }
833
getByValType() const834 Type *AttributeSet::getByValType() const {
835 return SetNode ? SetNode->getByValType() : nullptr;
836 }
837
getStructRetType() const838 Type *AttributeSet::getStructRetType() const {
839 return SetNode ? SetNode->getStructRetType() : nullptr;
840 }
841
getPreallocatedType() const842 Type *AttributeSet::getPreallocatedType() const {
843 return SetNode ? SetNode->getPreallocatedType() : nullptr;
844 }
845
getInAllocaType() const846 Type *AttributeSet::getInAllocaType() const {
847 return SetNode ? SetNode->getInAllocaType() : nullptr;
848 }
849
getAllocSizeArgs() const850 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
851 return SetNode ? SetNode->getAllocSizeArgs()
852 : std::pair<unsigned, Optional<unsigned>>(0, 0);
853 }
854
getVScaleRangeArgs() const855 std::pair<unsigned, unsigned> AttributeSet::getVScaleRangeArgs() const {
856 return SetNode ? SetNode->getVScaleRangeArgs()
857 : std::pair<unsigned, unsigned>(0, 0);
858 }
859
getAsString(bool InAttrGrp) const860 std::string AttributeSet::getAsString(bool InAttrGrp) const {
861 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
862 }
863
hasParentContext(LLVMContext & C) const864 bool AttributeSet::hasParentContext(LLVMContext &C) const {
865 assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
866 FoldingSetNodeID ID;
867 SetNode->Profile(ID);
868 void *Unused;
869 return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
870 }
871
begin() const872 AttributeSet::iterator AttributeSet::begin() const {
873 return SetNode ? SetNode->begin() : nullptr;
874 }
875
end() const876 AttributeSet::iterator AttributeSet::end() const {
877 return SetNode ? SetNode->end() : nullptr;
878 }
879
880 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const881 LLVM_DUMP_METHOD void AttributeSet::dump() const {
882 dbgs() << "AS =\n";
883 dbgs() << " { ";
884 dbgs() << getAsString(true) << " }\n";
885 }
886 #endif
887
888 //===----------------------------------------------------------------------===//
889 // AttributeSetNode Definition
890 //===----------------------------------------------------------------------===//
891
AttributeSetNode(ArrayRef<Attribute> Attrs)892 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
893 : NumAttrs(Attrs.size()) {
894 // There's memory after the node where we can store the entries in.
895 llvm::copy(Attrs, getTrailingObjects<Attribute>());
896
897 for (const auto &I : *this) {
898 if (I.isStringAttribute())
899 StringAttrs.insert({ I.getKindAsString(), I });
900 else
901 AvailableAttrs.addAttribute(I.getKindAsEnum());
902 }
903 }
904
get(LLVMContext & C,ArrayRef<Attribute> Attrs)905 AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
906 ArrayRef<Attribute> Attrs) {
907 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
908 llvm::sort(SortedAttrs);
909 return getSorted(C, SortedAttrs);
910 }
911
getSorted(LLVMContext & C,ArrayRef<Attribute> SortedAttrs)912 AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
913 ArrayRef<Attribute> SortedAttrs) {
914 if (SortedAttrs.empty())
915 return nullptr;
916
917 // Build a key to look up the existing attributes.
918 LLVMContextImpl *pImpl = C.pImpl;
919 FoldingSetNodeID ID;
920
921 assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
922 for (const auto &Attr : SortedAttrs)
923 Attr.Profile(ID);
924
925 void *InsertPoint;
926 AttributeSetNode *PA =
927 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
928
929 // If we didn't find any existing attributes of the same shape then create a
930 // new one and insert it.
931 if (!PA) {
932 // Coallocate entries after the AttributeSetNode itself.
933 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
934 PA = new (Mem) AttributeSetNode(SortedAttrs);
935 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
936 }
937
938 // Return the AttributeSetNode that we found or created.
939 return PA;
940 }
941
get(LLVMContext & C,const AttrBuilder & B)942 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
943 // Add target-independent attributes.
944 SmallVector<Attribute, 8> Attrs;
945 for (Attribute::AttrKind Kind = Attribute::None;
946 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
947 if (!B.contains(Kind))
948 continue;
949
950 Attribute Attr;
951 switch (Kind) {
952 case Attribute::ByVal:
953 Attr = Attribute::getWithByValType(C, B.getByValType());
954 break;
955 case Attribute::StructRet:
956 Attr = Attribute::getWithStructRetType(C, B.getStructRetType());
957 break;
958 case Attribute::ByRef:
959 Attr = Attribute::getWithByRefType(C, B.getByRefType());
960 break;
961 case Attribute::Preallocated:
962 Attr = Attribute::getWithPreallocatedType(C, B.getPreallocatedType());
963 break;
964 case Attribute::InAlloca:
965 Attr = Attribute::getWithInAllocaType(C, B.getInAllocaType());
966 break;
967 case Attribute::Alignment:
968 assert(B.getAlignment() && "Alignment must be set");
969 Attr = Attribute::getWithAlignment(C, *B.getAlignment());
970 break;
971 case Attribute::StackAlignment:
972 assert(B.getStackAlignment() && "StackAlignment must be set");
973 Attr = Attribute::getWithStackAlignment(C, *B.getStackAlignment());
974 break;
975 case Attribute::Dereferenceable:
976 Attr = Attribute::getWithDereferenceableBytes(
977 C, B.getDereferenceableBytes());
978 break;
979 case Attribute::DereferenceableOrNull:
980 Attr = Attribute::getWithDereferenceableOrNullBytes(
981 C, B.getDereferenceableOrNullBytes());
982 break;
983 case Attribute::AllocSize: {
984 auto A = B.getAllocSizeArgs();
985 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
986 break;
987 }
988 case Attribute::VScaleRange: {
989 auto A = B.getVScaleRangeArgs();
990 Attr = Attribute::getWithVScaleRangeArgs(C, A.first, A.second);
991 break;
992 }
993 default:
994 Attr = Attribute::get(C, Kind);
995 }
996 Attrs.push_back(Attr);
997 }
998
999 // Add target-dependent (string) attributes.
1000 for (const auto &TDA : B.td_attrs())
1001 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
1002
1003 return getSorted(C, Attrs);
1004 }
1005
hasAttribute(StringRef Kind) const1006 bool AttributeSetNode::hasAttribute(StringRef Kind) const {
1007 return StringAttrs.count(Kind);
1008 }
1009
1010 Optional<Attribute>
findEnumAttribute(Attribute::AttrKind Kind) const1011 AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
1012 // Do a quick presence check.
1013 if (!hasAttribute(Kind))
1014 return None;
1015
1016 // Attributes in a set are sorted by enum value, followed by string
1017 // attributes. Binary search the one we want.
1018 const Attribute *I =
1019 std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
1020 [](Attribute A, Attribute::AttrKind Kind) {
1021 return A.getKindAsEnum() < Kind;
1022 });
1023 assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
1024 return *I;
1025 }
1026
getAttribute(Attribute::AttrKind Kind) const1027 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
1028 if (auto A = findEnumAttribute(Kind))
1029 return *A;
1030 return {};
1031 }
1032
getAttribute(StringRef Kind) const1033 Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
1034 return StringAttrs.lookup(Kind);
1035 }
1036
getAlignment() const1037 MaybeAlign AttributeSetNode::getAlignment() const {
1038 if (auto A = findEnumAttribute(Attribute::Alignment))
1039 return A->getAlignment();
1040 return None;
1041 }
1042
getStackAlignment() const1043 MaybeAlign AttributeSetNode::getStackAlignment() const {
1044 if (auto A = findEnumAttribute(Attribute::StackAlignment))
1045 return A->getStackAlignment();
1046 return None;
1047 }
1048
getByValType() const1049 Type *AttributeSetNode::getByValType() const {
1050 if (auto A = findEnumAttribute(Attribute::ByVal))
1051 return A->getValueAsType();
1052 return nullptr;
1053 }
1054
getStructRetType() const1055 Type *AttributeSetNode::getStructRetType() const {
1056 if (auto A = findEnumAttribute(Attribute::StructRet))
1057 return A->getValueAsType();
1058 return nullptr;
1059 }
1060
getByRefType() const1061 Type *AttributeSetNode::getByRefType() const {
1062 if (auto A = findEnumAttribute(Attribute::ByRef))
1063 return A->getValueAsType();
1064 return nullptr;
1065 }
1066
getPreallocatedType() const1067 Type *AttributeSetNode::getPreallocatedType() const {
1068 if (auto A = findEnumAttribute(Attribute::Preallocated))
1069 return A->getValueAsType();
1070 return nullptr;
1071 }
1072
getInAllocaType() const1073 Type *AttributeSetNode::getInAllocaType() const {
1074 if (auto A = findEnumAttribute(Attribute::InAlloca))
1075 return A->getValueAsType();
1076 return nullptr;
1077 }
1078
getDereferenceableBytes() const1079 uint64_t AttributeSetNode::getDereferenceableBytes() const {
1080 if (auto A = findEnumAttribute(Attribute::Dereferenceable))
1081 return A->getDereferenceableBytes();
1082 return 0;
1083 }
1084
getDereferenceableOrNullBytes() const1085 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
1086 if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1087 return A->getDereferenceableOrNullBytes();
1088 return 0;
1089 }
1090
1091 std::pair<unsigned, Optional<unsigned>>
getAllocSizeArgs() const1092 AttributeSetNode::getAllocSizeArgs() const {
1093 if (auto A = findEnumAttribute(Attribute::AllocSize))
1094 return A->getAllocSizeArgs();
1095 return std::make_pair(0, 0);
1096 }
1097
getVScaleRangeArgs() const1098 std::pair<unsigned, unsigned> AttributeSetNode::getVScaleRangeArgs() const {
1099 if (auto A = findEnumAttribute(Attribute::VScaleRange))
1100 return A->getVScaleRangeArgs();
1101 return std::make_pair(0, 0);
1102 }
1103
getAsString(bool InAttrGrp) const1104 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
1105 std::string Str;
1106 for (iterator I = begin(), E = end(); I != E; ++I) {
1107 if (I != begin())
1108 Str += ' ';
1109 Str += I->getAsString(InAttrGrp);
1110 }
1111 return Str;
1112 }
1113
1114 //===----------------------------------------------------------------------===//
1115 // AttributeListImpl Definition
1116 //===----------------------------------------------------------------------===//
1117
1118 /// Map from AttributeList index to the internal array index. Adding one happens
1119 /// to work, because -1 wraps around to 0.
attrIdxToArrayIdx(unsigned Index)1120 static unsigned attrIdxToArrayIdx(unsigned Index) {
1121 return Index + 1;
1122 }
1123
AttributeListImpl(ArrayRef<AttributeSet> Sets)1124 AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
1125 : NumAttrSets(Sets.size()) {
1126 assert(!Sets.empty() && "pointless AttributeListImpl");
1127
1128 // There's memory after the node where we can store the entries in.
1129 llvm::copy(Sets, getTrailingObjects<AttributeSet>());
1130
1131 // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
1132 // summary bitsets.
1133 for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
1134 if (!I.isStringAttribute())
1135 AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
1136
1137 for (const auto &Set : Sets)
1138 for (const auto &I : Set)
1139 if (!I.isStringAttribute())
1140 AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
1141 }
1142
Profile(FoldingSetNodeID & ID) const1143 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
1144 Profile(ID, makeArrayRef(begin(), end()));
1145 }
1146
Profile(FoldingSetNodeID & ID,ArrayRef<AttributeSet> Sets)1147 void AttributeListImpl::Profile(FoldingSetNodeID &ID,
1148 ArrayRef<AttributeSet> Sets) {
1149 for (const auto &Set : Sets)
1150 ID.AddPointer(Set.SetNode);
1151 }
1152
hasAttrSomewhere(Attribute::AttrKind Kind,unsigned * Index) const1153 bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind,
1154 unsigned *Index) const {
1155 if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1156 return false;
1157
1158 if (Index) {
1159 for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1160 if (begin()[I].hasAttribute(Kind)) {
1161 *Index = I - 1;
1162 break;
1163 }
1164 }
1165 }
1166
1167 return true;
1168 }
1169
1170
1171 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1172 LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
1173 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
1174 }
1175 #endif
1176
1177 //===----------------------------------------------------------------------===//
1178 // AttributeList Construction and Mutation Methods
1179 //===----------------------------------------------------------------------===//
1180
getImpl(LLVMContext & C,ArrayRef<AttributeSet> AttrSets)1181 AttributeList AttributeList::getImpl(LLVMContext &C,
1182 ArrayRef<AttributeSet> AttrSets) {
1183 assert(!AttrSets.empty() && "pointless AttributeListImpl");
1184
1185 LLVMContextImpl *pImpl = C.pImpl;
1186 FoldingSetNodeID ID;
1187 AttributeListImpl::Profile(ID, AttrSets);
1188
1189 void *InsertPoint;
1190 AttributeListImpl *PA =
1191 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
1192
1193 // If we didn't find any existing attributes of the same shape then
1194 // create a new one and insert it.
1195 if (!PA) {
1196 // Coallocate entries after the AttributeListImpl itself.
1197 void *Mem = pImpl->Alloc.Allocate(
1198 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1199 alignof(AttributeListImpl));
1200 PA = new (Mem) AttributeListImpl(AttrSets);
1201 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1202 }
1203
1204 // Return the AttributesList that we found or created.
1205 return AttributeList(PA);
1206 }
1207
1208 AttributeList
get(LLVMContext & C,ArrayRef<std::pair<unsigned,Attribute>> Attrs)1209 AttributeList::get(LLVMContext &C,
1210 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1211 // If there are no attributes then return a null AttributesList pointer.
1212 if (Attrs.empty())
1213 return {};
1214
1215 assert(llvm::is_sorted(Attrs,
1216 [](const std::pair<unsigned, Attribute> &LHS,
1217 const std::pair<unsigned, Attribute> &RHS) {
1218 return LHS.first < RHS.first;
1219 }) &&
1220 "Misordered Attributes list!");
1221 assert(llvm::all_of(Attrs,
1222 [](const std::pair<unsigned, Attribute> &Pair) {
1223 return Pair.second.isValid();
1224 }) &&
1225 "Pointless attribute!");
1226
1227 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1228 // list.
1229 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
1230 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1231 E = Attrs.end(); I != E; ) {
1232 unsigned Index = I->first;
1233 SmallVector<Attribute, 4> AttrVec;
1234 while (I != E && I->first == Index) {
1235 AttrVec.push_back(I->second);
1236 ++I;
1237 }
1238
1239 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1240 }
1241
1242 return get(C, AttrPairVec);
1243 }
1244
1245 AttributeList
get(LLVMContext & C,ArrayRef<std::pair<unsigned,AttributeSet>> Attrs)1246 AttributeList::get(LLVMContext &C,
1247 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1248 // If there are no attributes then return a null AttributesList pointer.
1249 if (Attrs.empty())
1250 return {};
1251
1252 assert(llvm::is_sorted(Attrs,
1253 [](const std::pair<unsigned, AttributeSet> &LHS,
1254 const std::pair<unsigned, AttributeSet> &RHS) {
1255 return LHS.first < RHS.first;
1256 }) &&
1257 "Misordered Attributes list!");
1258 assert(llvm::none_of(Attrs,
1259 [](const std::pair<unsigned, AttributeSet> &Pair) {
1260 return !Pair.second.hasAttributes();
1261 }) &&
1262 "Pointless attribute!");
1263
1264 unsigned MaxIndex = Attrs.back().first;
1265 // If the MaxIndex is FunctionIndex and there are other indices in front
1266 // of it, we need to use the largest of those to get the right size.
1267 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1268 MaxIndex = Attrs[Attrs.size() - 2].first;
1269
1270 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1271 for (const auto &Pair : Attrs)
1272 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1273
1274 return getImpl(C, AttrVec);
1275 }
1276
get(LLVMContext & C,AttributeSet FnAttrs,AttributeSet RetAttrs,ArrayRef<AttributeSet> ArgAttrs)1277 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
1278 AttributeSet RetAttrs,
1279 ArrayRef<AttributeSet> ArgAttrs) {
1280 // Scan from the end to find the last argument with attributes. Most
1281 // arguments don't have attributes, so it's nice if we can have fewer unique
1282 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1283 unsigned NumSets = 0;
1284 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1285 if (ArgAttrs[I - 1].hasAttributes()) {
1286 NumSets = I + 2;
1287 break;
1288 }
1289 }
1290 if (NumSets == 0) {
1291 // Check function and return attributes if we didn't have argument
1292 // attributes.
1293 if (RetAttrs.hasAttributes())
1294 NumSets = 2;
1295 else if (FnAttrs.hasAttributes())
1296 NumSets = 1;
1297 }
1298
1299 // If all attribute sets were empty, we can use the empty attribute list.
1300 if (NumSets == 0)
1301 return {};
1302
1303 SmallVector<AttributeSet, 8> AttrSets;
1304 AttrSets.reserve(NumSets);
1305 // If we have any attributes, we always have function attributes.
1306 AttrSets.push_back(FnAttrs);
1307 if (NumSets > 1)
1308 AttrSets.push_back(RetAttrs);
1309 if (NumSets > 2) {
1310 // Drop the empty argument attribute sets at the end.
1311 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1312 llvm::append_range(AttrSets, ArgAttrs);
1313 }
1314
1315 return getImpl(C, AttrSets);
1316 }
1317
get(LLVMContext & C,unsigned Index,const AttrBuilder & B)1318 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1319 const AttrBuilder &B) {
1320 if (!B.hasAttributes())
1321 return {};
1322 Index = attrIdxToArrayIdx(Index);
1323 SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1324 AttrSets[Index] = AttributeSet::get(C, B);
1325 return getImpl(C, AttrSets);
1326 }
1327
get(LLVMContext & C,unsigned Index,ArrayRef<Attribute::AttrKind> Kinds)1328 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1329 ArrayRef<Attribute::AttrKind> Kinds) {
1330 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1331 for (const auto K : Kinds)
1332 Attrs.emplace_back(Index, Attribute::get(C, K));
1333 return get(C, Attrs);
1334 }
1335
get(LLVMContext & C,unsigned Index,ArrayRef<Attribute::AttrKind> Kinds,ArrayRef<uint64_t> Values)1336 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1337 ArrayRef<Attribute::AttrKind> Kinds,
1338 ArrayRef<uint64_t> Values) {
1339 assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1340 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1341 auto VI = Values.begin();
1342 for (const auto K : Kinds)
1343 Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
1344 return get(C, Attrs);
1345 }
1346
get(LLVMContext & C,unsigned Index,ArrayRef<StringRef> Kinds)1347 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1348 ArrayRef<StringRef> Kinds) {
1349 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1350 for (const auto &K : Kinds)
1351 Attrs.emplace_back(Index, Attribute::get(C, K));
1352 return get(C, Attrs);
1353 }
1354
get(LLVMContext & C,ArrayRef<AttributeList> Attrs)1355 AttributeList AttributeList::get(LLVMContext &C,
1356 ArrayRef<AttributeList> Attrs) {
1357 if (Attrs.empty())
1358 return {};
1359 if (Attrs.size() == 1)
1360 return Attrs[0];
1361
1362 unsigned MaxSize = 0;
1363 for (const auto &List : Attrs)
1364 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1365
1366 // If every list was empty, there is no point in merging the lists.
1367 if (MaxSize == 0)
1368 return {};
1369
1370 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1371 for (unsigned I = 0; I < MaxSize; ++I) {
1372 AttrBuilder CurBuilder;
1373 for (const auto &List : Attrs)
1374 CurBuilder.merge(List.getAttributes(I - 1));
1375 NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1376 }
1377
1378 return getImpl(C, NewAttrSets);
1379 }
1380
addAttribute(LLVMContext & C,unsigned Index,Attribute::AttrKind Kind) const1381 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1382 Attribute::AttrKind Kind) const {
1383 if (hasAttribute(Index, Kind)) return *this;
1384 AttributeSet Attrs = getAttributes(Index);
1385 // TODO: Insert at correct position and avoid sort.
1386 SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
1387 NewAttrs.push_back(Attribute::get(C, Kind));
1388 return setAttributes(C, Index, AttributeSet::get(C, NewAttrs));
1389 }
1390
addAttribute(LLVMContext & C,unsigned Index,StringRef Kind,StringRef Value) const1391 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1392 StringRef Kind,
1393 StringRef Value) const {
1394 AttrBuilder B;
1395 B.addAttribute(Kind, Value);
1396 return addAttributes(C, Index, B);
1397 }
1398
addAttribute(LLVMContext & C,unsigned Index,Attribute A) const1399 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1400 Attribute A) const {
1401 AttrBuilder B;
1402 B.addAttribute(A);
1403 return addAttributes(C, Index, B);
1404 }
1405
setAttributes(LLVMContext & C,unsigned Index,AttributeSet Attrs) const1406 AttributeList AttributeList::setAttributes(LLVMContext &C, unsigned Index,
1407 AttributeSet Attrs) const {
1408 Index = attrIdxToArrayIdx(Index);
1409 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1410 if (Index >= AttrSets.size())
1411 AttrSets.resize(Index + 1);
1412 AttrSets[Index] = Attrs;
1413 return AttributeList::getImpl(C, AttrSets);
1414 }
1415
addAttributes(LLVMContext & C,unsigned Index,const AttrBuilder & B) const1416 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
1417 const AttrBuilder &B) const {
1418 if (!B.hasAttributes())
1419 return *this;
1420
1421 if (!pImpl)
1422 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1423
1424 #ifndef NDEBUG
1425 // FIXME it is not obvious how this should work for alignment. For now, say
1426 // we can't change a known alignment.
1427 const MaybeAlign OldAlign = getAttributes(Index).getAlignment();
1428 const MaybeAlign NewAlign = B.getAlignment();
1429 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1430 "Attempt to change alignment!");
1431 #endif
1432
1433 AttrBuilder Merged(getAttributes(Index));
1434 Merged.merge(B);
1435 return setAttributes(C, Index, AttributeSet::get(C, Merged));
1436 }
1437
addParamAttribute(LLVMContext & C,ArrayRef<unsigned> ArgNos,Attribute A) const1438 AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1439 ArrayRef<unsigned> ArgNos,
1440 Attribute A) const {
1441 assert(llvm::is_sorted(ArgNos));
1442
1443 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1444 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1445 if (MaxIndex >= AttrSets.size())
1446 AttrSets.resize(MaxIndex + 1);
1447
1448 for (unsigned ArgNo : ArgNos) {
1449 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1450 AttrBuilder B(AttrSets[Index]);
1451 B.addAttribute(A);
1452 AttrSets[Index] = AttributeSet::get(C, B);
1453 }
1454
1455 return getImpl(C, AttrSets);
1456 }
1457
removeAttribute(LLVMContext & C,unsigned Index,Attribute::AttrKind Kind) const1458 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1459 Attribute::AttrKind Kind) const {
1460 if (!hasAttribute(Index, Kind)) return *this;
1461
1462 Index = attrIdxToArrayIdx(Index);
1463 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1464 assert(Index < AttrSets.size());
1465
1466 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1467
1468 return getImpl(C, AttrSets);
1469 }
1470
removeAttribute(LLVMContext & C,unsigned Index,StringRef Kind) const1471 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1472 StringRef Kind) const {
1473 if (!hasAttribute(Index, Kind)) return *this;
1474
1475 Index = attrIdxToArrayIdx(Index);
1476 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1477 assert(Index < AttrSets.size());
1478
1479 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1480
1481 return getImpl(C, AttrSets);
1482 }
1483
1484 AttributeList
removeAttributes(LLVMContext & C,unsigned Index,const AttrBuilder & AttrsToRemove) const1485 AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
1486 const AttrBuilder &AttrsToRemove) const {
1487 AttributeSet Attrs = getAttributes(Index);
1488 AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
1489 // If nothing was removed, return the original list.
1490 if (Attrs == NewAttrs)
1491 return *this;
1492 return setAttributes(C, Index, NewAttrs);
1493 }
1494
removeAttributes(LLVMContext & C,unsigned WithoutIndex) const1495 AttributeList AttributeList::removeAttributes(LLVMContext &C,
1496 unsigned WithoutIndex) const {
1497 if (!pImpl)
1498 return {};
1499 WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1500 if (WithoutIndex >= getNumAttrSets())
1501 return *this;
1502 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1503 AttrSets[WithoutIndex] = AttributeSet();
1504 return getImpl(C, AttrSets);
1505 }
1506
1507 AttributeList
removeParamUndefImplyingAttributes(LLVMContext & C,unsigned ArgNo) const1508 AttributeList::removeParamUndefImplyingAttributes(LLVMContext &C,
1509 unsigned ArgNo) const {
1510 AttrBuilder B;
1511 B.addAttribute(Attribute::NoUndef);
1512 B.addAttribute(Attribute::NonNull);
1513 B.addDereferenceableAttr(1);
1514 B.addDereferenceableOrNullAttr(1);
1515 return removeParamAttributes(C, ArgNo, B);
1516 }
1517
addDereferenceableAttr(LLVMContext & C,unsigned Index,uint64_t Bytes) const1518 AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
1519 unsigned Index,
1520 uint64_t Bytes) const {
1521 AttrBuilder B;
1522 B.addDereferenceableAttr(Bytes);
1523 return addAttributes(C, Index, B);
1524 }
1525
1526 AttributeList
addDereferenceableOrNullAttr(LLVMContext & C,unsigned Index,uint64_t Bytes) const1527 AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
1528 uint64_t Bytes) const {
1529 AttrBuilder B;
1530 B.addDereferenceableOrNullAttr(Bytes);
1531 return addAttributes(C, Index, B);
1532 }
1533
1534 AttributeList
addAllocSizeAttr(LLVMContext & C,unsigned Index,unsigned ElemSizeArg,const Optional<unsigned> & NumElemsArg)1535 AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
1536 unsigned ElemSizeArg,
1537 const Optional<unsigned> &NumElemsArg) {
1538 AttrBuilder B;
1539 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1540 return addAttributes(C, Index, B);
1541 }
1542
addVScaleRangeAttr(LLVMContext & C,unsigned Index,unsigned MinValue,unsigned MaxValue)1543 AttributeList AttributeList::addVScaleRangeAttr(LLVMContext &C, unsigned Index,
1544 unsigned MinValue,
1545 unsigned MaxValue) {
1546 AttrBuilder B;
1547 B.addVScaleRangeAttr(MinValue, MaxValue);
1548 return addAttributes(C, Index, B);
1549 }
1550
1551 //===----------------------------------------------------------------------===//
1552 // AttributeList Accessor Methods
1553 //===----------------------------------------------------------------------===//
1554
getParamAttributes(unsigned ArgNo) const1555 AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
1556 return getAttributes(ArgNo + FirstArgIndex);
1557 }
1558
getRetAttributes() const1559 AttributeSet AttributeList::getRetAttributes() const {
1560 return getAttributes(ReturnIndex);
1561 }
1562
getFnAttributes() const1563 AttributeSet AttributeList::getFnAttributes() const {
1564 return getAttributes(FunctionIndex);
1565 }
1566
hasAttribute(unsigned Index,Attribute::AttrKind Kind) const1567 bool AttributeList::hasAttribute(unsigned Index,
1568 Attribute::AttrKind Kind) const {
1569 return getAttributes(Index).hasAttribute(Kind);
1570 }
1571
hasAttribute(unsigned Index,StringRef Kind) const1572 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
1573 return getAttributes(Index).hasAttribute(Kind);
1574 }
1575
hasAttributes(unsigned Index) const1576 bool AttributeList::hasAttributes(unsigned Index) const {
1577 return getAttributes(Index).hasAttributes();
1578 }
1579
hasFnAttribute(Attribute::AttrKind Kind) const1580 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
1581 return pImpl && pImpl->hasFnAttribute(Kind);
1582 }
1583
hasFnAttribute(StringRef Kind) const1584 bool AttributeList::hasFnAttribute(StringRef Kind) const {
1585 return hasAttribute(AttributeList::FunctionIndex, Kind);
1586 }
1587
hasParamAttribute(unsigned ArgNo,Attribute::AttrKind Kind) const1588 bool AttributeList::hasParamAttribute(unsigned ArgNo,
1589 Attribute::AttrKind Kind) const {
1590 return hasAttribute(ArgNo + FirstArgIndex, Kind);
1591 }
1592
hasAttrSomewhere(Attribute::AttrKind Attr,unsigned * Index) const1593 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1594 unsigned *Index) const {
1595 return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1596 }
1597
getAttribute(unsigned Index,Attribute::AttrKind Kind) const1598 Attribute AttributeList::getAttribute(unsigned Index,
1599 Attribute::AttrKind Kind) const {
1600 return getAttributes(Index).getAttribute(Kind);
1601 }
1602
getAttribute(unsigned Index,StringRef Kind) const1603 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
1604 return getAttributes(Index).getAttribute(Kind);
1605 }
1606
getRetAlignment() const1607 MaybeAlign AttributeList::getRetAlignment() const {
1608 return getAttributes(ReturnIndex).getAlignment();
1609 }
1610
getParamAlignment(unsigned ArgNo) const1611 MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
1612 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1613 }
1614
getParamStackAlignment(unsigned ArgNo) const1615 MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const {
1616 return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1617 }
1618
getParamByValType(unsigned Index) const1619 Type *AttributeList::getParamByValType(unsigned Index) const {
1620 return getAttributes(Index+FirstArgIndex).getByValType();
1621 }
1622
getParamStructRetType(unsigned Index) const1623 Type *AttributeList::getParamStructRetType(unsigned Index) const {
1624 return getAttributes(Index + FirstArgIndex).getStructRetType();
1625 }
1626
getParamByRefType(unsigned Index) const1627 Type *AttributeList::getParamByRefType(unsigned Index) const {
1628 return getAttributes(Index + FirstArgIndex).getByRefType();
1629 }
1630
getParamPreallocatedType(unsigned Index) const1631 Type *AttributeList::getParamPreallocatedType(unsigned Index) const {
1632 return getAttributes(Index + FirstArgIndex).getPreallocatedType();
1633 }
1634
getParamInAllocaType(unsigned Index) const1635 Type *AttributeList::getParamInAllocaType(unsigned Index) const {
1636 return getAttributes(Index + FirstArgIndex).getInAllocaType();
1637 }
1638
getStackAlignment(unsigned Index) const1639 MaybeAlign AttributeList::getStackAlignment(unsigned Index) const {
1640 return getAttributes(Index).getStackAlignment();
1641 }
1642
getDereferenceableBytes(unsigned Index) const1643 uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
1644 return getAttributes(Index).getDereferenceableBytes();
1645 }
1646
getDereferenceableOrNullBytes(unsigned Index) const1647 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
1648 return getAttributes(Index).getDereferenceableOrNullBytes();
1649 }
1650
1651 std::pair<unsigned, Optional<unsigned>>
getAllocSizeArgs(unsigned Index) const1652 AttributeList::getAllocSizeArgs(unsigned Index) const {
1653 return getAttributes(Index).getAllocSizeArgs();
1654 }
1655
1656 std::pair<unsigned, unsigned>
getVScaleRangeArgs(unsigned Index) const1657 AttributeList::getVScaleRangeArgs(unsigned Index) const {
1658 return getAttributes(Index).getVScaleRangeArgs();
1659 }
1660
getAsString(unsigned Index,bool InAttrGrp) const1661 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1662 return getAttributes(Index).getAsString(InAttrGrp);
1663 }
1664
getAttributes(unsigned Index) const1665 AttributeSet AttributeList::getAttributes(unsigned Index) const {
1666 Index = attrIdxToArrayIdx(Index);
1667 if (!pImpl || Index >= getNumAttrSets())
1668 return {};
1669 return pImpl->begin()[Index];
1670 }
1671
hasParentContext(LLVMContext & C) const1672 bool AttributeList::hasParentContext(LLVMContext &C) const {
1673 assert(!isEmpty() && "an empty attribute list has no parent context");
1674 FoldingSetNodeID ID;
1675 pImpl->Profile(ID);
1676 void *Unused;
1677 return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
1678 }
1679
begin() const1680 AttributeList::iterator AttributeList::begin() const {
1681 return pImpl ? pImpl->begin() : nullptr;
1682 }
1683
end() const1684 AttributeList::iterator AttributeList::end() const {
1685 return pImpl ? pImpl->end() : nullptr;
1686 }
1687
1688 //===----------------------------------------------------------------------===//
1689 // AttributeList Introspection Methods
1690 //===----------------------------------------------------------------------===//
1691
getNumAttrSets() const1692 unsigned AttributeList::getNumAttrSets() const {
1693 return pImpl ? pImpl->NumAttrSets : 0;
1694 }
1695
print(raw_ostream & O) const1696 void AttributeList::print(raw_ostream &O) const {
1697 O << "AttributeList[\n";
1698
1699 for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
1700 if (!getAttributes(i).hasAttributes())
1701 continue;
1702 O << " { ";
1703 switch (i) {
1704 case AttrIndex::ReturnIndex:
1705 O << "return";
1706 break;
1707 case AttrIndex::FunctionIndex:
1708 O << "function";
1709 break;
1710 default:
1711 O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
1712 }
1713 O << " => " << getAsString(i) << " }\n";
1714 }
1715
1716 O << "]\n";
1717 }
1718
1719 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
dump() const1720 LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); }
1721 #endif
1722
1723 //===----------------------------------------------------------------------===//
1724 // AttrBuilder Method Implementations
1725 //===----------------------------------------------------------------------===//
1726
1727 // FIXME: Remove this ctor, use AttributeSet.
AttrBuilder(AttributeList AL,unsigned Index)1728 AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
1729 AttributeSet AS = AL.getAttributes(Index);
1730 for (const auto &A : AS)
1731 addAttribute(A);
1732 }
1733
AttrBuilder(AttributeSet AS)1734 AttrBuilder::AttrBuilder(AttributeSet AS) {
1735 for (const auto &A : AS)
1736 addAttribute(A);
1737 }
1738
clear()1739 void AttrBuilder::clear() {
1740 Attrs.reset();
1741 TargetDepAttrs.clear();
1742 Alignment.reset();
1743 StackAlignment.reset();
1744 DerefBytes = DerefOrNullBytes = 0;
1745 AllocSizeArgs = 0;
1746 VScaleRangeArgs = 0;
1747 ByValType = nullptr;
1748 StructRetType = nullptr;
1749 ByRefType = nullptr;
1750 PreallocatedType = nullptr;
1751 }
1752
addAttribute(Attribute Attr)1753 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1754 if (Attr.isStringAttribute()) {
1755 addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1756 return *this;
1757 }
1758
1759 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1760 Attrs[Kind] = true;
1761
1762 if (Kind == Attribute::Alignment)
1763 Alignment = Attr.getAlignment();
1764 else if (Kind == Attribute::StackAlignment)
1765 StackAlignment = Attr.getStackAlignment();
1766 else if (Kind == Attribute::ByVal)
1767 ByValType = Attr.getValueAsType();
1768 else if (Kind == Attribute::StructRet)
1769 StructRetType = Attr.getValueAsType();
1770 else if (Kind == Attribute::ByRef)
1771 ByRefType = Attr.getValueAsType();
1772 else if (Kind == Attribute::Preallocated)
1773 PreallocatedType = Attr.getValueAsType();
1774 else if (Kind == Attribute::Dereferenceable)
1775 DerefBytes = Attr.getDereferenceableBytes();
1776 else if (Kind == Attribute::DereferenceableOrNull)
1777 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1778 else if (Kind == Attribute::AllocSize)
1779 AllocSizeArgs = Attr.getValueAsInt();
1780 else if (Kind == Attribute::VScaleRange)
1781 VScaleRangeArgs = Attr.getValueAsInt();
1782 else if (Kind == Attribute::InAlloca)
1783 InAllocaType = Attr.getValueAsType();
1784
1785 return *this;
1786 }
1787
addAttribute(StringRef A,StringRef V)1788 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1789 TargetDepAttrs[A] = V;
1790 return *this;
1791 }
1792
removeAttribute(Attribute::AttrKind Val)1793 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1794 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1795 Attrs[Val] = false;
1796
1797 if (Val == Attribute::Alignment)
1798 Alignment.reset();
1799 else if (Val == Attribute::StackAlignment)
1800 StackAlignment.reset();
1801 else if (Val == Attribute::ByVal)
1802 ByValType = nullptr;
1803 else if (Val == Attribute::StructRet)
1804 StructRetType = nullptr;
1805 else if (Val == Attribute::ByRef)
1806 ByRefType = nullptr;
1807 else if (Val == Attribute::Preallocated)
1808 PreallocatedType = nullptr;
1809 else if (Val == Attribute::InAlloca)
1810 InAllocaType = nullptr;
1811 else if (Val == Attribute::Dereferenceable)
1812 DerefBytes = 0;
1813 else if (Val == Attribute::DereferenceableOrNull)
1814 DerefOrNullBytes = 0;
1815 else if (Val == Attribute::AllocSize)
1816 AllocSizeArgs = 0;
1817 else if (Val == Attribute::VScaleRange)
1818 VScaleRangeArgs = 0;
1819
1820 return *this;
1821 }
1822
removeAttributes(AttributeList A,uint64_t Index)1823 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
1824 remove(A.getAttributes(Index));
1825 return *this;
1826 }
1827
removeAttribute(StringRef A)1828 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1829 auto I = TargetDepAttrs.find(A);
1830 if (I != TargetDepAttrs.end())
1831 TargetDepAttrs.erase(I);
1832 return *this;
1833 }
1834
getAllocSizeArgs() const1835 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1836 return unpackAllocSizeArgs(AllocSizeArgs);
1837 }
1838
getVScaleRangeArgs() const1839 std::pair<unsigned, unsigned> AttrBuilder::getVScaleRangeArgs() const {
1840 return unpackVScaleRangeArgs(VScaleRangeArgs);
1841 }
1842
addAlignmentAttr(MaybeAlign Align)1843 AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
1844 if (!Align)
1845 return *this;
1846
1847 assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
1848
1849 Attrs[Attribute::Alignment] = true;
1850 Alignment = Align;
1851 return *this;
1852 }
1853
addStackAlignmentAttr(MaybeAlign Align)1854 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
1855 // Default alignment, allow the target to define how to align it.
1856 if (!Align)
1857 return *this;
1858
1859 assert(*Align <= 0x100 && "Alignment too large.");
1860
1861 Attrs[Attribute::StackAlignment] = true;
1862 StackAlignment = Align;
1863 return *this;
1864 }
1865
addDereferenceableAttr(uint64_t Bytes)1866 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1867 if (Bytes == 0) return *this;
1868
1869 Attrs[Attribute::Dereferenceable] = true;
1870 DerefBytes = Bytes;
1871 return *this;
1872 }
1873
addDereferenceableOrNullAttr(uint64_t Bytes)1874 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1875 if (Bytes == 0)
1876 return *this;
1877
1878 Attrs[Attribute::DereferenceableOrNull] = true;
1879 DerefOrNullBytes = Bytes;
1880 return *this;
1881 }
1882
addAllocSizeAttr(unsigned ElemSize,const Optional<unsigned> & NumElems)1883 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1884 const Optional<unsigned> &NumElems) {
1885 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1886 }
1887
addAllocSizeAttrFromRawRepr(uint64_t RawArgs)1888 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1889 // (0, 0) is our "not present" value, so we need to check for it here.
1890 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1891
1892 Attrs[Attribute::AllocSize] = true;
1893 // Reuse existing machinery to store this as a single 64-bit integer so we can
1894 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1895 AllocSizeArgs = RawArgs;
1896 return *this;
1897 }
1898
addVScaleRangeAttr(unsigned MinValue,unsigned MaxValue)1899 AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
1900 unsigned MaxValue) {
1901 return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
1902 }
1903
addVScaleRangeAttrFromRawRepr(uint64_t RawArgs)1904 AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
1905 // (0, 0) is not present hence ignore this case
1906 if (RawArgs == 0)
1907 return *this;
1908
1909 Attrs[Attribute::VScaleRange] = true;
1910 // Reuse existing machinery to store this as a single 64-bit integer so we can
1911 // save a few bytes over using a pair<unsigned, unsigned>.
1912 VScaleRangeArgs = RawArgs;
1913 return *this;
1914 }
1915
addByValAttr(Type * Ty)1916 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1917 Attrs[Attribute::ByVal] = true;
1918 ByValType = Ty;
1919 return *this;
1920 }
1921
addStructRetAttr(Type * Ty)1922 AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
1923 Attrs[Attribute::StructRet] = true;
1924 StructRetType = Ty;
1925 return *this;
1926 }
1927
addByRefAttr(Type * Ty)1928 AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
1929 Attrs[Attribute::ByRef] = true;
1930 ByRefType = Ty;
1931 return *this;
1932 }
1933
addPreallocatedAttr(Type * Ty)1934 AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) {
1935 Attrs[Attribute::Preallocated] = true;
1936 PreallocatedType = Ty;
1937 return *this;
1938 }
1939
addInAllocaAttr(Type * Ty)1940 AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) {
1941 Attrs[Attribute::InAlloca] = true;
1942 InAllocaType = Ty;
1943 return *this;
1944 }
1945
merge(const AttrBuilder & B)1946 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1947 // FIXME: What if both have alignments, but they don't match?!
1948 if (!Alignment)
1949 Alignment = B.Alignment;
1950
1951 if (!StackAlignment)
1952 StackAlignment = B.StackAlignment;
1953
1954 if (!DerefBytes)
1955 DerefBytes = B.DerefBytes;
1956
1957 if (!DerefOrNullBytes)
1958 DerefOrNullBytes = B.DerefOrNullBytes;
1959
1960 if (!AllocSizeArgs)
1961 AllocSizeArgs = B.AllocSizeArgs;
1962
1963 if (!ByValType)
1964 ByValType = B.ByValType;
1965
1966 if (!StructRetType)
1967 StructRetType = B.StructRetType;
1968
1969 if (!ByRefType)
1970 ByRefType = B.ByRefType;
1971
1972 if (!PreallocatedType)
1973 PreallocatedType = B.PreallocatedType;
1974
1975 if (!InAllocaType)
1976 InAllocaType = B.InAllocaType;
1977
1978 if (!VScaleRangeArgs)
1979 VScaleRangeArgs = B.VScaleRangeArgs;
1980
1981 Attrs |= B.Attrs;
1982
1983 for (const auto &I : B.td_attrs())
1984 TargetDepAttrs[I.first] = I.second;
1985
1986 return *this;
1987 }
1988
remove(const AttrBuilder & B)1989 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1990 // FIXME: What if both have alignments, but they don't match?!
1991 if (B.Alignment)
1992 Alignment.reset();
1993
1994 if (B.StackAlignment)
1995 StackAlignment.reset();
1996
1997 if (B.DerefBytes)
1998 DerefBytes = 0;
1999
2000 if (B.DerefOrNullBytes)
2001 DerefOrNullBytes = 0;
2002
2003 if (B.AllocSizeArgs)
2004 AllocSizeArgs = 0;
2005
2006 if (B.ByValType)
2007 ByValType = nullptr;
2008
2009 if (B.StructRetType)
2010 StructRetType = nullptr;
2011
2012 if (B.ByRefType)
2013 ByRefType = nullptr;
2014
2015 if (B.PreallocatedType)
2016 PreallocatedType = nullptr;
2017
2018 if (B.InAllocaType)
2019 InAllocaType = nullptr;
2020
2021 if (B.VScaleRangeArgs)
2022 VScaleRangeArgs = 0;
2023
2024 Attrs &= ~B.Attrs;
2025
2026 for (const auto &I : B.td_attrs())
2027 TargetDepAttrs.erase(I.first);
2028
2029 return *this;
2030 }
2031
overlaps(const AttrBuilder & B) const2032 bool AttrBuilder::overlaps(const AttrBuilder &B) const {
2033 // First check if any of the target independent attributes overlap.
2034 if ((Attrs & B.Attrs).any())
2035 return true;
2036
2037 // Then check if any target dependent ones do.
2038 for (const auto &I : td_attrs())
2039 if (B.contains(I.first))
2040 return true;
2041
2042 return false;
2043 }
2044
contains(StringRef A) const2045 bool AttrBuilder::contains(StringRef A) const {
2046 return TargetDepAttrs.find(A) != TargetDepAttrs.end();
2047 }
2048
hasAttributes() const2049 bool AttrBuilder::hasAttributes() const {
2050 return !Attrs.none() || !TargetDepAttrs.empty();
2051 }
2052
hasAttributes(AttributeList AL,uint64_t Index) const2053 bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const {
2054 AttributeSet AS = AL.getAttributes(Index);
2055
2056 for (const auto &Attr : AS) {
2057 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
2058 if (contains(Attr.getKindAsEnum()))
2059 return true;
2060 } else {
2061 assert(Attr.isStringAttribute() && "Invalid attribute kind!");
2062 return contains(Attr.getKindAsString());
2063 }
2064 }
2065
2066 return false;
2067 }
2068
hasAlignmentAttr() const2069 bool AttrBuilder::hasAlignmentAttr() const {
2070 return Alignment != 0;
2071 }
2072
operator ==(const AttrBuilder & B) const2073 bool AttrBuilder::operator==(const AttrBuilder &B) const {
2074 if (Attrs != B.Attrs)
2075 return false;
2076
2077 for (const auto &TDA : TargetDepAttrs)
2078 if (B.TargetDepAttrs.find(TDA.first) == B.TargetDepAttrs.end())
2079 return false;
2080
2081 return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
2082 DerefBytes == B.DerefBytes && ByValType == B.ByValType &&
2083 StructRetType == B.StructRetType && ByRefType == B.ByRefType &&
2084 PreallocatedType == B.PreallocatedType &&
2085 InAllocaType == B.InAllocaType &&
2086 VScaleRangeArgs == B.VScaleRangeArgs;
2087 }
2088
2089 //===----------------------------------------------------------------------===//
2090 // AttributeFuncs Function Defintions
2091 //===----------------------------------------------------------------------===//
2092
2093 /// Which attributes cannot be applied to a type.
typeIncompatible(Type * Ty)2094 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
2095 AttrBuilder Incompatible;
2096
2097 if (!Ty->isIntegerTy())
2098 // Attribute that only apply to integers.
2099 Incompatible.addAttribute(Attribute::SExt)
2100 .addAttribute(Attribute::ZExt);
2101
2102 if (!Ty->isPointerTy())
2103 // Attribute that only apply to pointers.
2104 Incompatible.addAttribute(Attribute::Nest)
2105 .addAttribute(Attribute::NoAlias)
2106 .addAttribute(Attribute::NoCapture)
2107 .addAttribute(Attribute::NonNull)
2108 .addAlignmentAttr(1) // the int here is ignored
2109 .addDereferenceableAttr(1) // the int here is ignored
2110 .addDereferenceableOrNullAttr(1) // the int here is ignored
2111 .addAttribute(Attribute::ReadNone)
2112 .addAttribute(Attribute::ReadOnly)
2113 .addAttribute(Attribute::InAlloca)
2114 .addPreallocatedAttr(Ty)
2115 .addInAllocaAttr(Ty)
2116 .addByValAttr(Ty)
2117 .addStructRetAttr(Ty)
2118 .addByRefAttr(Ty);
2119
2120 // Some attributes can apply to all "values" but there are no `void` values.
2121 if (Ty->isVoidTy())
2122 Incompatible.addAttribute(Attribute::NoUndef);
2123
2124 return Incompatible;
2125 }
2126
2127 template<typename AttrClass>
isEqual(const Function & Caller,const Function & Callee)2128 static bool isEqual(const Function &Caller, const Function &Callee) {
2129 return Caller.getFnAttribute(AttrClass::getKind()) ==
2130 Callee.getFnAttribute(AttrClass::getKind());
2131 }
2132
2133 /// Compute the logical AND of the attributes of the caller and the
2134 /// callee.
2135 ///
2136 /// This function sets the caller's attribute to false if the callee's attribute
2137 /// is false.
2138 template<typename AttrClass>
setAND(Function & Caller,const Function & Callee)2139 static void setAND(Function &Caller, const Function &Callee) {
2140 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2141 !AttrClass::isSet(Callee, AttrClass::getKind()))
2142 AttrClass::set(Caller, AttrClass::getKind(), false);
2143 }
2144
2145 /// Compute the logical OR of the attributes of the caller and the
2146 /// callee.
2147 ///
2148 /// This function sets the caller's attribute to true if the callee's attribute
2149 /// is true.
2150 template<typename AttrClass>
setOR(Function & Caller,const Function & Callee)2151 static void setOR(Function &Caller, const Function &Callee) {
2152 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2153 AttrClass::isSet(Callee, AttrClass::getKind()))
2154 AttrClass::set(Caller, AttrClass::getKind(), true);
2155 }
2156
2157 /// If the inlined function had a higher stack protection level than the
2158 /// calling function, then bump up the caller's stack protection level.
adjustCallerSSPLevel(Function & Caller,const Function & Callee)2159 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
2160 #ifndef NDEBUG
2161 if (!Callee.hasFnAttribute(Attribute::AlwaysInline)) {
2162 assert(!(!Callee.hasStackProtectorFnAttr() &&
2163 Caller.hasStackProtectorFnAttr()) &&
2164 "stack protected caller but callee requested no stack protector");
2165 assert(!(!Caller.hasStackProtectorFnAttr() &&
2166 Callee.hasStackProtectorFnAttr()) &&
2167 "stack protected callee but caller requested no stack protector");
2168 }
2169 #endif
2170 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
2171 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
2172 // clutter to the IR.
2173 AttrBuilder OldSSPAttr;
2174 OldSSPAttr.addAttribute(Attribute::StackProtect)
2175 .addAttribute(Attribute::StackProtectStrong)
2176 .addAttribute(Attribute::StackProtectReq);
2177
2178 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2179 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
2180 Caller.addFnAttr(Attribute::StackProtectReq);
2181 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2182 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2183 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
2184 Caller.addFnAttr(Attribute::StackProtectStrong);
2185 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2186 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2187 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2188 Caller.addFnAttr(Attribute::StackProtect);
2189 }
2190
2191 /// If the inlined function required stack probes, then ensure that
2192 /// the calling function has those too.
adjustCallerStackProbes(Function & Caller,const Function & Callee)2193 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
2194 if (!Caller.hasFnAttribute("probe-stack") &&
2195 Callee.hasFnAttribute("probe-stack")) {
2196 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
2197 }
2198 }
2199
2200 /// If the inlined function defines the size of guard region
2201 /// on the stack, then ensure that the calling function defines a guard region
2202 /// that is no larger.
2203 static void
adjustCallerStackProbeSize(Function & Caller,const Function & Callee)2204 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
2205 Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
2206 if (CalleeAttr.isValid()) {
2207 Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
2208 if (CallerAttr.isValid()) {
2209 uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2210 CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
2211 CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
2212
2213 if (CallerStackProbeSize > CalleeStackProbeSize) {
2214 Caller.addFnAttr(CalleeAttr);
2215 }
2216 } else {
2217 Caller.addFnAttr(CalleeAttr);
2218 }
2219 }
2220 }
2221
2222 /// If the inlined function defines a min legal vector width, then ensure
2223 /// the calling function has the same or larger min legal vector width. If the
2224 /// caller has the attribute, but the callee doesn't, we need to remove the
2225 /// attribute from the caller since we can't make any guarantees about the
2226 /// caller's requirements.
2227 /// This function is called after the inlining decision has been made so we have
2228 /// to merge the attribute this way. Heuristics that would use
2229 /// min-legal-vector-width to determine inline compatibility would need to be
2230 /// handled as part of inline cost analysis.
2231 static void
adjustMinLegalVectorWidth(Function & Caller,const Function & Callee)2232 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
2233 Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
2234 if (CallerAttr.isValid()) {
2235 Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
2236 if (CalleeAttr.isValid()) {
2237 uint64_t CallerVectorWidth, CalleeVectorWidth;
2238 CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
2239 CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
2240 if (CallerVectorWidth < CalleeVectorWidth)
2241 Caller.addFnAttr(CalleeAttr);
2242 } else {
2243 // If the callee doesn't have the attribute then we don't know anything
2244 // and must drop the attribute from the caller.
2245 Caller.removeFnAttr("min-legal-vector-width");
2246 }
2247 }
2248 }
2249
2250 /// If the inlined function has null_pointer_is_valid attribute,
2251 /// set this attribute in the caller post inlining.
2252 static void
adjustNullPointerValidAttr(Function & Caller,const Function & Callee)2253 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
2254 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2255 Caller.addFnAttr(Attribute::NullPointerIsValid);
2256 }
2257 }
2258
2259 struct EnumAttr {
isSetEnumAttr2260 static bool isSet(const Function &Fn,
2261 Attribute::AttrKind Kind) {
2262 return Fn.hasFnAttribute(Kind);
2263 }
2264
setEnumAttr2265 static void set(Function &Fn,
2266 Attribute::AttrKind Kind, bool Val) {
2267 if (Val)
2268 Fn.addFnAttr(Kind);
2269 else
2270 Fn.removeFnAttr(Kind);
2271 }
2272 };
2273
2274 struct StrBoolAttr {
isSetStrBoolAttr2275 static bool isSet(const Function &Fn,
2276 StringRef Kind) {
2277 auto A = Fn.getFnAttribute(Kind);
2278 return A.getValueAsString().equals("true");
2279 }
2280
setStrBoolAttr2281 static void set(Function &Fn,
2282 StringRef Kind, bool Val) {
2283 Fn.addFnAttr(Kind, Val ? "true" : "false");
2284 }
2285 };
2286
2287 #define GET_ATTR_NAMES
2288 #define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME) \
2289 struct ENUM_NAME##Attr : EnumAttr { \
2290 static enum Attribute::AttrKind getKind() { \
2291 return llvm::Attribute::ENUM_NAME; \
2292 } \
2293 };
2294 #define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME) \
2295 struct ENUM_NAME##Attr : StrBoolAttr { \
2296 static StringRef getKind() { return #DISPLAY_NAME; } \
2297 };
2298 #include "llvm/IR/Attributes.inc"
2299
2300 #define GET_ATTR_COMPAT_FUNC
2301 #include "llvm/IR/Attributes.inc"
2302
areInlineCompatible(const Function & Caller,const Function & Callee)2303 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
2304 const Function &Callee) {
2305 return hasCompatibleFnAttrs(Caller, Callee);
2306 }
2307
areOutlineCompatible(const Function & A,const Function & B)2308 bool AttributeFuncs::areOutlineCompatible(const Function &A,
2309 const Function &B) {
2310 return hasCompatibleFnAttrs(A, B);
2311 }
2312
mergeAttributesForInlining(Function & Caller,const Function & Callee)2313 void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
2314 const Function &Callee) {
2315 mergeFnAttrs(Caller, Callee);
2316 }
2317
mergeAttributesForOutlining(Function & Base,const Function & ToMerge)2318 void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
2319 const Function &ToMerge) {
2320
2321 // We merge functions so that they meet the most general case.
2322 // For example, if the NoNansFPMathAttr is set in one function, but not in
2323 // the other, in the merged function we can say that the NoNansFPMathAttr
2324 // is not set.
2325 // However if we have the SpeculativeLoadHardeningAttr set true in one
2326 // function, but not the other, we make sure that the function retains
2327 // that aspect in the merged function.
2328 mergeFnAttrs(Base, ToMerge);
2329 }
2330