[ARM] MVE Vector Shifts
[llvm-core.git] / lib / IR / Attributes.cpp
blob1ba703bb14c7628bba69fdd776447521ba29581a
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.
13 //===----------------------------------------------------------------------===//
15 #include "llvm/IR/Attributes.h"
16 #include "AttributeImpl.h"
17 #include "LLVMContextImpl.h"
18 #include "llvm/ADT/ArrayRef.h"
19 #include "llvm/ADT/FoldingSet.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/STLExtras.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/StringExtras.h"
24 #include "llvm/ADT/StringRef.h"
25 #include "llvm/ADT/Twine.h"
26 #include "llvm/Config/llvm-config.h"
27 #include "llvm/IR/Function.h"
28 #include "llvm/IR/LLVMContext.h"
29 #include "llvm/IR/Type.h"
30 #include "llvm/Support/Compiler.h"
31 #include "llvm/Support/Debug.h"
32 #include "llvm/Support/ErrorHandling.h"
33 #include "llvm/Support/MathExtras.h"
34 #include "llvm/Support/raw_ostream.h"
35 #include <algorithm>
36 #include <cassert>
37 #include <climits>
38 #include <cstddef>
39 #include <cstdint>
40 #include <limits>
41 #include <string>
42 #include <tuple>
43 #include <utility>
45 using namespace llvm;
47 //===----------------------------------------------------------------------===//
48 // Attribute Construction Methods
49 //===----------------------------------------------------------------------===//
51 // allocsize has two integer arguments, but because they're both 32 bits, we can
52 // pack them into one 64-bit value, at the cost of making said value
53 // nonsensical.
55 // In order to do this, we need to reserve one value of the second (optional)
56 // allocsize argument to signify "not present."
57 static const unsigned AllocSizeNumElemsNotPresent = -1;
59 static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
60 const Optional<unsigned> &NumElemsArg) {
61 assert((!NumElemsArg.hasValue() ||
62 *NumElemsArg != AllocSizeNumElemsNotPresent) &&
63 "Attempting to pack a reserved value");
65 return uint64_t(ElemSizeArg) << 32 |
66 NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
69 static std::pair<unsigned, Optional<unsigned>>
70 unpackAllocSizeArgs(uint64_t Num) {
71 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
72 unsigned ElemSizeArg = Num >> 32;
74 Optional<unsigned> NumElemsArg;
75 if (NumElems != AllocSizeNumElemsNotPresent)
76 NumElemsArg = NumElems;
77 return std::make_pair(ElemSizeArg, NumElemsArg);
80 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
81 uint64_t Val) {
82 LLVMContextImpl *pImpl = Context.pImpl;
83 FoldingSetNodeID ID;
84 ID.AddInteger(Kind);
85 if (Val) ID.AddInteger(Val);
87 void *InsertPoint;
88 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
90 if (!PA) {
91 // If we didn't find any existing attributes of the same shape then create a
92 // new one and insert it.
93 if (!Val)
94 PA = new EnumAttributeImpl(Kind);
95 else
96 PA = new IntAttributeImpl(Kind, Val);
97 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
100 // Return the Attribute that we found or created.
101 return Attribute(PA);
104 Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
105 LLVMContextImpl *pImpl = Context.pImpl;
106 FoldingSetNodeID ID;
107 ID.AddString(Kind);
108 if (!Val.empty()) ID.AddString(Val);
110 void *InsertPoint;
111 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
113 if (!PA) {
114 // If we didn't find any existing attributes of the same shape then create a
115 // new one and insert it.
116 PA = new StringAttributeImpl(Kind, Val);
117 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
120 // Return the Attribute that we found or created.
121 return Attribute(PA);
124 Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
125 Type *Ty) {
126 LLVMContextImpl *pImpl = Context.pImpl;
127 FoldingSetNodeID ID;
128 ID.AddInteger(Kind);
129 ID.AddPointer(Ty);
131 void *InsertPoint;
132 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
134 if (!PA) {
135 // If we didn't find any existing attributes of the same shape then create a
136 // new one and insert it.
137 PA = new TypeAttributeImpl(Kind, Ty);
138 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
141 // Return the Attribute that we found or created.
142 return Attribute(PA);
145 Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
146 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
147 assert(Align <= 0x40000000 && "Alignment too large.");
148 return get(Context, Alignment, Align);
151 Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
152 uint64_t Align) {
153 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
154 assert(Align <= 0x100 && "Alignment too large.");
155 return get(Context, StackAlignment, Align);
158 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
159 uint64_t Bytes) {
160 assert(Bytes && "Bytes must be non-zero.");
161 return get(Context, Dereferenceable, Bytes);
164 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
165 uint64_t Bytes) {
166 assert(Bytes && "Bytes must be non-zero.");
167 return get(Context, DereferenceableOrNull, Bytes);
170 Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
171 return get(Context, ByVal, Ty);
174 Attribute
175 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
176 const Optional<unsigned> &NumElemsArg) {
177 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
178 "Invalid allocsize arguments -- given allocsize(0, 0)");
179 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
182 //===----------------------------------------------------------------------===//
183 // Attribute Accessor Methods
184 //===----------------------------------------------------------------------===//
186 bool Attribute::isEnumAttribute() const {
187 return pImpl && pImpl->isEnumAttribute();
190 bool Attribute::isIntAttribute() const {
191 return pImpl && pImpl->isIntAttribute();
194 bool Attribute::isStringAttribute() const {
195 return pImpl && pImpl->isStringAttribute();
198 bool Attribute::isTypeAttribute() const {
199 return pImpl && pImpl->isTypeAttribute();
202 Attribute::AttrKind Attribute::getKindAsEnum() const {
203 if (!pImpl) return None;
204 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
205 "Invalid attribute type to get the kind as an enum!");
206 return pImpl->getKindAsEnum();
209 uint64_t Attribute::getValueAsInt() const {
210 if (!pImpl) return 0;
211 assert(isIntAttribute() &&
212 "Expected the attribute to be an integer attribute!");
213 return pImpl->getValueAsInt();
216 StringRef Attribute::getKindAsString() const {
217 if (!pImpl) return {};
218 assert(isStringAttribute() &&
219 "Invalid attribute type to get the kind as a string!");
220 return pImpl->getKindAsString();
223 StringRef Attribute::getValueAsString() const {
224 if (!pImpl) return {};
225 assert(isStringAttribute() &&
226 "Invalid attribute type to get the value as a string!");
227 return pImpl->getValueAsString();
230 Type *Attribute::getValueAsType() const {
231 if (!pImpl) return {};
232 assert(isTypeAttribute() &&
233 "Invalid attribute type to get the value as a type!");
234 return pImpl->getValueAsType();
238 bool Attribute::hasAttribute(AttrKind Kind) const {
239 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
242 bool Attribute::hasAttribute(StringRef Kind) const {
243 if (!isStringAttribute()) return false;
244 return pImpl && pImpl->hasAttribute(Kind);
247 unsigned Attribute::getAlignment() const {
248 assert(hasAttribute(Attribute::Alignment) &&
249 "Trying to get alignment from non-alignment attribute!");
250 return pImpl->getValueAsInt();
253 unsigned Attribute::getStackAlignment() const {
254 assert(hasAttribute(Attribute::StackAlignment) &&
255 "Trying to get alignment from non-alignment attribute!");
256 return pImpl->getValueAsInt();
259 uint64_t Attribute::getDereferenceableBytes() const {
260 assert(hasAttribute(Attribute::Dereferenceable) &&
261 "Trying to get dereferenceable bytes from "
262 "non-dereferenceable attribute!");
263 return pImpl->getValueAsInt();
266 uint64_t Attribute::getDereferenceableOrNullBytes() const {
267 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
268 "Trying to get dereferenceable bytes from "
269 "non-dereferenceable attribute!");
270 return pImpl->getValueAsInt();
273 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
274 assert(hasAttribute(Attribute::AllocSize) &&
275 "Trying to get allocsize args from non-allocsize attribute");
276 return unpackAllocSizeArgs(pImpl->getValueAsInt());
279 std::string Attribute::getAsString(bool InAttrGrp) const {
280 if (!pImpl) return {};
282 if (hasAttribute(Attribute::SanitizeAddress))
283 return "sanitize_address";
284 if (hasAttribute(Attribute::SanitizeHWAddress))
285 return "sanitize_hwaddress";
286 if (hasAttribute(Attribute::AlwaysInline))
287 return "alwaysinline";
288 if (hasAttribute(Attribute::ArgMemOnly))
289 return "argmemonly";
290 if (hasAttribute(Attribute::Builtin))
291 return "builtin";
292 if (hasAttribute(Attribute::Convergent))
293 return "convergent";
294 if (hasAttribute(Attribute::SwiftError))
295 return "swifterror";
296 if (hasAttribute(Attribute::SwiftSelf))
297 return "swiftself";
298 if (hasAttribute(Attribute::InaccessibleMemOnly))
299 return "inaccessiblememonly";
300 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
301 return "inaccessiblemem_or_argmemonly";
302 if (hasAttribute(Attribute::InAlloca))
303 return "inalloca";
304 if (hasAttribute(Attribute::InlineHint))
305 return "inlinehint";
306 if (hasAttribute(Attribute::InReg))
307 return "inreg";
308 if (hasAttribute(Attribute::JumpTable))
309 return "jumptable";
310 if (hasAttribute(Attribute::MinSize))
311 return "minsize";
312 if (hasAttribute(Attribute::Naked))
313 return "naked";
314 if (hasAttribute(Attribute::Nest))
315 return "nest";
316 if (hasAttribute(Attribute::NoAlias))
317 return "noalias";
318 if (hasAttribute(Attribute::NoBuiltin))
319 return "nobuiltin";
320 if (hasAttribute(Attribute::NoCapture))
321 return "nocapture";
322 if (hasAttribute(Attribute::NoDuplicate))
323 return "noduplicate";
324 if (hasAttribute(Attribute::NoFree))
325 return "nofree";
326 if (hasAttribute(Attribute::NoImplicitFloat))
327 return "noimplicitfloat";
328 if (hasAttribute(Attribute::NoInline))
329 return "noinline";
330 if (hasAttribute(Attribute::NonLazyBind))
331 return "nonlazybind";
332 if (hasAttribute(Attribute::NonNull))
333 return "nonnull";
334 if (hasAttribute(Attribute::NoRedZone))
335 return "noredzone";
336 if (hasAttribute(Attribute::NoReturn))
337 return "noreturn";
338 if (hasAttribute(Attribute::NoSync))
339 return "nosync";
340 if (hasAttribute(Attribute::WillReturn))
341 return "willreturn";
342 if (hasAttribute(Attribute::NoCfCheck))
343 return "nocf_check";
344 if (hasAttribute(Attribute::NoRecurse))
345 return "norecurse";
346 if (hasAttribute(Attribute::NoUnwind))
347 return "nounwind";
348 if (hasAttribute(Attribute::OptForFuzzing))
349 return "optforfuzzing";
350 if (hasAttribute(Attribute::OptimizeNone))
351 return "optnone";
352 if (hasAttribute(Attribute::OptimizeForSize))
353 return "optsize";
354 if (hasAttribute(Attribute::ReadNone))
355 return "readnone";
356 if (hasAttribute(Attribute::ReadOnly))
357 return "readonly";
358 if (hasAttribute(Attribute::WriteOnly))
359 return "writeonly";
360 if (hasAttribute(Attribute::Returned))
361 return "returned";
362 if (hasAttribute(Attribute::ReturnsTwice))
363 return "returns_twice";
364 if (hasAttribute(Attribute::SExt))
365 return "signext";
366 if (hasAttribute(Attribute::SpeculativeLoadHardening))
367 return "speculative_load_hardening";
368 if (hasAttribute(Attribute::Speculatable))
369 return "speculatable";
370 if (hasAttribute(Attribute::StackProtect))
371 return "ssp";
372 if (hasAttribute(Attribute::StackProtectReq))
373 return "sspreq";
374 if (hasAttribute(Attribute::StackProtectStrong))
375 return "sspstrong";
376 if (hasAttribute(Attribute::SafeStack))
377 return "safestack";
378 if (hasAttribute(Attribute::ShadowCallStack))
379 return "shadowcallstack";
380 if (hasAttribute(Attribute::StrictFP))
381 return "strictfp";
382 if (hasAttribute(Attribute::StructRet))
383 return "sret";
384 if (hasAttribute(Attribute::SanitizeThread))
385 return "sanitize_thread";
386 if (hasAttribute(Attribute::SanitizeMemory))
387 return "sanitize_memory";
388 if (hasAttribute(Attribute::UWTable))
389 return "uwtable";
390 if (hasAttribute(Attribute::ZExt))
391 return "zeroext";
392 if (hasAttribute(Attribute::Cold))
393 return "cold";
394 if (hasAttribute(Attribute::ImmArg))
395 return "immarg";
397 if (hasAttribute(Attribute::ByVal)) {
398 std::string Result;
399 Result += "byval";
400 if (Type *Ty = getValueAsType()) {
401 raw_string_ostream OS(Result);
402 Result += '(';
403 Ty->print(OS, false, true);
404 OS.flush();
405 Result += ')';
407 return Result;
410 // FIXME: These should be output like this:
412 // align=4
413 // alignstack=8
415 if (hasAttribute(Attribute::Alignment)) {
416 std::string Result;
417 Result += "align";
418 Result += (InAttrGrp) ? "=" : " ";
419 Result += utostr(getValueAsInt());
420 return Result;
423 auto AttrWithBytesToString = [&](const char *Name) {
424 std::string Result;
425 Result += Name;
426 if (InAttrGrp) {
427 Result += "=";
428 Result += utostr(getValueAsInt());
429 } else {
430 Result += "(";
431 Result += utostr(getValueAsInt());
432 Result += ")";
434 return Result;
437 if (hasAttribute(Attribute::StackAlignment))
438 return AttrWithBytesToString("alignstack");
440 if (hasAttribute(Attribute::Dereferenceable))
441 return AttrWithBytesToString("dereferenceable");
443 if (hasAttribute(Attribute::DereferenceableOrNull))
444 return AttrWithBytesToString("dereferenceable_or_null");
446 if (hasAttribute(Attribute::AllocSize)) {
447 unsigned ElemSize;
448 Optional<unsigned> NumElems;
449 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
451 std::string Result = "allocsize(";
452 Result += utostr(ElemSize);
453 if (NumElems.hasValue()) {
454 Result += ',';
455 Result += utostr(*NumElems);
457 Result += ')';
458 return Result;
461 // Convert target-dependent attributes to strings of the form:
463 // "kind"
464 // "kind" = "value"
466 if (isStringAttribute()) {
467 std::string Result;
468 Result += (Twine('"') + getKindAsString() + Twine('"')).str();
470 std::string AttrVal = pImpl->getValueAsString();
471 if (AttrVal.empty()) return Result;
473 // Since some attribute strings contain special characters that cannot be
474 // printable, those have to be escaped to make the attribute value printable
475 // as is. e.g. "\01__gnu_mcount_nc"
477 raw_string_ostream OS(Result);
478 OS << "=\"";
479 printEscapedString(AttrVal, OS);
480 OS << "\"";
482 return Result;
485 llvm_unreachable("Unknown attribute");
488 bool Attribute::operator<(Attribute A) const {
489 if (!pImpl && !A.pImpl) return false;
490 if (!pImpl) return true;
491 if (!A.pImpl) return false;
492 return *pImpl < *A.pImpl;
495 //===----------------------------------------------------------------------===//
496 // AttributeImpl Definition
497 //===----------------------------------------------------------------------===//
499 // Pin the vtables to this file.
500 AttributeImpl::~AttributeImpl() = default;
502 void EnumAttributeImpl::anchor() {}
504 void IntAttributeImpl::anchor() {}
506 void StringAttributeImpl::anchor() {}
508 void TypeAttributeImpl::anchor() {}
510 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
511 if (isStringAttribute()) return false;
512 return getKindAsEnum() == A;
515 bool AttributeImpl::hasAttribute(StringRef Kind) const {
516 if (!isStringAttribute()) return false;
517 return getKindAsString() == Kind;
520 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
521 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
522 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
525 uint64_t AttributeImpl::getValueAsInt() const {
526 assert(isIntAttribute());
527 return static_cast<const IntAttributeImpl *>(this)->getValue();
530 StringRef AttributeImpl::getKindAsString() const {
531 assert(isStringAttribute());
532 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
535 StringRef AttributeImpl::getValueAsString() const {
536 assert(isStringAttribute());
537 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
540 Type *AttributeImpl::getValueAsType() const {
541 assert(isTypeAttribute());
542 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
545 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
546 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
547 // relative to their enum value) and then strings.
548 if (isEnumAttribute()) {
549 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
550 if (AI.isIntAttribute()) return true;
551 if (AI.isStringAttribute()) return true;
552 if (AI.isTypeAttribute()) return true;
555 if (isTypeAttribute()) {
556 if (AI.isEnumAttribute()) return false;
557 if (AI.isTypeAttribute()) {
558 assert(getKindAsEnum() != AI.getKindAsEnum() &&
559 "Comparison of types would be unstable");
560 return getKindAsEnum() < AI.getKindAsEnum();
562 if (AI.isIntAttribute()) return true;
563 if (AI.isStringAttribute()) return true;
566 if (isIntAttribute()) {
567 if (AI.isEnumAttribute()) return false;
568 if (AI.isTypeAttribute()) return false;
569 if (AI.isIntAttribute()) {
570 if (getKindAsEnum() == AI.getKindAsEnum())
571 return getValueAsInt() < AI.getValueAsInt();
572 return getKindAsEnum() < AI.getKindAsEnum();
574 if (AI.isStringAttribute()) return true;
577 assert(isStringAttribute());
578 if (AI.isEnumAttribute()) return false;
579 if (AI.isTypeAttribute()) return false;
580 if (AI.isIntAttribute()) return false;
581 if (getKindAsString() == AI.getKindAsString())
582 return getValueAsString() < AI.getValueAsString();
583 return getKindAsString() < AI.getKindAsString();
586 //===----------------------------------------------------------------------===//
587 // AttributeSet Definition
588 //===----------------------------------------------------------------------===//
590 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
591 return AttributeSet(AttributeSetNode::get(C, B));
594 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
595 return AttributeSet(AttributeSetNode::get(C, Attrs));
598 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));
606 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));
613 AttributeSet AttributeSet::addAttributes(LLVMContext &C,
614 const AttributeSet AS) const {
615 if (!hasAttributes())
616 return AS;
618 if (!AS.hasAttributes())
619 return *this;
621 AttrBuilder B(AS);
622 for (const auto I : *this)
623 B.addAttribute(I);
625 return get(C, B);
628 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);
636 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);
644 AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
645 const AttrBuilder &Attrs) const {
646 AttrBuilder B(*this);
647 B.remove(Attrs);
648 return get(C, B);
651 unsigned AttributeSet::getNumAttributes() const {
652 return SetNode ? SetNode->getNumAttributes() : 0;
655 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
656 return SetNode ? SetNode->hasAttribute(Kind) : false;
659 bool AttributeSet::hasAttribute(StringRef Kind) const {
660 return SetNode ? SetNode->hasAttribute(Kind) : false;
663 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
664 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
667 Attribute AttributeSet::getAttribute(StringRef Kind) const {
668 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
671 unsigned AttributeSet::getAlignment() const {
672 return SetNode ? SetNode->getAlignment() : 0;
675 unsigned AttributeSet::getStackAlignment() const {
676 return SetNode ? SetNode->getStackAlignment() : 0;
679 uint64_t AttributeSet::getDereferenceableBytes() const {
680 return SetNode ? SetNode->getDereferenceableBytes() : 0;
683 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
684 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
687 Type *AttributeSet::getByValType() const {
688 return SetNode ? SetNode->getByValType() : nullptr;
691 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
692 return SetNode ? SetNode->getAllocSizeArgs()
693 : std::pair<unsigned, Optional<unsigned>>(0, 0);
696 std::string AttributeSet::getAsString(bool InAttrGrp) const {
697 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
700 AttributeSet::iterator AttributeSet::begin() const {
701 return SetNode ? SetNode->begin() : nullptr;
704 AttributeSet::iterator AttributeSet::end() const {
705 return SetNode ? SetNode->end() : nullptr;
708 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
709 LLVM_DUMP_METHOD void AttributeSet::dump() const {
710 dbgs() << "AS =\n";
711 dbgs() << " { ";
712 dbgs() << getAsString(true) << " }\n";
714 #endif
716 //===----------------------------------------------------------------------===//
717 // AttributeSetNode Definition
718 //===----------------------------------------------------------------------===//
720 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
721 : NumAttrs(Attrs.size()) {
722 // There's memory after the node where we can store the entries in.
723 llvm::copy(Attrs, getTrailingObjects<Attribute>());
725 static_assert(Attribute::EndAttrKinds <=
726 sizeof(AvailableAttrs) * CHAR_BIT,
727 "Too many attributes");
729 for (const auto I : *this) {
730 if (!I.isStringAttribute()) {
731 Attribute::AttrKind Kind = I.getKindAsEnum();
732 AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8);
737 AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
738 ArrayRef<Attribute> Attrs) {
739 if (Attrs.empty())
740 return nullptr;
742 // Otherwise, build a key to look up the existing attributes.
743 LLVMContextImpl *pImpl = C.pImpl;
744 FoldingSetNodeID ID;
746 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
747 llvm::sort(SortedAttrs);
749 for (const auto Attr : SortedAttrs)
750 Attr.Profile(ID);
752 void *InsertPoint;
753 AttributeSetNode *PA =
754 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
756 // If we didn't find any existing attributes of the same shape then create a
757 // new one and insert it.
758 if (!PA) {
759 // Coallocate entries after the AttributeSetNode itself.
760 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
761 PA = new (Mem) AttributeSetNode(SortedAttrs);
762 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
765 // Return the AttributeSetNode that we found or created.
766 return PA;
769 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
770 // Add target-independent attributes.
771 SmallVector<Attribute, 8> Attrs;
772 for (Attribute::AttrKind Kind = Attribute::None;
773 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
774 if (!B.contains(Kind))
775 continue;
777 Attribute Attr;
778 switch (Kind) {
779 case Attribute::ByVal:
780 Attr = Attribute::getWithByValType(C, B.getByValType());
781 break;
782 case Attribute::Alignment:
783 Attr = Attribute::getWithAlignment(C, B.getAlignment());
784 break;
785 case Attribute::StackAlignment:
786 Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
787 break;
788 case Attribute::Dereferenceable:
789 Attr = Attribute::getWithDereferenceableBytes(
790 C, B.getDereferenceableBytes());
791 break;
792 case Attribute::DereferenceableOrNull:
793 Attr = Attribute::getWithDereferenceableOrNullBytes(
794 C, B.getDereferenceableOrNullBytes());
795 break;
796 case Attribute::AllocSize: {
797 auto A = B.getAllocSizeArgs();
798 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
799 break;
801 default:
802 Attr = Attribute::get(C, Kind);
804 Attrs.push_back(Attr);
807 // Add target-dependent (string) attributes.
808 for (const auto &TDA : B.td_attrs())
809 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
811 return get(C, Attrs);
814 bool AttributeSetNode::hasAttribute(StringRef Kind) const {
815 for (const auto I : *this)
816 if (I.hasAttribute(Kind))
817 return true;
818 return false;
821 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
822 if (hasAttribute(Kind)) {
823 for (const auto I : *this)
824 if (I.hasAttribute(Kind))
825 return I;
827 return {};
830 Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
831 for (const auto I : *this)
832 if (I.hasAttribute(Kind))
833 return I;
834 return {};
837 unsigned AttributeSetNode::getAlignment() const {
838 for (const auto I : *this)
839 if (I.hasAttribute(Attribute::Alignment))
840 return I.getAlignment();
841 return 0;
844 unsigned AttributeSetNode::getStackAlignment() const {
845 for (const auto I : *this)
846 if (I.hasAttribute(Attribute::StackAlignment))
847 return I.getStackAlignment();
848 return 0;
851 Type *AttributeSetNode::getByValType() const {
852 for (const auto I : *this)
853 if (I.hasAttribute(Attribute::ByVal))
854 return I.getValueAsType();
855 return 0;
858 uint64_t AttributeSetNode::getDereferenceableBytes() const {
859 for (const auto I : *this)
860 if (I.hasAttribute(Attribute::Dereferenceable))
861 return I.getDereferenceableBytes();
862 return 0;
865 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
866 for (const auto I : *this)
867 if (I.hasAttribute(Attribute::DereferenceableOrNull))
868 return I.getDereferenceableOrNullBytes();
869 return 0;
872 std::pair<unsigned, Optional<unsigned>>
873 AttributeSetNode::getAllocSizeArgs() const {
874 for (const auto I : *this)
875 if (I.hasAttribute(Attribute::AllocSize))
876 return I.getAllocSizeArgs();
877 return std::make_pair(0, 0);
880 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
881 std::string Str;
882 for (iterator I = begin(), E = end(); I != E; ++I) {
883 if (I != begin())
884 Str += ' ';
885 Str += I->getAsString(InAttrGrp);
887 return Str;
890 //===----------------------------------------------------------------------===//
891 // AttributeListImpl Definition
892 //===----------------------------------------------------------------------===//
894 /// Map from AttributeList index to the internal array index. Adding one happens
895 /// to work, but it relies on unsigned integer wrapping. MSVC warns about
896 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
897 /// folds it to add anyway.
898 static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
899 return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
902 AttributeListImpl::AttributeListImpl(LLVMContext &C,
903 ArrayRef<AttributeSet> Sets)
904 : Context(C), NumAttrSets(Sets.size()) {
905 assert(!Sets.empty() && "pointless AttributeListImpl");
907 // There's memory after the node where we can store the entries in.
908 llvm::copy(Sets, getTrailingObjects<AttributeSet>());
910 // Initialize AvailableFunctionAttrs summary bitset.
911 static_assert(Attribute::EndAttrKinds <=
912 sizeof(AvailableFunctionAttrs) * CHAR_BIT,
913 "Too many attributes");
914 static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
915 "function should be stored in slot 0");
916 for (const auto I : Sets[0]) {
917 if (!I.isStringAttribute()) {
918 Attribute::AttrKind Kind = I.getKindAsEnum();
919 AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8);
924 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
925 Profile(ID, makeArrayRef(begin(), end()));
928 void AttributeListImpl::Profile(FoldingSetNodeID &ID,
929 ArrayRef<AttributeSet> Sets) {
930 for (const auto &Set : Sets)
931 ID.AddPointer(Set.SetNode);
934 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
935 LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
936 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
938 #endif
940 //===----------------------------------------------------------------------===//
941 // AttributeList Construction and Mutation Methods
942 //===----------------------------------------------------------------------===//
944 AttributeList AttributeList::getImpl(LLVMContext &C,
945 ArrayRef<AttributeSet> AttrSets) {
946 assert(!AttrSets.empty() && "pointless AttributeListImpl");
948 LLVMContextImpl *pImpl = C.pImpl;
949 FoldingSetNodeID ID;
950 AttributeListImpl::Profile(ID, AttrSets);
952 void *InsertPoint;
953 AttributeListImpl *PA =
954 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
956 // If we didn't find any existing attributes of the same shape then
957 // create a new one and insert it.
958 if (!PA) {
959 // Coallocate entries after the AttributeListImpl itself.
960 void *Mem = ::operator new(
961 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
962 PA = new (Mem) AttributeListImpl(C, AttrSets);
963 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
966 // Return the AttributesList that we found or created.
967 return AttributeList(PA);
970 AttributeList
971 AttributeList::get(LLVMContext &C,
972 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
973 // If there are no attributes then return a null AttributesList pointer.
974 if (Attrs.empty())
975 return {};
977 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
978 [](const std::pair<unsigned, Attribute> &LHS,
979 const std::pair<unsigned, Attribute> &RHS) {
980 return LHS.first < RHS.first;
981 }) && "Misordered Attributes list!");
982 assert(llvm::none_of(Attrs,
983 [](const std::pair<unsigned, Attribute> &Pair) {
984 return Pair.second.hasAttribute(Attribute::None);
985 }) &&
986 "Pointless attribute!");
988 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
989 // list.
990 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
991 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
992 E = Attrs.end(); I != E; ) {
993 unsigned Index = I->first;
994 SmallVector<Attribute, 4> AttrVec;
995 while (I != E && I->first == Index) {
996 AttrVec.push_back(I->second);
997 ++I;
1000 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1003 return get(C, AttrPairVec);
1006 AttributeList
1007 AttributeList::get(LLVMContext &C,
1008 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1009 // If there are no attributes then return a null AttributesList pointer.
1010 if (Attrs.empty())
1011 return {};
1013 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
1014 [](const std::pair<unsigned, AttributeSet> &LHS,
1015 const std::pair<unsigned, AttributeSet> &RHS) {
1016 return LHS.first < RHS.first;
1017 }) &&
1018 "Misordered Attributes list!");
1019 assert(llvm::none_of(Attrs,
1020 [](const std::pair<unsigned, AttributeSet> &Pair) {
1021 return !Pair.second.hasAttributes();
1022 }) &&
1023 "Pointless attribute!");
1025 unsigned MaxIndex = Attrs.back().first;
1026 // If the MaxIndex is FunctionIndex and there are other indices in front
1027 // of it, we need to use the largest of those to get the right size.
1028 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1029 MaxIndex = Attrs[Attrs.size() - 2].first;
1031 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1032 for (const auto Pair : Attrs)
1033 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1035 return getImpl(C, AttrVec);
1038 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
1039 AttributeSet RetAttrs,
1040 ArrayRef<AttributeSet> ArgAttrs) {
1041 // Scan from the end to find the last argument with attributes. Most
1042 // arguments don't have attributes, so it's nice if we can have fewer unique
1043 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1044 unsigned NumSets = 0;
1045 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1046 if (ArgAttrs[I - 1].hasAttributes()) {
1047 NumSets = I + 2;
1048 break;
1051 if (NumSets == 0) {
1052 // Check function and return attributes if we didn't have argument
1053 // attributes.
1054 if (RetAttrs.hasAttributes())
1055 NumSets = 2;
1056 else if (FnAttrs.hasAttributes())
1057 NumSets = 1;
1060 // If all attribute sets were empty, we can use the empty attribute list.
1061 if (NumSets == 0)
1062 return {};
1064 SmallVector<AttributeSet, 8> AttrSets;
1065 AttrSets.reserve(NumSets);
1066 // If we have any attributes, we always have function attributes.
1067 AttrSets.push_back(FnAttrs);
1068 if (NumSets > 1)
1069 AttrSets.push_back(RetAttrs);
1070 if (NumSets > 2) {
1071 // Drop the empty argument attribute sets at the end.
1072 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1073 AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
1076 return getImpl(C, AttrSets);
1079 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1080 const AttrBuilder &B) {
1081 if (!B.hasAttributes())
1082 return {};
1083 Index = attrIdxToArrayIdx(Index);
1084 SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1085 AttrSets[Index] = AttributeSet::get(C, B);
1086 return getImpl(C, AttrSets);
1089 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1090 ArrayRef<Attribute::AttrKind> Kinds) {
1091 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1092 for (const auto K : Kinds)
1093 Attrs.emplace_back(Index, Attribute::get(C, K));
1094 return get(C, Attrs);
1097 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1098 ArrayRef<StringRef> Kinds) {
1099 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1100 for (const auto K : Kinds)
1101 Attrs.emplace_back(Index, Attribute::get(C, K));
1102 return get(C, Attrs);
1105 AttributeList AttributeList::get(LLVMContext &C,
1106 ArrayRef<AttributeList> Attrs) {
1107 if (Attrs.empty())
1108 return {};
1109 if (Attrs.size() == 1)
1110 return Attrs[0];
1112 unsigned MaxSize = 0;
1113 for (const auto List : Attrs)
1114 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1116 // If every list was empty, there is no point in merging the lists.
1117 if (MaxSize == 0)
1118 return {};
1120 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1121 for (unsigned I = 0; I < MaxSize; ++I) {
1122 AttrBuilder CurBuilder;
1123 for (const auto List : Attrs)
1124 CurBuilder.merge(List.getAttributes(I - 1));
1125 NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1128 return getImpl(C, NewAttrSets);
1131 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1132 Attribute::AttrKind Kind) const {
1133 if (hasAttribute(Index, Kind)) return *this;
1134 AttrBuilder B;
1135 B.addAttribute(Kind);
1136 return addAttributes(C, Index, B);
1139 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1140 StringRef Kind,
1141 StringRef Value) const {
1142 AttrBuilder B;
1143 B.addAttribute(Kind, Value);
1144 return addAttributes(C, Index, B);
1147 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1148 Attribute A) const {
1149 AttrBuilder B;
1150 B.addAttribute(A);
1151 return addAttributes(C, Index, B);
1154 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
1155 const AttrBuilder &B) const {
1156 if (!B.hasAttributes())
1157 return *this;
1159 if (!pImpl)
1160 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1162 #ifndef NDEBUG
1163 // FIXME it is not obvious how this should work for alignment. For now, say
1164 // we can't change a known alignment.
1165 unsigned OldAlign = getAttributes(Index).getAlignment();
1166 unsigned NewAlign = B.getAlignment();
1167 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1168 "Attempt to change alignment!");
1169 #endif
1171 Index = attrIdxToArrayIdx(Index);
1172 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1173 if (Index >= AttrSets.size())
1174 AttrSets.resize(Index + 1);
1176 AttrBuilder Merged(AttrSets[Index]);
1177 Merged.merge(B);
1178 AttrSets[Index] = AttributeSet::get(C, Merged);
1180 return getImpl(C, AttrSets);
1183 AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1184 ArrayRef<unsigned> ArgNos,
1185 Attribute A) const {
1186 assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
1188 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1189 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1190 if (MaxIndex >= AttrSets.size())
1191 AttrSets.resize(MaxIndex + 1);
1193 for (unsigned ArgNo : ArgNos) {
1194 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1195 AttrBuilder B(AttrSets[Index]);
1196 B.addAttribute(A);
1197 AttrSets[Index] = AttributeSet::get(C, B);
1200 return getImpl(C, AttrSets);
1203 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1204 Attribute::AttrKind Kind) const {
1205 if (!hasAttribute(Index, Kind)) return *this;
1207 Index = attrIdxToArrayIdx(Index);
1208 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1209 assert(Index < AttrSets.size());
1211 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1213 return getImpl(C, AttrSets);
1216 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1217 StringRef Kind) const {
1218 if (!hasAttribute(Index, Kind)) return *this;
1220 Index = attrIdxToArrayIdx(Index);
1221 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1222 assert(Index < AttrSets.size());
1224 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1226 return getImpl(C, AttrSets);
1229 AttributeList
1230 AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
1231 const AttrBuilder &AttrsToRemove) const {
1232 if (!pImpl)
1233 return {};
1235 Index = attrIdxToArrayIdx(Index);
1236 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1237 if (Index >= AttrSets.size())
1238 AttrSets.resize(Index + 1);
1240 AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
1242 return getImpl(C, AttrSets);
1245 AttributeList AttributeList::removeAttributes(LLVMContext &C,
1246 unsigned WithoutIndex) const {
1247 if (!pImpl)
1248 return {};
1249 WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1250 if (WithoutIndex >= getNumAttrSets())
1251 return *this;
1252 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1253 AttrSets[WithoutIndex] = AttributeSet();
1254 return getImpl(C, AttrSets);
1257 AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
1258 unsigned Index,
1259 uint64_t Bytes) const {
1260 AttrBuilder B;
1261 B.addDereferenceableAttr(Bytes);
1262 return addAttributes(C, Index, B);
1265 AttributeList
1266 AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
1267 uint64_t Bytes) const {
1268 AttrBuilder B;
1269 B.addDereferenceableOrNullAttr(Bytes);
1270 return addAttributes(C, Index, B);
1273 AttributeList
1274 AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
1275 unsigned ElemSizeArg,
1276 const Optional<unsigned> &NumElemsArg) {
1277 AttrBuilder B;
1278 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1279 return addAttributes(C, Index, B);
1282 //===----------------------------------------------------------------------===//
1283 // AttributeList Accessor Methods
1284 //===----------------------------------------------------------------------===//
1286 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
1288 AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
1289 return getAttributes(ArgNo + FirstArgIndex);
1292 AttributeSet AttributeList::getRetAttributes() const {
1293 return getAttributes(ReturnIndex);
1296 AttributeSet AttributeList::getFnAttributes() const {
1297 return getAttributes(FunctionIndex);
1300 bool AttributeList::hasAttribute(unsigned Index,
1301 Attribute::AttrKind Kind) const {
1302 return getAttributes(Index).hasAttribute(Kind);
1305 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
1306 return getAttributes(Index).hasAttribute(Kind);
1309 bool AttributeList::hasAttributes(unsigned Index) const {
1310 return getAttributes(Index).hasAttributes();
1313 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
1314 return pImpl && pImpl->hasFnAttribute(Kind);
1317 bool AttributeList::hasFnAttribute(StringRef Kind) const {
1318 return hasAttribute(AttributeList::FunctionIndex, Kind);
1321 bool AttributeList::hasParamAttribute(unsigned ArgNo,
1322 Attribute::AttrKind Kind) const {
1323 return hasAttribute(ArgNo + FirstArgIndex, Kind);
1326 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1327 unsigned *Index) const {
1328 if (!pImpl) return false;
1330 for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
1331 if (hasAttribute(I, Attr)) {
1332 if (Index)
1333 *Index = I;
1334 return true;
1338 return false;
1341 Attribute AttributeList::getAttribute(unsigned Index,
1342 Attribute::AttrKind Kind) const {
1343 return getAttributes(Index).getAttribute(Kind);
1346 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
1347 return getAttributes(Index).getAttribute(Kind);
1350 unsigned AttributeList::getRetAlignment() const {
1351 return getAttributes(ReturnIndex).getAlignment();
1354 unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
1355 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1358 Type *AttributeList::getParamByValType(unsigned Index) const {
1359 return getAttributes(Index+FirstArgIndex).getByValType();
1363 unsigned AttributeList::getStackAlignment(unsigned Index) const {
1364 return getAttributes(Index).getStackAlignment();
1367 uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
1368 return getAttributes(Index).getDereferenceableBytes();
1371 uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
1372 return getAttributes(Index).getDereferenceableOrNullBytes();
1375 std::pair<unsigned, Optional<unsigned>>
1376 AttributeList::getAllocSizeArgs(unsigned Index) const {
1377 return getAttributes(Index).getAllocSizeArgs();
1380 std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1381 return getAttributes(Index).getAsString(InAttrGrp);
1384 AttributeSet AttributeList::getAttributes(unsigned Index) const {
1385 Index = attrIdxToArrayIdx(Index);
1386 if (!pImpl || Index >= getNumAttrSets())
1387 return {};
1388 return pImpl->begin()[Index];
1391 AttributeList::iterator AttributeList::begin() const {
1392 return pImpl ? pImpl->begin() : nullptr;
1395 AttributeList::iterator AttributeList::end() const {
1396 return pImpl ? pImpl->end() : nullptr;
1399 //===----------------------------------------------------------------------===//
1400 // AttributeList Introspection Methods
1401 //===----------------------------------------------------------------------===//
1403 unsigned AttributeList::getNumAttrSets() const {
1404 return pImpl ? pImpl->NumAttrSets : 0;
1407 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1408 LLVM_DUMP_METHOD void AttributeList::dump() const {
1409 dbgs() << "PAL[\n";
1411 for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
1412 if (getAttributes(i).hasAttributes())
1413 dbgs() << " { " << i << " => " << getAsString(i) << " }\n";
1416 dbgs() << "]\n";
1418 #endif
1420 //===----------------------------------------------------------------------===//
1421 // AttrBuilder Method Implementations
1422 //===----------------------------------------------------------------------===//
1424 // FIXME: Remove this ctor, use AttributeSet.
1425 AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
1426 AttributeSet AS = AL.getAttributes(Index);
1427 for (const auto &A : AS)
1428 addAttribute(A);
1431 AttrBuilder::AttrBuilder(AttributeSet AS) {
1432 for (const auto &A : AS)
1433 addAttribute(A);
1436 void AttrBuilder::clear() {
1437 Attrs.reset();
1438 TargetDepAttrs.clear();
1439 Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1440 AllocSizeArgs = 0;
1441 ByValType = nullptr;
1444 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
1445 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1446 assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1447 Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1448 "Adding integer attribute without adding a value!");
1449 Attrs[Val] = true;
1450 return *this;
1453 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1454 if (Attr.isStringAttribute()) {
1455 addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1456 return *this;
1459 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1460 Attrs[Kind] = true;
1462 if (Kind == Attribute::Alignment)
1463 Alignment = Attr.getAlignment();
1464 else if (Kind == Attribute::StackAlignment)
1465 StackAlignment = Attr.getStackAlignment();
1466 else if (Kind == Attribute::ByVal)
1467 ByValType = Attr.getValueAsType();
1468 else if (Kind == Attribute::Dereferenceable)
1469 DerefBytes = Attr.getDereferenceableBytes();
1470 else if (Kind == Attribute::DereferenceableOrNull)
1471 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1472 else if (Kind == Attribute::AllocSize)
1473 AllocSizeArgs = Attr.getValueAsInt();
1474 return *this;
1477 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1478 TargetDepAttrs[A] = V;
1479 return *this;
1482 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1483 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1484 Attrs[Val] = false;
1486 if (Val == Attribute::Alignment)
1487 Alignment = 0;
1488 else if (Val == Attribute::StackAlignment)
1489 StackAlignment = 0;
1490 else if (Val == Attribute::ByVal)
1491 ByValType = nullptr;
1492 else if (Val == Attribute::Dereferenceable)
1493 DerefBytes = 0;
1494 else if (Val == Attribute::DereferenceableOrNull)
1495 DerefOrNullBytes = 0;
1496 else if (Val == Attribute::AllocSize)
1497 AllocSizeArgs = 0;
1499 return *this;
1502 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
1503 remove(A.getAttributes(Index));
1504 return *this;
1507 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1508 auto I = TargetDepAttrs.find(A);
1509 if (I != TargetDepAttrs.end())
1510 TargetDepAttrs.erase(I);
1511 return *this;
1514 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1515 return unpackAllocSizeArgs(AllocSizeArgs);
1518 AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
1519 if (Align == 0) return *this;
1521 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1522 assert(Align <= 0x40000000 && "Alignment too large.");
1524 Attrs[Attribute::Alignment] = true;
1525 Alignment = Align;
1526 return *this;
1529 AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
1530 // Default alignment, allow the target to define how to align it.
1531 if (Align == 0) return *this;
1533 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1534 assert(Align <= 0x100 && "Alignment too large.");
1536 Attrs[Attribute::StackAlignment] = true;
1537 StackAlignment = Align;
1538 return *this;
1541 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1542 if (Bytes == 0) return *this;
1544 Attrs[Attribute::Dereferenceable] = true;
1545 DerefBytes = Bytes;
1546 return *this;
1549 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1550 if (Bytes == 0)
1551 return *this;
1553 Attrs[Attribute::DereferenceableOrNull] = true;
1554 DerefOrNullBytes = Bytes;
1555 return *this;
1558 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1559 const Optional<unsigned> &NumElems) {
1560 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1563 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1564 // (0, 0) is our "not present" value, so we need to check for it here.
1565 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1567 Attrs[Attribute::AllocSize] = true;
1568 // Reuse existing machinery to store this as a single 64-bit integer so we can
1569 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1570 AllocSizeArgs = RawArgs;
1571 return *this;
1574 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1575 Attrs[Attribute::ByVal] = true;
1576 ByValType = Ty;
1577 return *this;
1580 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1581 // FIXME: What if both have alignments, but they don't match?!
1582 if (!Alignment)
1583 Alignment = B.Alignment;
1585 if (!StackAlignment)
1586 StackAlignment = B.StackAlignment;
1588 if (!DerefBytes)
1589 DerefBytes = B.DerefBytes;
1591 if (!DerefOrNullBytes)
1592 DerefOrNullBytes = B.DerefOrNullBytes;
1594 if (!AllocSizeArgs)
1595 AllocSizeArgs = B.AllocSizeArgs;
1597 if (!ByValType)
1598 ByValType = B.ByValType;
1600 Attrs |= B.Attrs;
1602 for (auto I : B.td_attrs())
1603 TargetDepAttrs[I.first] = I.second;
1605 return *this;
1608 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1609 // FIXME: What if both have alignments, but they don't match?!
1610 if (B.Alignment)
1611 Alignment = 0;
1613 if (B.StackAlignment)
1614 StackAlignment = 0;
1616 if (B.DerefBytes)
1617 DerefBytes = 0;
1619 if (B.DerefOrNullBytes)
1620 DerefOrNullBytes = 0;
1622 if (B.AllocSizeArgs)
1623 AllocSizeArgs = 0;
1625 if (B.ByValType)
1626 ByValType = nullptr;
1628 Attrs &= ~B.Attrs;
1630 for (auto I : B.td_attrs())
1631 TargetDepAttrs.erase(I.first);
1633 return *this;
1636 bool AttrBuilder::overlaps(const AttrBuilder &B) const {
1637 // First check if any of the target independent attributes overlap.
1638 if ((Attrs & B.Attrs).any())
1639 return true;
1641 // Then check if any target dependent ones do.
1642 for (const auto &I : td_attrs())
1643 if (B.contains(I.first))
1644 return true;
1646 return false;
1649 bool AttrBuilder::contains(StringRef A) const {
1650 return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1653 bool AttrBuilder::hasAttributes() const {
1654 return !Attrs.none() || !TargetDepAttrs.empty();
1657 bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const {
1658 AttributeSet AS = AL.getAttributes(Index);
1660 for (const auto Attr : AS) {
1661 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1662 if (contains(Attr.getKindAsEnum()))
1663 return true;
1664 } else {
1665 assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1666 return contains(Attr.getKindAsString());
1670 return false;
1673 bool AttrBuilder::hasAlignmentAttr() const {
1674 return Alignment != 0;
1677 bool AttrBuilder::operator==(const AttrBuilder &B) {
1678 if (Attrs != B.Attrs)
1679 return false;
1681 for (td_const_iterator I = TargetDepAttrs.begin(),
1682 E = TargetDepAttrs.end(); I != E; ++I)
1683 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1684 return false;
1686 return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1687 DerefBytes == B.DerefBytes && ByValType == B.ByValType;
1690 //===----------------------------------------------------------------------===//
1691 // AttributeFuncs Function Defintions
1692 //===----------------------------------------------------------------------===//
1694 /// Which attributes cannot be applied to a type.
1695 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
1696 AttrBuilder Incompatible;
1698 if (!Ty->isIntegerTy())
1699 // Attribute that only apply to integers.
1700 Incompatible.addAttribute(Attribute::SExt)
1701 .addAttribute(Attribute::ZExt);
1703 if (!Ty->isPointerTy())
1704 // Attribute that only apply to pointers.
1705 Incompatible.addAttribute(Attribute::ByVal)
1706 .addAttribute(Attribute::Nest)
1707 .addAttribute(Attribute::NoAlias)
1708 .addAttribute(Attribute::NoCapture)
1709 .addAttribute(Attribute::NonNull)
1710 .addDereferenceableAttr(1) // the int here is ignored
1711 .addDereferenceableOrNullAttr(1) // the int here is ignored
1712 .addAttribute(Attribute::ReadNone)
1713 .addAttribute(Attribute::ReadOnly)
1714 .addAttribute(Attribute::StructRet)
1715 .addAttribute(Attribute::InAlloca);
1717 return Incompatible;
1720 template<typename AttrClass>
1721 static bool isEqual(const Function &Caller, const Function &Callee) {
1722 return Caller.getFnAttribute(AttrClass::getKind()) ==
1723 Callee.getFnAttribute(AttrClass::getKind());
1726 /// Compute the logical AND of the attributes of the caller and the
1727 /// callee.
1729 /// This function sets the caller's attribute to false if the callee's attribute
1730 /// is false.
1731 template<typename AttrClass>
1732 static void setAND(Function &Caller, const Function &Callee) {
1733 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1734 !AttrClass::isSet(Callee, AttrClass::getKind()))
1735 AttrClass::set(Caller, AttrClass::getKind(), false);
1738 /// Compute the logical OR of the attributes of the caller and the
1739 /// callee.
1741 /// This function sets the caller's attribute to true if the callee's attribute
1742 /// is true.
1743 template<typename AttrClass>
1744 static void setOR(Function &Caller, const Function &Callee) {
1745 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1746 AttrClass::isSet(Callee, AttrClass::getKind()))
1747 AttrClass::set(Caller, AttrClass::getKind(), true);
1750 /// If the inlined function had a higher stack protection level than the
1751 /// calling function, then bump up the caller's stack protection level.
1752 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1753 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1754 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1755 // clutter to the IR.
1756 AttrBuilder OldSSPAttr;
1757 OldSSPAttr.addAttribute(Attribute::StackProtect)
1758 .addAttribute(Attribute::StackProtectStrong)
1759 .addAttribute(Attribute::StackProtectReq);
1761 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1762 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1763 Caller.addFnAttr(Attribute::StackProtectReq);
1764 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1765 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1766 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1767 Caller.addFnAttr(Attribute::StackProtectStrong);
1768 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1769 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1770 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1771 Caller.addFnAttr(Attribute::StackProtect);
1774 /// If the inlined function required stack probes, then ensure that
1775 /// the calling function has those too.
1776 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
1777 if (!Caller.hasFnAttribute("probe-stack") &&
1778 Callee.hasFnAttribute("probe-stack")) {
1779 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
1783 /// If the inlined function defines the size of guard region
1784 /// on the stack, then ensure that the calling function defines a guard region
1785 /// that is no larger.
1786 static void
1787 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
1788 if (Callee.hasFnAttribute("stack-probe-size")) {
1789 uint64_t CalleeStackProbeSize;
1790 Callee.getFnAttribute("stack-probe-size")
1791 .getValueAsString()
1792 .getAsInteger(0, CalleeStackProbeSize);
1793 if (Caller.hasFnAttribute("stack-probe-size")) {
1794 uint64_t CallerStackProbeSize;
1795 Caller.getFnAttribute("stack-probe-size")
1796 .getValueAsString()
1797 .getAsInteger(0, CallerStackProbeSize);
1798 if (CallerStackProbeSize > CalleeStackProbeSize) {
1799 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1801 } else {
1802 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1807 /// If the inlined function defines a min legal vector width, then ensure
1808 /// the calling function has the same or larger min legal vector width. If the
1809 /// caller has the attribute, but the callee doesn't, we need to remove the
1810 /// attribute from the caller since we can't make any guarantees about the
1811 /// caller's requirements.
1812 /// This function is called after the inlining decision has been made so we have
1813 /// to merge the attribute this way. Heuristics that would use
1814 /// min-legal-vector-width to determine inline compatibility would need to be
1815 /// handled as part of inline cost analysis.
1816 static void
1817 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
1818 if (Caller.hasFnAttribute("min-legal-vector-width")) {
1819 if (Callee.hasFnAttribute("min-legal-vector-width")) {
1820 uint64_t CallerVectorWidth;
1821 Caller.getFnAttribute("min-legal-vector-width")
1822 .getValueAsString()
1823 .getAsInteger(0, CallerVectorWidth);
1824 uint64_t CalleeVectorWidth;
1825 Callee.getFnAttribute("min-legal-vector-width")
1826 .getValueAsString()
1827 .getAsInteger(0, CalleeVectorWidth);
1828 if (CallerVectorWidth < CalleeVectorWidth)
1829 Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
1830 } else {
1831 // If the callee doesn't have the attribute then we don't know anything
1832 // and must drop the attribute from the caller.
1833 Caller.removeFnAttr("min-legal-vector-width");
1838 /// If the inlined function has "null-pointer-is-valid=true" attribute,
1839 /// set this attribute in the caller post inlining.
1840 static void
1841 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
1842 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
1843 Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid"));
1847 #define GET_ATTR_COMPAT_FUNC
1848 #include "AttributesCompatFunc.inc"
1850 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1851 const Function &Callee) {
1852 return hasCompatibleFnAttrs(Caller, Callee);
1855 void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
1856 const Function &Callee) {
1857 mergeFnAttrs(Caller, Callee);