[InstCombine] Signed saturation tests. NFC
[llvm-complete.git] / lib / IR / Attributes.cpp
blobcc370e628e9a97068491ab327c3e441df3f5fa5f
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, Align A) {
146 assert(A <= 0x40000000 && "Alignment too large.");
147 return get(Context, Alignment, A.value());
150 Attribute Attribute::getWithStackAlignment(LLVMContext &Context, Align A) {
151 assert(A <= 0x100 && "Alignment too large.");
152 return get(Context, StackAlignment, A.value());
155 Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
156 uint64_t Bytes) {
157 assert(Bytes && "Bytes must be non-zero.");
158 return get(Context, Dereferenceable, Bytes);
161 Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
162 uint64_t Bytes) {
163 assert(Bytes && "Bytes must be non-zero.");
164 return get(Context, DereferenceableOrNull, Bytes);
167 Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
168 return get(Context, ByVal, Ty);
171 Attribute
172 Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
173 const Optional<unsigned> &NumElemsArg) {
174 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
175 "Invalid allocsize arguments -- given allocsize(0, 0)");
176 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
179 //===----------------------------------------------------------------------===//
180 // Attribute Accessor Methods
181 //===----------------------------------------------------------------------===//
183 bool Attribute::isEnumAttribute() const {
184 return pImpl && pImpl->isEnumAttribute();
187 bool Attribute::isIntAttribute() const {
188 return pImpl && pImpl->isIntAttribute();
191 bool Attribute::isStringAttribute() const {
192 return pImpl && pImpl->isStringAttribute();
195 bool Attribute::isTypeAttribute() const {
196 return pImpl && pImpl->isTypeAttribute();
199 Attribute::AttrKind Attribute::getKindAsEnum() const {
200 if (!pImpl) return None;
201 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
202 "Invalid attribute type to get the kind as an enum!");
203 return pImpl->getKindAsEnum();
206 uint64_t Attribute::getValueAsInt() const {
207 if (!pImpl) return 0;
208 assert(isIntAttribute() &&
209 "Expected the attribute to be an integer attribute!");
210 return pImpl->getValueAsInt();
213 StringRef Attribute::getKindAsString() const {
214 if (!pImpl) return {};
215 assert(isStringAttribute() &&
216 "Invalid attribute type to get the kind as a string!");
217 return pImpl->getKindAsString();
220 StringRef Attribute::getValueAsString() const {
221 if (!pImpl) return {};
222 assert(isStringAttribute() &&
223 "Invalid attribute type to get the value as a string!");
224 return pImpl->getValueAsString();
227 Type *Attribute::getValueAsType() const {
228 if (!pImpl) return {};
229 assert(isTypeAttribute() &&
230 "Invalid attribute type to get the value as a type!");
231 return pImpl->getValueAsType();
235 bool Attribute::hasAttribute(AttrKind Kind) const {
236 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
239 bool Attribute::hasAttribute(StringRef Kind) const {
240 if (!isStringAttribute()) return false;
241 return pImpl && pImpl->hasAttribute(Kind);
244 MaybeAlign Attribute::getAlignment() const {
245 assert(hasAttribute(Attribute::Alignment) &&
246 "Trying to get alignment from non-alignment attribute!");
247 return MaybeAlign(pImpl->getValueAsInt());
250 MaybeAlign Attribute::getStackAlignment() const {
251 assert(hasAttribute(Attribute::StackAlignment) &&
252 "Trying to get alignment from non-alignment attribute!");
253 return MaybeAlign(pImpl->getValueAsInt());
256 uint64_t Attribute::getDereferenceableBytes() const {
257 assert(hasAttribute(Attribute::Dereferenceable) &&
258 "Trying to get dereferenceable bytes from "
259 "non-dereferenceable attribute!");
260 return pImpl->getValueAsInt();
263 uint64_t Attribute::getDereferenceableOrNullBytes() const {
264 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
265 "Trying to get dereferenceable bytes from "
266 "non-dereferenceable attribute!");
267 return pImpl->getValueAsInt();
270 std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
271 assert(hasAttribute(Attribute::AllocSize) &&
272 "Trying to get allocsize args from non-allocsize attribute");
273 return unpackAllocSizeArgs(pImpl->getValueAsInt());
276 std::string Attribute::getAsString(bool InAttrGrp) const {
277 if (!pImpl) return {};
279 if (hasAttribute(Attribute::SanitizeAddress))
280 return "sanitize_address";
281 if (hasAttribute(Attribute::SanitizeHWAddress))
282 return "sanitize_hwaddress";
283 if (hasAttribute(Attribute::SanitizeMemTag))
284 return "sanitize_memtag";
285 if (hasAttribute(Attribute::AlwaysInline))
286 return "alwaysinline";
287 if (hasAttribute(Attribute::ArgMemOnly))
288 return "argmemonly";
289 if (hasAttribute(Attribute::Builtin))
290 return "builtin";
291 if (hasAttribute(Attribute::Convergent))
292 return "convergent";
293 if (hasAttribute(Attribute::SwiftError))
294 return "swifterror";
295 if (hasAttribute(Attribute::SwiftSelf))
296 return "swiftself";
297 if (hasAttribute(Attribute::InaccessibleMemOnly))
298 return "inaccessiblememonly";
299 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
300 return "inaccessiblemem_or_argmemonly";
301 if (hasAttribute(Attribute::InAlloca))
302 return "inalloca";
303 if (hasAttribute(Attribute::InlineHint))
304 return "inlinehint";
305 if (hasAttribute(Attribute::InReg))
306 return "inreg";
307 if (hasAttribute(Attribute::JumpTable))
308 return "jumptable";
309 if (hasAttribute(Attribute::MinSize))
310 return "minsize";
311 if (hasAttribute(Attribute::Naked))
312 return "naked";
313 if (hasAttribute(Attribute::Nest))
314 return "nest";
315 if (hasAttribute(Attribute::NoAlias))
316 return "noalias";
317 if (hasAttribute(Attribute::NoBuiltin))
318 return "nobuiltin";
319 if (hasAttribute(Attribute::NoCapture))
320 return "nocapture";
321 if (hasAttribute(Attribute::NoDuplicate))
322 return "noduplicate";
323 if (hasAttribute(Attribute::NoFree))
324 return "nofree";
325 if (hasAttribute(Attribute::NoImplicitFloat))
326 return "noimplicitfloat";
327 if (hasAttribute(Attribute::NoInline))
328 return "noinline";
329 if (hasAttribute(Attribute::NonLazyBind))
330 return "nonlazybind";
331 if (hasAttribute(Attribute::NonNull))
332 return "nonnull";
333 if (hasAttribute(Attribute::NoRedZone))
334 return "noredzone";
335 if (hasAttribute(Attribute::NoReturn))
336 return "noreturn";
337 if (hasAttribute(Attribute::NoSync))
338 return "nosync";
339 if (hasAttribute(Attribute::WillReturn))
340 return "willreturn";
341 if (hasAttribute(Attribute::NoCfCheck))
342 return "nocf_check";
343 if (hasAttribute(Attribute::NoRecurse))
344 return "norecurse";
345 if (hasAttribute(Attribute::NoUnwind))
346 return "nounwind";
347 if (hasAttribute(Attribute::OptForFuzzing))
348 return "optforfuzzing";
349 if (hasAttribute(Attribute::OptimizeNone))
350 return "optnone";
351 if (hasAttribute(Attribute::OptimizeForSize))
352 return "optsize";
353 if (hasAttribute(Attribute::ReadNone))
354 return "readnone";
355 if (hasAttribute(Attribute::ReadOnly))
356 return "readonly";
357 if (hasAttribute(Attribute::WriteOnly))
358 return "writeonly";
359 if (hasAttribute(Attribute::Returned))
360 return "returned";
361 if (hasAttribute(Attribute::ReturnsTwice))
362 return "returns_twice";
363 if (hasAttribute(Attribute::SExt))
364 return "signext";
365 if (hasAttribute(Attribute::SpeculativeLoadHardening))
366 return "speculative_load_hardening";
367 if (hasAttribute(Attribute::Speculatable))
368 return "speculatable";
369 if (hasAttribute(Attribute::StackProtect))
370 return "ssp";
371 if (hasAttribute(Attribute::StackProtectReq))
372 return "sspreq";
373 if (hasAttribute(Attribute::StackProtectStrong))
374 return "sspstrong";
375 if (hasAttribute(Attribute::SafeStack))
376 return "safestack";
377 if (hasAttribute(Attribute::ShadowCallStack))
378 return "shadowcallstack";
379 if (hasAttribute(Attribute::StrictFP))
380 return "strictfp";
381 if (hasAttribute(Attribute::StructRet))
382 return "sret";
383 if (hasAttribute(Attribute::SanitizeThread))
384 return "sanitize_thread";
385 if (hasAttribute(Attribute::SanitizeMemory))
386 return "sanitize_memory";
387 if (hasAttribute(Attribute::UWTable))
388 return "uwtable";
389 if (hasAttribute(Attribute::ZExt))
390 return "zeroext";
391 if (hasAttribute(Attribute::Cold))
392 return "cold";
393 if (hasAttribute(Attribute::ImmArg))
394 return "immarg";
396 if (hasAttribute(Attribute::ByVal)) {
397 std::string Result;
398 Result += "byval";
399 if (Type *Ty = getValueAsType()) {
400 raw_string_ostream OS(Result);
401 Result += '(';
402 Ty->print(OS, false, true);
403 OS.flush();
404 Result += ')';
406 return Result;
409 // FIXME: These should be output like this:
411 // align=4
412 // alignstack=8
414 if (hasAttribute(Attribute::Alignment)) {
415 std::string Result;
416 Result += "align";
417 Result += (InAttrGrp) ? "=" : " ";
418 Result += utostr(getValueAsInt());
419 return Result;
422 auto AttrWithBytesToString = [&](const char *Name) {
423 std::string Result;
424 Result += Name;
425 if (InAttrGrp) {
426 Result += "=";
427 Result += utostr(getValueAsInt());
428 } else {
429 Result += "(";
430 Result += utostr(getValueAsInt());
431 Result += ")";
433 return Result;
436 if (hasAttribute(Attribute::StackAlignment))
437 return AttrWithBytesToString("alignstack");
439 if (hasAttribute(Attribute::Dereferenceable))
440 return AttrWithBytesToString("dereferenceable");
442 if (hasAttribute(Attribute::DereferenceableOrNull))
443 return AttrWithBytesToString("dereferenceable_or_null");
445 if (hasAttribute(Attribute::AllocSize)) {
446 unsigned ElemSize;
447 Optional<unsigned> NumElems;
448 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
450 std::string Result = "allocsize(";
451 Result += utostr(ElemSize);
452 if (NumElems.hasValue()) {
453 Result += ',';
454 Result += utostr(*NumElems);
456 Result += ')';
457 return Result;
460 // Convert target-dependent attributes to strings of the form:
462 // "kind"
463 // "kind" = "value"
465 if (isStringAttribute()) {
466 std::string Result;
467 Result += (Twine('"') + getKindAsString() + Twine('"')).str();
469 std::string AttrVal = pImpl->getValueAsString();
470 if (AttrVal.empty()) return Result;
472 // Since some attribute strings contain special characters that cannot be
473 // printable, those have to be escaped to make the attribute value printable
474 // as is. e.g. "\01__gnu_mcount_nc"
476 raw_string_ostream OS(Result);
477 OS << "=\"";
478 printEscapedString(AttrVal, OS);
479 OS << "\"";
481 return Result;
484 llvm_unreachable("Unknown attribute");
487 bool Attribute::operator<(Attribute A) const {
488 if (!pImpl && !A.pImpl) return false;
489 if (!pImpl) return true;
490 if (!A.pImpl) return false;
491 return *pImpl < *A.pImpl;
494 //===----------------------------------------------------------------------===//
495 // AttributeImpl Definition
496 //===----------------------------------------------------------------------===//
498 // Pin the vtables to this file.
499 AttributeImpl::~AttributeImpl() = default;
501 void EnumAttributeImpl::anchor() {}
503 void IntAttributeImpl::anchor() {}
505 void StringAttributeImpl::anchor() {}
507 void TypeAttributeImpl::anchor() {}
509 bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
510 if (isStringAttribute()) return false;
511 return getKindAsEnum() == A;
514 bool AttributeImpl::hasAttribute(StringRef Kind) const {
515 if (!isStringAttribute()) return false;
516 return getKindAsString() == Kind;
519 Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
520 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
521 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
524 uint64_t AttributeImpl::getValueAsInt() const {
525 assert(isIntAttribute());
526 return static_cast<const IntAttributeImpl *>(this)->getValue();
529 StringRef AttributeImpl::getKindAsString() const {
530 assert(isStringAttribute());
531 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
534 StringRef AttributeImpl::getValueAsString() const {
535 assert(isStringAttribute());
536 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
539 Type *AttributeImpl::getValueAsType() const {
540 assert(isTypeAttribute());
541 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
544 bool AttributeImpl::operator<(const AttributeImpl &AI) const {
545 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
546 // relative to their enum value) and then strings.
547 if (isEnumAttribute()) {
548 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
549 if (AI.isIntAttribute()) return true;
550 if (AI.isStringAttribute()) return true;
551 if (AI.isTypeAttribute()) return true;
554 if (isTypeAttribute()) {
555 if (AI.isEnumAttribute()) return false;
556 if (AI.isTypeAttribute()) {
557 assert(getKindAsEnum() != AI.getKindAsEnum() &&
558 "Comparison of types would be unstable");
559 return getKindAsEnum() < AI.getKindAsEnum();
561 if (AI.isIntAttribute()) return true;
562 if (AI.isStringAttribute()) return true;
565 if (isIntAttribute()) {
566 if (AI.isEnumAttribute()) return false;
567 if (AI.isTypeAttribute()) return false;
568 if (AI.isIntAttribute()) {
569 if (getKindAsEnum() == AI.getKindAsEnum())
570 return getValueAsInt() < AI.getValueAsInt();
571 return getKindAsEnum() < AI.getKindAsEnum();
573 if (AI.isStringAttribute()) return true;
576 assert(isStringAttribute());
577 if (AI.isEnumAttribute()) return false;
578 if (AI.isTypeAttribute()) return false;
579 if (AI.isIntAttribute()) return false;
580 if (getKindAsString() == AI.getKindAsString())
581 return getValueAsString() < AI.getValueAsString();
582 return getKindAsString() < AI.getKindAsString();
585 //===----------------------------------------------------------------------===//
586 // AttributeSet Definition
587 //===----------------------------------------------------------------------===//
589 AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
590 return AttributeSet(AttributeSetNode::get(C, B));
593 AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
594 return AttributeSet(AttributeSetNode::get(C, Attrs));
597 AttributeSet AttributeSet::addAttribute(LLVMContext &C,
598 Attribute::AttrKind Kind) const {
599 if (hasAttribute(Kind)) return *this;
600 AttrBuilder B;
601 B.addAttribute(Kind);
602 return addAttributes(C, AttributeSet::get(C, B));
605 AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
606 StringRef Value) const {
607 AttrBuilder B;
608 B.addAttribute(Kind, Value);
609 return addAttributes(C, AttributeSet::get(C, B));
612 AttributeSet AttributeSet::addAttributes(LLVMContext &C,
613 const AttributeSet AS) const {
614 if (!hasAttributes())
615 return AS;
617 if (!AS.hasAttributes())
618 return *this;
620 AttrBuilder B(AS);
621 for (const auto I : *this)
622 B.addAttribute(I);
624 return get(C, B);
627 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
628 Attribute::AttrKind Kind) const {
629 if (!hasAttribute(Kind)) return *this;
630 AttrBuilder B(*this);
631 B.removeAttribute(Kind);
632 return get(C, B);
635 AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
636 StringRef Kind) const {
637 if (!hasAttribute(Kind)) return *this;
638 AttrBuilder B(*this);
639 B.removeAttribute(Kind);
640 return get(C, B);
643 AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
644 const AttrBuilder &Attrs) const {
645 AttrBuilder B(*this);
646 B.remove(Attrs);
647 return get(C, B);
650 unsigned AttributeSet::getNumAttributes() const {
651 return SetNode ? SetNode->getNumAttributes() : 0;
654 bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
655 return SetNode ? SetNode->hasAttribute(Kind) : false;
658 bool AttributeSet::hasAttribute(StringRef Kind) const {
659 return SetNode ? SetNode->hasAttribute(Kind) : false;
662 Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
663 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
666 Attribute AttributeSet::getAttribute(StringRef Kind) const {
667 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
670 MaybeAlign AttributeSet::getAlignment() const {
671 return SetNode ? SetNode->getAlignment() : None;
674 MaybeAlign AttributeSet::getStackAlignment() const {
675 return SetNode ? SetNode->getStackAlignment() : None;
678 uint64_t AttributeSet::getDereferenceableBytes() const {
679 return SetNode ? SetNode->getDereferenceableBytes() : 0;
682 uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
683 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
686 Type *AttributeSet::getByValType() const {
687 return SetNode ? SetNode->getByValType() : nullptr;
690 std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
691 return SetNode ? SetNode->getAllocSizeArgs()
692 : std::pair<unsigned, Optional<unsigned>>(0, 0);
695 std::string AttributeSet::getAsString(bool InAttrGrp) const {
696 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
699 AttributeSet::iterator AttributeSet::begin() const {
700 return SetNode ? SetNode->begin() : nullptr;
703 AttributeSet::iterator AttributeSet::end() const {
704 return SetNode ? SetNode->end() : nullptr;
707 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
708 LLVM_DUMP_METHOD void AttributeSet::dump() const {
709 dbgs() << "AS =\n";
710 dbgs() << " { ";
711 dbgs() << getAsString(true) << " }\n";
713 #endif
715 //===----------------------------------------------------------------------===//
716 // AttributeSetNode Definition
717 //===----------------------------------------------------------------------===//
719 AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
720 : NumAttrs(Attrs.size()) {
721 // There's memory after the node where we can store the entries in.
722 llvm::copy(Attrs, getTrailingObjects<Attribute>());
724 static_assert(Attribute::EndAttrKinds <=
725 sizeof(AvailableAttrs) * CHAR_BIT,
726 "Too many attributes");
728 for (const auto I : *this) {
729 if (!I.isStringAttribute()) {
730 Attribute::AttrKind Kind = I.getKindAsEnum();
731 AvailableAttrs[Kind / 8] |= 1ULL << (Kind % 8);
736 AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
737 ArrayRef<Attribute> Attrs) {
738 if (Attrs.empty())
739 return nullptr;
741 // Otherwise, build a key to look up the existing attributes.
742 LLVMContextImpl *pImpl = C.pImpl;
743 FoldingSetNodeID ID;
745 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
746 llvm::sort(SortedAttrs);
748 for (const auto Attr : SortedAttrs)
749 Attr.Profile(ID);
751 void *InsertPoint;
752 AttributeSetNode *PA =
753 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
755 // If we didn't find any existing attributes of the same shape then create a
756 // new one and insert it.
757 if (!PA) {
758 // Coallocate entries after the AttributeSetNode itself.
759 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
760 PA = new (Mem) AttributeSetNode(SortedAttrs);
761 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
764 // Return the AttributeSetNode that we found or created.
765 return PA;
768 AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
769 // Add target-independent attributes.
770 SmallVector<Attribute, 8> Attrs;
771 for (Attribute::AttrKind Kind = Attribute::None;
772 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
773 if (!B.contains(Kind))
774 continue;
776 Attribute Attr;
777 switch (Kind) {
778 case Attribute::ByVal:
779 Attr = Attribute::getWithByValType(C, B.getByValType());
780 break;
781 case Attribute::Alignment:
782 assert(B.getAlignment() && "Alignment must be set");
783 Attr = Attribute::getWithAlignment(C, *B.getAlignment());
784 break;
785 case Attribute::StackAlignment:
786 assert(B.getStackAlignment() && "StackAlignment must be set");
787 Attr = Attribute::getWithStackAlignment(C, *B.getStackAlignment());
788 break;
789 case Attribute::Dereferenceable:
790 Attr = Attribute::getWithDereferenceableBytes(
791 C, B.getDereferenceableBytes());
792 break;
793 case Attribute::DereferenceableOrNull:
794 Attr = Attribute::getWithDereferenceableOrNullBytes(
795 C, B.getDereferenceableOrNullBytes());
796 break;
797 case Attribute::AllocSize: {
798 auto A = B.getAllocSizeArgs();
799 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
800 break;
802 default:
803 Attr = Attribute::get(C, Kind);
805 Attrs.push_back(Attr);
808 // Add target-dependent (string) attributes.
809 for (const auto &TDA : B.td_attrs())
810 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
812 return get(C, Attrs);
815 bool AttributeSetNode::hasAttribute(StringRef Kind) const {
816 for (const auto I : *this)
817 if (I.hasAttribute(Kind))
818 return true;
819 return false;
822 Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
823 if (hasAttribute(Kind)) {
824 for (const auto I : *this)
825 if (I.hasAttribute(Kind))
826 return I;
828 return {};
831 Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
832 for (const auto I : *this)
833 if (I.hasAttribute(Kind))
834 return I;
835 return {};
838 MaybeAlign AttributeSetNode::getAlignment() const {
839 for (const auto I : *this)
840 if (I.hasAttribute(Attribute::Alignment))
841 return I.getAlignment();
842 return None;
845 MaybeAlign AttributeSetNode::getStackAlignment() const {
846 for (const auto I : *this)
847 if (I.hasAttribute(Attribute::StackAlignment))
848 return I.getStackAlignment();
849 return None;
852 Type *AttributeSetNode::getByValType() const {
853 for (const auto I : *this)
854 if (I.hasAttribute(Attribute::ByVal))
855 return I.getValueAsType();
856 return 0;
859 uint64_t AttributeSetNode::getDereferenceableBytes() const {
860 for (const auto I : *this)
861 if (I.hasAttribute(Attribute::Dereferenceable))
862 return I.getDereferenceableBytes();
863 return 0;
866 uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
867 for (const auto I : *this)
868 if (I.hasAttribute(Attribute::DereferenceableOrNull))
869 return I.getDereferenceableOrNullBytes();
870 return 0;
873 std::pair<unsigned, Optional<unsigned>>
874 AttributeSetNode::getAllocSizeArgs() const {
875 for (const auto I : *this)
876 if (I.hasAttribute(Attribute::AllocSize))
877 return I.getAllocSizeArgs();
878 return std::make_pair(0, 0);
881 std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
882 std::string Str;
883 for (iterator I = begin(), E = end(); I != E; ++I) {
884 if (I != begin())
885 Str += ' ';
886 Str += I->getAsString(InAttrGrp);
888 return Str;
891 //===----------------------------------------------------------------------===//
892 // AttributeListImpl Definition
893 //===----------------------------------------------------------------------===//
895 /// Map from AttributeList index to the internal array index. Adding one happens
896 /// to work, but it relies on unsigned integer wrapping. MSVC warns about
897 /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
898 /// folds it to add anyway.
899 static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
900 return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
903 AttributeListImpl::AttributeListImpl(LLVMContext &C,
904 ArrayRef<AttributeSet> Sets)
905 : Context(C), NumAttrSets(Sets.size()) {
906 assert(!Sets.empty() && "pointless AttributeListImpl");
908 // There's memory after the node where we can store the entries in.
909 llvm::copy(Sets, getTrailingObjects<AttributeSet>());
911 // Initialize AvailableFunctionAttrs summary bitset.
912 static_assert(Attribute::EndAttrKinds <=
913 sizeof(AvailableFunctionAttrs) * CHAR_BIT,
914 "Too many attributes");
915 static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
916 "function should be stored in slot 0");
917 for (const auto I : Sets[0]) {
918 if (!I.isStringAttribute()) {
919 Attribute::AttrKind Kind = I.getKindAsEnum();
920 AvailableFunctionAttrs[Kind / 8] |= 1ULL << (Kind % 8);
925 void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
926 Profile(ID, makeArrayRef(begin(), end()));
929 void AttributeListImpl::Profile(FoldingSetNodeID &ID,
930 ArrayRef<AttributeSet> Sets) {
931 for (const auto &Set : Sets)
932 ID.AddPointer(Set.SetNode);
935 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
936 LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
937 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
939 #endif
941 //===----------------------------------------------------------------------===//
942 // AttributeList Construction and Mutation Methods
943 //===----------------------------------------------------------------------===//
945 AttributeList AttributeList::getImpl(LLVMContext &C,
946 ArrayRef<AttributeSet> AttrSets) {
947 assert(!AttrSets.empty() && "pointless AttributeListImpl");
949 LLVMContextImpl *pImpl = C.pImpl;
950 FoldingSetNodeID ID;
951 AttributeListImpl::Profile(ID, AttrSets);
953 void *InsertPoint;
954 AttributeListImpl *PA =
955 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
957 // If we didn't find any existing attributes of the same shape then
958 // create a new one and insert it.
959 if (!PA) {
960 // Coallocate entries after the AttributeListImpl itself.
961 void *Mem = ::operator new(
962 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
963 PA = new (Mem) AttributeListImpl(C, AttrSets);
964 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
967 // Return the AttributesList that we found or created.
968 return AttributeList(PA);
971 AttributeList
972 AttributeList::get(LLVMContext &C,
973 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
974 // If there are no attributes then return a null AttributesList pointer.
975 if (Attrs.empty())
976 return {};
978 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
979 [](const std::pair<unsigned, Attribute> &LHS,
980 const std::pair<unsigned, Attribute> &RHS) {
981 return LHS.first < RHS.first;
982 }) && "Misordered Attributes list!");
983 assert(llvm::none_of(Attrs,
984 [](const std::pair<unsigned, Attribute> &Pair) {
985 return Pair.second.hasAttribute(Attribute::None);
986 }) &&
987 "Pointless attribute!");
989 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
990 // list.
991 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
992 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
993 E = Attrs.end(); I != E; ) {
994 unsigned Index = I->first;
995 SmallVector<Attribute, 4> AttrVec;
996 while (I != E && I->first == Index) {
997 AttrVec.push_back(I->second);
998 ++I;
1001 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1004 return get(C, AttrPairVec);
1007 AttributeList
1008 AttributeList::get(LLVMContext &C,
1009 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1010 // If there are no attributes then return a null AttributesList pointer.
1011 if (Attrs.empty())
1012 return {};
1014 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
1015 [](const std::pair<unsigned, AttributeSet> &LHS,
1016 const std::pair<unsigned, AttributeSet> &RHS) {
1017 return LHS.first < RHS.first;
1018 }) &&
1019 "Misordered Attributes list!");
1020 assert(llvm::none_of(Attrs,
1021 [](const std::pair<unsigned, AttributeSet> &Pair) {
1022 return !Pair.second.hasAttributes();
1023 }) &&
1024 "Pointless attribute!");
1026 unsigned MaxIndex = Attrs.back().first;
1027 // If the MaxIndex is FunctionIndex and there are other indices in front
1028 // of it, we need to use the largest of those to get the right size.
1029 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1030 MaxIndex = Attrs[Attrs.size() - 2].first;
1032 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1033 for (const auto Pair : Attrs)
1034 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1036 return getImpl(C, AttrVec);
1039 AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
1040 AttributeSet RetAttrs,
1041 ArrayRef<AttributeSet> ArgAttrs) {
1042 // Scan from the end to find the last argument with attributes. Most
1043 // arguments don't have attributes, so it's nice if we can have fewer unique
1044 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1045 unsigned NumSets = 0;
1046 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1047 if (ArgAttrs[I - 1].hasAttributes()) {
1048 NumSets = I + 2;
1049 break;
1052 if (NumSets == 0) {
1053 // Check function and return attributes if we didn't have argument
1054 // attributes.
1055 if (RetAttrs.hasAttributes())
1056 NumSets = 2;
1057 else if (FnAttrs.hasAttributes())
1058 NumSets = 1;
1061 // If all attribute sets were empty, we can use the empty attribute list.
1062 if (NumSets == 0)
1063 return {};
1065 SmallVector<AttributeSet, 8> AttrSets;
1066 AttrSets.reserve(NumSets);
1067 // If we have any attributes, we always have function attributes.
1068 AttrSets.push_back(FnAttrs);
1069 if (NumSets > 1)
1070 AttrSets.push_back(RetAttrs);
1071 if (NumSets > 2) {
1072 // Drop the empty argument attribute sets at the end.
1073 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1074 AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
1077 return getImpl(C, AttrSets);
1080 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1081 const AttrBuilder &B) {
1082 if (!B.hasAttributes())
1083 return {};
1084 Index = attrIdxToArrayIdx(Index);
1085 SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1086 AttrSets[Index] = AttributeSet::get(C, B);
1087 return getImpl(C, AttrSets);
1090 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1091 ArrayRef<Attribute::AttrKind> Kinds) {
1092 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1093 for (const auto K : Kinds)
1094 Attrs.emplace_back(Index, Attribute::get(C, K));
1095 return get(C, Attrs);
1098 AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1099 ArrayRef<StringRef> Kinds) {
1100 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1101 for (const auto K : Kinds)
1102 Attrs.emplace_back(Index, Attribute::get(C, K));
1103 return get(C, Attrs);
1106 AttributeList AttributeList::get(LLVMContext &C,
1107 ArrayRef<AttributeList> Attrs) {
1108 if (Attrs.empty())
1109 return {};
1110 if (Attrs.size() == 1)
1111 return Attrs[0];
1113 unsigned MaxSize = 0;
1114 for (const auto List : Attrs)
1115 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1117 // If every list was empty, there is no point in merging the lists.
1118 if (MaxSize == 0)
1119 return {};
1121 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1122 for (unsigned I = 0; I < MaxSize; ++I) {
1123 AttrBuilder CurBuilder;
1124 for (const auto List : Attrs)
1125 CurBuilder.merge(List.getAttributes(I - 1));
1126 NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1129 return getImpl(C, NewAttrSets);
1132 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1133 Attribute::AttrKind Kind) const {
1134 if (hasAttribute(Index, Kind)) return *this;
1135 AttrBuilder B;
1136 B.addAttribute(Kind);
1137 return addAttributes(C, Index, B);
1140 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1141 StringRef Kind,
1142 StringRef Value) const {
1143 AttrBuilder B;
1144 B.addAttribute(Kind, Value);
1145 return addAttributes(C, Index, B);
1148 AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1149 Attribute A) const {
1150 AttrBuilder B;
1151 B.addAttribute(A);
1152 return addAttributes(C, Index, B);
1155 AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
1156 const AttrBuilder &B) const {
1157 if (!B.hasAttributes())
1158 return *this;
1160 if (!pImpl)
1161 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1163 #ifndef NDEBUG
1164 // FIXME it is not obvious how this should work for alignment. For now, say
1165 // we can't change a known alignment.
1166 const MaybeAlign OldAlign = getAttributes(Index).getAlignment();
1167 const MaybeAlign NewAlign = B.getAlignment();
1168 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1169 "Attempt to change alignment!");
1170 #endif
1172 Index = attrIdxToArrayIdx(Index);
1173 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1174 if (Index >= AttrSets.size())
1175 AttrSets.resize(Index + 1);
1177 AttrBuilder Merged(AttrSets[Index]);
1178 Merged.merge(B);
1179 AttrSets[Index] = AttributeSet::get(C, Merged);
1181 return getImpl(C, AttrSets);
1184 AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1185 ArrayRef<unsigned> ArgNos,
1186 Attribute A) const {
1187 assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
1189 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1190 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1191 if (MaxIndex >= AttrSets.size())
1192 AttrSets.resize(MaxIndex + 1);
1194 for (unsigned ArgNo : ArgNos) {
1195 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1196 AttrBuilder B(AttrSets[Index]);
1197 B.addAttribute(A);
1198 AttrSets[Index] = AttributeSet::get(C, B);
1201 return getImpl(C, AttrSets);
1204 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1205 Attribute::AttrKind Kind) const {
1206 if (!hasAttribute(Index, Kind)) return *this;
1208 Index = attrIdxToArrayIdx(Index);
1209 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1210 assert(Index < AttrSets.size());
1212 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1214 return getImpl(C, AttrSets);
1217 AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1218 StringRef Kind) const {
1219 if (!hasAttribute(Index, Kind)) return *this;
1221 Index = attrIdxToArrayIdx(Index);
1222 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1223 assert(Index < AttrSets.size());
1225 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1227 return getImpl(C, AttrSets);
1230 AttributeList
1231 AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
1232 const AttrBuilder &AttrsToRemove) const {
1233 if (!pImpl)
1234 return {};
1236 Index = attrIdxToArrayIdx(Index);
1237 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1238 if (Index >= AttrSets.size())
1239 AttrSets.resize(Index + 1);
1241 AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
1243 return getImpl(C, AttrSets);
1246 AttributeList AttributeList::removeAttributes(LLVMContext &C,
1247 unsigned WithoutIndex) const {
1248 if (!pImpl)
1249 return {};
1250 WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1251 if (WithoutIndex >= getNumAttrSets())
1252 return *this;
1253 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1254 AttrSets[WithoutIndex] = AttributeSet();
1255 return getImpl(C, AttrSets);
1258 AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
1259 unsigned Index,
1260 uint64_t Bytes) const {
1261 AttrBuilder B;
1262 B.addDereferenceableAttr(Bytes);
1263 return addAttributes(C, Index, B);
1266 AttributeList
1267 AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
1268 uint64_t Bytes) const {
1269 AttrBuilder B;
1270 B.addDereferenceableOrNullAttr(Bytes);
1271 return addAttributes(C, Index, B);
1274 AttributeList
1275 AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
1276 unsigned ElemSizeArg,
1277 const Optional<unsigned> &NumElemsArg) {
1278 AttrBuilder B;
1279 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1280 return addAttributes(C, Index, B);
1283 //===----------------------------------------------------------------------===//
1284 // AttributeList Accessor Methods
1285 //===----------------------------------------------------------------------===//
1287 LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
1289 AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
1290 return getAttributes(ArgNo + FirstArgIndex);
1293 AttributeSet AttributeList::getRetAttributes() const {
1294 return getAttributes(ReturnIndex);
1297 AttributeSet AttributeList::getFnAttributes() const {
1298 return getAttributes(FunctionIndex);
1301 bool AttributeList::hasAttribute(unsigned Index,
1302 Attribute::AttrKind Kind) const {
1303 return getAttributes(Index).hasAttribute(Kind);
1306 bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
1307 return getAttributes(Index).hasAttribute(Kind);
1310 bool AttributeList::hasAttributes(unsigned Index) const {
1311 return getAttributes(Index).hasAttributes();
1314 bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
1315 return pImpl && pImpl->hasFnAttribute(Kind);
1318 bool AttributeList::hasFnAttribute(StringRef Kind) const {
1319 return hasAttribute(AttributeList::FunctionIndex, Kind);
1322 bool AttributeList::hasParamAttribute(unsigned ArgNo,
1323 Attribute::AttrKind Kind) const {
1324 return hasAttribute(ArgNo + FirstArgIndex, Kind);
1327 bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1328 unsigned *Index) const {
1329 if (!pImpl) return false;
1331 for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
1332 if (hasAttribute(I, Attr)) {
1333 if (Index)
1334 *Index = I;
1335 return true;
1339 return false;
1342 Attribute AttributeList::getAttribute(unsigned Index,
1343 Attribute::AttrKind Kind) const {
1344 return getAttributes(Index).getAttribute(Kind);
1347 Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
1348 return getAttributes(Index).getAttribute(Kind);
1351 MaybeAlign AttributeList::getRetAlignment() const {
1352 return getAttributes(ReturnIndex).getAlignment();
1355 MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
1356 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1359 Type *AttributeList::getParamByValType(unsigned Index) const {
1360 return getAttributes(Index+FirstArgIndex).getByValType();
1363 MaybeAlign 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.reset();
1440 StackAlignment.reset();
1441 DerefBytes = DerefOrNullBytes = 0;
1442 AllocSizeArgs = 0;
1443 ByValType = nullptr;
1446 AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
1447 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1448 assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1449 Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1450 "Adding integer attribute without adding a value!");
1451 Attrs[Val] = true;
1452 return *this;
1455 AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1456 if (Attr.isStringAttribute()) {
1457 addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1458 return *this;
1461 Attribute::AttrKind Kind = Attr.getKindAsEnum();
1462 Attrs[Kind] = true;
1464 if (Kind == Attribute::Alignment)
1465 Alignment = Attr.getAlignment();
1466 else if (Kind == Attribute::StackAlignment)
1467 StackAlignment = Attr.getStackAlignment();
1468 else if (Kind == Attribute::ByVal)
1469 ByValType = Attr.getValueAsType();
1470 else if (Kind == Attribute::Dereferenceable)
1471 DerefBytes = Attr.getDereferenceableBytes();
1472 else if (Kind == Attribute::DereferenceableOrNull)
1473 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1474 else if (Kind == Attribute::AllocSize)
1475 AllocSizeArgs = Attr.getValueAsInt();
1476 return *this;
1479 AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1480 TargetDepAttrs[A] = V;
1481 return *this;
1484 AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1485 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1486 Attrs[Val] = false;
1488 if (Val == Attribute::Alignment)
1489 Alignment.reset();
1490 else if (Val == Attribute::StackAlignment)
1491 StackAlignment.reset();
1492 else if (Val == Attribute::ByVal)
1493 ByValType = nullptr;
1494 else if (Val == Attribute::Dereferenceable)
1495 DerefBytes = 0;
1496 else if (Val == Attribute::DereferenceableOrNull)
1497 DerefOrNullBytes = 0;
1498 else if (Val == Attribute::AllocSize)
1499 AllocSizeArgs = 0;
1501 return *this;
1504 AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
1505 remove(A.getAttributes(Index));
1506 return *this;
1509 AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1510 auto I = TargetDepAttrs.find(A);
1511 if (I != TargetDepAttrs.end())
1512 TargetDepAttrs.erase(I);
1513 return *this;
1516 std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1517 return unpackAllocSizeArgs(AllocSizeArgs);
1520 AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
1521 if (!Align)
1522 return *this;
1524 assert(*Align <= 0x40000000 && "Alignment too large.");
1526 Attrs[Attribute::Alignment] = true;
1527 Alignment = Align;
1528 return *this;
1531 AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
1532 // Default alignment, allow the target to define how to align it.
1533 if (!Align)
1534 return *this;
1536 assert(*Align <= 0x100 && "Alignment too large.");
1538 Attrs[Attribute::StackAlignment] = true;
1539 StackAlignment = Align;
1540 return *this;
1543 AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1544 if (Bytes == 0) return *this;
1546 Attrs[Attribute::Dereferenceable] = true;
1547 DerefBytes = Bytes;
1548 return *this;
1551 AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1552 if (Bytes == 0)
1553 return *this;
1555 Attrs[Attribute::DereferenceableOrNull] = true;
1556 DerefOrNullBytes = Bytes;
1557 return *this;
1560 AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1561 const Optional<unsigned> &NumElems) {
1562 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1565 AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1566 // (0, 0) is our "not present" value, so we need to check for it here.
1567 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1569 Attrs[Attribute::AllocSize] = true;
1570 // Reuse existing machinery to store this as a single 64-bit integer so we can
1571 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1572 AllocSizeArgs = RawArgs;
1573 return *this;
1576 AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1577 Attrs[Attribute::ByVal] = true;
1578 ByValType = Ty;
1579 return *this;
1582 AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1583 // FIXME: What if both have alignments, but they don't match?!
1584 if (!Alignment)
1585 Alignment = B.Alignment;
1587 if (!StackAlignment)
1588 StackAlignment = B.StackAlignment;
1590 if (!DerefBytes)
1591 DerefBytes = B.DerefBytes;
1593 if (!DerefOrNullBytes)
1594 DerefOrNullBytes = B.DerefOrNullBytes;
1596 if (!AllocSizeArgs)
1597 AllocSizeArgs = B.AllocSizeArgs;
1599 if (!ByValType)
1600 ByValType = B.ByValType;
1602 Attrs |= B.Attrs;
1604 for (auto I : B.td_attrs())
1605 TargetDepAttrs[I.first] = I.second;
1607 return *this;
1610 AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1611 // FIXME: What if both have alignments, but they don't match?!
1612 if (B.Alignment)
1613 Alignment.reset();
1615 if (B.StackAlignment)
1616 StackAlignment.reset();
1618 if (B.DerefBytes)
1619 DerefBytes = 0;
1621 if (B.DerefOrNullBytes)
1622 DerefOrNullBytes = 0;
1624 if (B.AllocSizeArgs)
1625 AllocSizeArgs = 0;
1627 if (B.ByValType)
1628 ByValType = nullptr;
1630 Attrs &= ~B.Attrs;
1632 for (auto I : B.td_attrs())
1633 TargetDepAttrs.erase(I.first);
1635 return *this;
1638 bool AttrBuilder::overlaps(const AttrBuilder &B) const {
1639 // First check if any of the target independent attributes overlap.
1640 if ((Attrs & B.Attrs).any())
1641 return true;
1643 // Then check if any target dependent ones do.
1644 for (const auto &I : td_attrs())
1645 if (B.contains(I.first))
1646 return true;
1648 return false;
1651 bool AttrBuilder::contains(StringRef A) const {
1652 return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1655 bool AttrBuilder::hasAttributes() const {
1656 return !Attrs.none() || !TargetDepAttrs.empty();
1659 bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const {
1660 AttributeSet AS = AL.getAttributes(Index);
1662 for (const auto Attr : AS) {
1663 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1664 if (contains(Attr.getKindAsEnum()))
1665 return true;
1666 } else {
1667 assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1668 return contains(Attr.getKindAsString());
1672 return false;
1675 bool AttrBuilder::hasAlignmentAttr() const {
1676 return Alignment != 0;
1679 bool AttrBuilder::operator==(const AttrBuilder &B) {
1680 if (Attrs != B.Attrs)
1681 return false;
1683 for (td_const_iterator I = TargetDepAttrs.begin(),
1684 E = TargetDepAttrs.end(); I != E; ++I)
1685 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1686 return false;
1688 return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1689 DerefBytes == B.DerefBytes && ByValType == B.ByValType;
1692 //===----------------------------------------------------------------------===//
1693 // AttributeFuncs Function Defintions
1694 //===----------------------------------------------------------------------===//
1696 /// Which attributes cannot be applied to a type.
1697 AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
1698 AttrBuilder Incompatible;
1700 if (!Ty->isIntegerTy())
1701 // Attribute that only apply to integers.
1702 Incompatible.addAttribute(Attribute::SExt)
1703 .addAttribute(Attribute::ZExt);
1705 if (!Ty->isPointerTy())
1706 // Attribute that only apply to pointers.
1707 Incompatible.addAttribute(Attribute::ByVal)
1708 .addAttribute(Attribute::Nest)
1709 .addAttribute(Attribute::NoAlias)
1710 .addAttribute(Attribute::NoCapture)
1711 .addAttribute(Attribute::NonNull)
1712 .addDereferenceableAttr(1) // the int here is ignored
1713 .addDereferenceableOrNullAttr(1) // the int here is ignored
1714 .addAttribute(Attribute::ReadNone)
1715 .addAttribute(Attribute::ReadOnly)
1716 .addAttribute(Attribute::StructRet)
1717 .addAttribute(Attribute::InAlloca);
1719 return Incompatible;
1722 template<typename AttrClass>
1723 static bool isEqual(const Function &Caller, const Function &Callee) {
1724 return Caller.getFnAttribute(AttrClass::getKind()) ==
1725 Callee.getFnAttribute(AttrClass::getKind());
1728 /// Compute the logical AND of the attributes of the caller and the
1729 /// callee.
1731 /// This function sets the caller's attribute to false if the callee's attribute
1732 /// is false.
1733 template<typename AttrClass>
1734 static void setAND(Function &Caller, const Function &Callee) {
1735 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1736 !AttrClass::isSet(Callee, AttrClass::getKind()))
1737 AttrClass::set(Caller, AttrClass::getKind(), false);
1740 /// Compute the logical OR of the attributes of the caller and the
1741 /// callee.
1743 /// This function sets the caller's attribute to true if the callee's attribute
1744 /// is true.
1745 template<typename AttrClass>
1746 static void setOR(Function &Caller, const Function &Callee) {
1747 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1748 AttrClass::isSet(Callee, AttrClass::getKind()))
1749 AttrClass::set(Caller, AttrClass::getKind(), true);
1752 /// If the inlined function had a higher stack protection level than the
1753 /// calling function, then bump up the caller's stack protection level.
1754 static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1755 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1756 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1757 // clutter to the IR.
1758 AttrBuilder OldSSPAttr;
1759 OldSSPAttr.addAttribute(Attribute::StackProtect)
1760 .addAttribute(Attribute::StackProtectStrong)
1761 .addAttribute(Attribute::StackProtectReq);
1763 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1764 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1765 Caller.addFnAttr(Attribute::StackProtectReq);
1766 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1767 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1768 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1769 Caller.addFnAttr(Attribute::StackProtectStrong);
1770 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1771 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1772 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1773 Caller.addFnAttr(Attribute::StackProtect);
1776 /// If the inlined function required stack probes, then ensure that
1777 /// the calling function has those too.
1778 static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
1779 if (!Caller.hasFnAttribute("probe-stack") &&
1780 Callee.hasFnAttribute("probe-stack")) {
1781 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
1785 /// If the inlined function defines the size of guard region
1786 /// on the stack, then ensure that the calling function defines a guard region
1787 /// that is no larger.
1788 static void
1789 adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
1790 if (Callee.hasFnAttribute("stack-probe-size")) {
1791 uint64_t CalleeStackProbeSize;
1792 Callee.getFnAttribute("stack-probe-size")
1793 .getValueAsString()
1794 .getAsInteger(0, CalleeStackProbeSize);
1795 if (Caller.hasFnAttribute("stack-probe-size")) {
1796 uint64_t CallerStackProbeSize;
1797 Caller.getFnAttribute("stack-probe-size")
1798 .getValueAsString()
1799 .getAsInteger(0, CallerStackProbeSize);
1800 if (CallerStackProbeSize > CalleeStackProbeSize) {
1801 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1803 } else {
1804 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1809 /// If the inlined function defines a min legal vector width, then ensure
1810 /// the calling function has the same or larger min legal vector width. If the
1811 /// caller has the attribute, but the callee doesn't, we need to remove the
1812 /// attribute from the caller since we can't make any guarantees about the
1813 /// caller's requirements.
1814 /// This function is called after the inlining decision has been made so we have
1815 /// to merge the attribute this way. Heuristics that would use
1816 /// min-legal-vector-width to determine inline compatibility would need to be
1817 /// handled as part of inline cost analysis.
1818 static void
1819 adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
1820 if (Caller.hasFnAttribute("min-legal-vector-width")) {
1821 if (Callee.hasFnAttribute("min-legal-vector-width")) {
1822 uint64_t CallerVectorWidth;
1823 Caller.getFnAttribute("min-legal-vector-width")
1824 .getValueAsString()
1825 .getAsInteger(0, CallerVectorWidth);
1826 uint64_t CalleeVectorWidth;
1827 Callee.getFnAttribute("min-legal-vector-width")
1828 .getValueAsString()
1829 .getAsInteger(0, CalleeVectorWidth);
1830 if (CallerVectorWidth < CalleeVectorWidth)
1831 Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
1832 } else {
1833 // If the callee doesn't have the attribute then we don't know anything
1834 // and must drop the attribute from the caller.
1835 Caller.removeFnAttr("min-legal-vector-width");
1840 /// If the inlined function has "null-pointer-is-valid=true" attribute,
1841 /// set this attribute in the caller post inlining.
1842 static void
1843 adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
1844 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
1845 Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid"));
1849 #define GET_ATTR_COMPAT_FUNC
1850 #include "AttributesCompatFunc.inc"
1852 bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1853 const Function &Callee) {
1854 return hasCompatibleFnAttrs(Caller, Callee);
1857 void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
1858 const Function &Callee) {
1859 mergeFnAttrs(Caller, Callee);