Line data Source code
1 : //===- Attributes.cpp - Implement AttributesList --------------------------===//
2 : //
3 : // The LLVM Compiler Infrastructure
4 : //
5 : // This file is distributed under the University of Illinois Open Source
6 : // License. See LICENSE.TXT for details.
7 : //
8 : //===----------------------------------------------------------------------===//
9 : //
10 : // \file
11 : // This file implements the Attribute, AttributeImpl, AttrBuilder,
12 : // AttributeListImpl, and AttributeList classes.
13 : //
14 : //===----------------------------------------------------------------------===//
15 :
16 : #include "llvm/IR/Attributes.h"
17 : #include "AttributeImpl.h"
18 : #include "LLVMContextImpl.h"
19 : #include "llvm/ADT/ArrayRef.h"
20 : #include "llvm/ADT/FoldingSet.h"
21 : #include "llvm/ADT/Optional.h"
22 : #include "llvm/ADT/STLExtras.h"
23 : #include "llvm/ADT/SmallVector.h"
24 : #include "llvm/ADT/StringExtras.h"
25 : #include "llvm/ADT/StringRef.h"
26 : #include "llvm/ADT/Twine.h"
27 : #include "llvm/Config/llvm-config.h"
28 : #include "llvm/IR/Function.h"
29 : #include "llvm/IR/LLVMContext.h"
30 : #include "llvm/IR/Type.h"
31 : #include "llvm/Support/Compiler.h"
32 : #include "llvm/Support/Debug.h"
33 : #include "llvm/Support/ErrorHandling.h"
34 : #include "llvm/Support/MathExtras.h"
35 : #include "llvm/Support/raw_ostream.h"
36 : #include <algorithm>
37 : #include <cassert>
38 : #include <climits>
39 : #include <cstddef>
40 : #include <cstdint>
41 : #include <limits>
42 : #include <string>
43 : #include <tuple>
44 : #include <utility>
45 :
46 : using namespace llvm;
47 :
48 : //===----------------------------------------------------------------------===//
49 : // Attribute Construction Methods
50 : //===----------------------------------------------------------------------===//
51 :
52 : // allocsize has two integer arguments, but because they're both 32 bits, we can
53 : // pack them into one 64-bit value, at the cost of making said value
54 : // nonsensical.
55 : //
56 : // In order to do this, we need to reserve one value of the second (optional)
57 : // allocsize argument to signify "not present."
58 : static const unsigned AllocSizeNumElemsNotPresent = -1;
59 :
60 : static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
61 : const Optional<unsigned> &NumElemsArg) {
62 : assert((!NumElemsArg.hasValue() ||
63 : *NumElemsArg != AllocSizeNumElemsNotPresent) &&
64 : "Attempting to pack a reserved value");
65 :
66 172 : return uint64_t(ElemSizeArg) << 32 |
67 172 : NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
68 : }
69 :
70 : static std::pair<unsigned, Optional<unsigned>>
71 : unpackAllocSizeArgs(uint64_t Num) {
72 258 : unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
73 258 : unsigned ElemSizeArg = Num >> 32;
74 :
75 : Optional<unsigned> NumElemsArg;
76 145 : if (NumElems != AllocSizeNumElemsNotPresent)
77 : NumElemsArg = NumElems;
78 : return std::make_pair(ElemSizeArg, NumElemsArg);
79 : }
80 :
81 12084857 : Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
82 : uint64_t Val) {
83 12084857 : LLVMContextImpl *pImpl = Context.pImpl;
84 : FoldingSetNodeID ID;
85 12084857 : ID.AddInteger(Kind);
86 12084857 : if (Val) ID.AddInteger(Val);
87 :
88 : void *InsertPoint;
89 : AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
90 :
91 11875168 : if (!PA) {
92 : // If we didn't find any existing attributes of the same shape then create a
93 : // new one and insert it.
94 209689 : if (!Val)
95 173368 : PA = new EnumAttributeImpl(Kind);
96 : else
97 36321 : PA = new IntAttributeImpl(Kind, Val);
98 209689 : pImpl->AttrsSet.InsertNode(PA, InsertPoint);
99 : }
100 :
101 : // Return the Attribute that we found or created.
102 12084857 : return Attribute(PA);
103 : }
104 :
105 75812945 : Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
106 75812945 : LLVMContextImpl *pImpl = Context.pImpl;
107 : FoldingSetNodeID ID;
108 75812945 : ID.AddString(Kind);
109 75812945 : if (!Val.empty()) ID.AddString(Val);
110 :
111 : void *InsertPoint;
112 : AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
113 :
114 75581029 : if (!PA) {
115 : // If we didn't find any existing attributes of the same shape then create a
116 : // new one and insert it.
117 231916 : PA = new StringAttributeImpl(Kind, Val);
118 231916 : pImpl->AttrsSet.InsertNode(PA, InsertPoint);
119 : }
120 :
121 : // Return the Attribute that we found or created.
122 75812945 : return Attribute(PA);
123 : }
124 :
125 790711 : Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
126 : assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
127 : assert(Align <= 0x40000000 && "Alignment too large.");
128 790711 : return get(Context, Alignment, Align);
129 : }
130 :
131 205 : Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
132 : uint64_t Align) {
133 : assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
134 : assert(Align <= 0x100 && "Alignment too large.");
135 205 : return get(Context, StackAlignment, Align);
136 : }
137 :
138 1720132 : Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
139 : uint64_t Bytes) {
140 : assert(Bytes && "Bytes must be non-zero.");
141 1720132 : return get(Context, Dereferenceable, Bytes);
142 : }
143 :
144 103 : Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
145 : uint64_t Bytes) {
146 : assert(Bytes && "Bytes must be non-zero.");
147 103 : return get(Context, DereferenceableOrNull, Bytes);
148 : }
149 :
150 : Attribute
151 114 : Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
152 : const Optional<unsigned> &NumElemsArg) {
153 : assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
154 : "Invalid allocsize arguments -- given allocsize(0, 0)");
155 114 : return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
156 : }
157 :
158 : //===----------------------------------------------------------------------===//
159 : // Attribute Accessor Methods
160 : //===----------------------------------------------------------------------===//
161 :
162 18484 : bool Attribute::isEnumAttribute() const {
163 18484 : return pImpl && pImpl->isEnumAttribute();
164 : }
165 :
166 11718 : bool Attribute::isIntAttribute() const {
167 11718 : return pImpl && pImpl->isIntAttribute();
168 : }
169 :
170 2825753706 : bool Attribute::isStringAttribute() const {
171 2825753706 : return pImpl && pImpl->isStringAttribute();
172 : }
173 :
174 7830263 : Attribute::AttrKind Attribute::getKindAsEnum() const {
175 7830263 : if (!pImpl) return None;
176 : assert((isEnumAttribute() || isIntAttribute()) &&
177 : "Invalid attribute type to get the kind as an enum!");
178 7830263 : return pImpl->getKindAsEnum();
179 : }
180 :
181 38321 : uint64_t Attribute::getValueAsInt() const {
182 38321 : if (!pImpl) return 0;
183 : assert(isIntAttribute() &&
184 : "Expected the attribute to be an integer attribute!");
185 38321 : return pImpl->getValueAsInt();
186 : }
187 :
188 61194514 : StringRef Attribute::getKindAsString() const {
189 61194514 : if (!pImpl) return {};
190 : assert(isStringAttribute() &&
191 : "Invalid attribute type to get the kind as a string!");
192 61194514 : return pImpl->getKindAsString();
193 : }
194 :
195 159743007 : StringRef Attribute::getValueAsString() const {
196 159743007 : if (!pImpl) return {};
197 : assert(isStringAttribute() &&
198 : "Invalid attribute type to get the value as a string!");
199 120939978 : return pImpl->getValueAsString();
200 : }
201 :
202 45793040 : bool Attribute::hasAttribute(AttrKind Kind) const {
203 45793040 : return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
204 : }
205 :
206 2739794745 : bool Attribute::hasAttribute(StringRef Kind) const {
207 2739794745 : if (!isStringAttribute()) return false;
208 2226640170 : return pImpl && pImpl->hasAttribute(Kind);
209 : }
210 :
211 1311545 : unsigned Attribute::getAlignment() const {
212 : assert(hasAttribute(Attribute::Alignment) &&
213 : "Trying to get alignment from non-alignment attribute!");
214 1311545 : return pImpl->getValueAsInt();
215 : }
216 :
217 184 : unsigned Attribute::getStackAlignment() const {
218 : assert(hasAttribute(Attribute::StackAlignment) &&
219 : "Trying to get alignment from non-alignment attribute!");
220 184 : return pImpl->getValueAsInt();
221 : }
222 :
223 207819 : uint64_t Attribute::getDereferenceableBytes() const {
224 : assert(hasAttribute(Attribute::Dereferenceable) &&
225 : "Trying to get dereferenceable bytes from "
226 : "non-dereferenceable attribute!");
227 207819 : return pImpl->getValueAsInt();
228 : }
229 :
230 149 : uint64_t Attribute::getDereferenceableOrNullBytes() const {
231 : assert(hasAttribute(Attribute::DereferenceableOrNull) &&
232 : "Trying to get dereferenceable bytes from "
233 : "non-dereferenceable attribute!");
234 149 : return pImpl->getValueAsInt();
235 : }
236 :
237 145 : std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
238 : assert(hasAttribute(Attribute::AllocSize) &&
239 : "Trying to get allocsize args from non-allocsize attribute");
240 145 : return unpackAllocSizeArgs(pImpl->getValueAsInt());
241 : }
242 :
243 706309 : std::string Attribute::getAsString(bool InAttrGrp) const {
244 706309 : if (!pImpl) return {};
245 :
246 706309 : if (hasAttribute(Attribute::SanitizeAddress))
247 1070 : return "sanitize_address";
248 705239 : if (hasAttribute(Attribute::SanitizeHWAddress))
249 221 : return "sanitize_hwaddress";
250 705018 : if (hasAttribute(Attribute::AlwaysInline))
251 854 : return "alwaysinline";
252 704164 : if (hasAttribute(Attribute::ArgMemOnly))
253 7059 : return "argmemonly";
254 697105 : if (hasAttribute(Attribute::Builtin))
255 364 : return "builtin";
256 696741 : if (hasAttribute(Attribute::ByVal))
257 1347 : return "byval";
258 695394 : if (hasAttribute(Attribute::Convergent))
259 1929 : return "convergent";
260 693465 : if (hasAttribute(Attribute::SwiftError))
261 71 : return "swifterror";
262 693394 : if (hasAttribute(Attribute::SwiftSelf))
263 46 : return "swiftself";
264 693348 : if (hasAttribute(Attribute::InaccessibleMemOnly))
265 197 : return "inaccessiblememonly";
266 693151 : if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
267 98 : return "inaccessiblemem_or_argmemonly";
268 693053 : if (hasAttribute(Attribute::InAlloca))
269 206 : return "inalloca";
270 692847 : if (hasAttribute(Attribute::InlineHint))
271 1203 : return "inlinehint";
272 691644 : if (hasAttribute(Attribute::InReg))
273 991 : return "inreg";
274 690653 : if (hasAttribute(Attribute::JumpTable))
275 28 : return "jumptable";
276 690625 : if (hasAttribute(Attribute::MinSize))
277 424 : return "minsize";
278 690201 : if (hasAttribute(Attribute::Naked))
279 120 : return "naked";
280 690081 : if (hasAttribute(Attribute::Nest))
281 81 : return "nest";
282 690000 : if (hasAttribute(Attribute::NoAlias))
283 17283 : return "noalias";
284 672717 : if (hasAttribute(Attribute::NoBuiltin))
285 951 : return "nobuiltin";
286 671766 : if (hasAttribute(Attribute::NoCapture))
287 10527 : return "nocapture";
288 661239 : if (hasAttribute(Attribute::NoDuplicate))
289 66 : return "noduplicate";
290 661173 : if (hasAttribute(Attribute::NoImplicitFloat))
291 81 : return "noimplicitfloat";
292 661092 : if (hasAttribute(Attribute::NoInline))
293 100626 : return "noinline";
294 560466 : if (hasAttribute(Attribute::NonLazyBind))
295 642 : return "nonlazybind";
296 559824 : if (hasAttribute(Attribute::NonNull))
297 3184 : return "nonnull";
298 556640 : if (hasAttribute(Attribute::NoRedZone))
299 187 : return "noredzone";
300 556453 : if (hasAttribute(Attribute::NoReturn))
301 1462 : return "noreturn";
302 554991 : if (hasAttribute(Attribute::NoCfCheck))
303 3 : return "nocf_check";
304 554988 : if (hasAttribute(Attribute::NoRecurse))
305 19566 : return "norecurse";
306 535422 : if (hasAttribute(Attribute::NoUnwind))
307 156245 : return "nounwind";
308 379177 : if (hasAttribute(Attribute::OptForFuzzing))
309 2 : return "optforfuzzing";
310 379175 : if (hasAttribute(Attribute::OptimizeNone))
311 76456 : return "optnone";
312 302719 : if (hasAttribute(Attribute::OptimizeForSize))
313 891 : return "optsize";
314 301828 : if (hasAttribute(Attribute::ReadNone))
315 19805 : return "readnone";
316 282023 : if (hasAttribute(Attribute::ReadOnly))
317 6837 : return "readonly";
318 275186 : if (hasAttribute(Attribute::WriteOnly))
319 2521 : return "writeonly";
320 272665 : if (hasAttribute(Attribute::Returned))
321 1742 : return "returned";
322 270923 : if (hasAttribute(Attribute::ReturnsTwice))
323 145 : return "returns_twice";
324 270778 : if (hasAttribute(Attribute::SExt))
325 8647 : return "signext";
326 262131 : if (hasAttribute(Attribute::SpeculativeLoadHardening))
327 10 : return "speculative_load_hardening";
328 262121 : if (hasAttribute(Attribute::Speculatable))
329 5200 : return "speculatable";
330 256921 : if (hasAttribute(Attribute::StackProtect))
331 1426 : return "ssp";
332 255495 : if (hasAttribute(Attribute::StackProtectReq))
333 86 : return "sspreq";
334 255409 : if (hasAttribute(Attribute::StackProtectStrong))
335 109 : return "sspstrong";
336 255300 : if (hasAttribute(Attribute::SafeStack))
337 334 : return "safestack";
338 254966 : if (hasAttribute(Attribute::ShadowCallStack))
339 21 : return "shadowcallstack";
340 254945 : if (hasAttribute(Attribute::StrictFP))
341 10 : return "strictfp";
342 254935 : if (hasAttribute(Attribute::StructRet))
343 2600 : return "sret";
344 252335 : if (hasAttribute(Attribute::SanitizeThread))
345 168 : return "sanitize_thread";
346 252167 : if (hasAttribute(Attribute::SanitizeMemory))
347 655 : return "sanitize_memory";
348 251512 : if (hasAttribute(Attribute::UWTable))
349 3249 : return "uwtable";
350 248263 : if (hasAttribute(Attribute::ZExt))
351 7653 : return "zeroext";
352 240610 : if (hasAttribute(Attribute::Cold))
353 74 : return "cold";
354 :
355 : // FIXME: These should be output like this:
356 : //
357 : // align=4
358 : // alignstack=8
359 : //
360 240536 : if (hasAttribute(Attribute::Alignment)) {
361 : std::string Result;
362 : Result += "align";
363 19778 : Result += (InAttrGrp) ? "=" : " ";
364 39556 : Result += utostr(getValueAsInt());
365 : return Result;
366 : }
367 :
368 : auto AttrWithBytesToString = [&](const char *Name) {
369 : std::string Result;
370 : Result += Name;
371 : if (InAttrGrp) {
372 : Result += "=";
373 : Result += utostr(getValueAsInt());
374 : } else {
375 : Result += "(";
376 : Result += utostr(getValueAsInt());
377 : Result += ")";
378 : }
379 : return Result;
380 220758 : };
381 :
382 220758 : if (hasAttribute(Attribute::StackAlignment))
383 74 : return AttrWithBytesToString("alignstack");
384 :
385 220684 : if (hasAttribute(Attribute::Dereferenceable))
386 17468 : return AttrWithBytesToString("dereferenceable");
387 :
388 203216 : if (hasAttribute(Attribute::DereferenceableOrNull))
389 65 : return AttrWithBytesToString("dereferenceable_or_null");
390 :
391 203151 : if (hasAttribute(Attribute::AllocSize)) {
392 : unsigned ElemSize;
393 : Optional<unsigned> NumElems;
394 44 : std::tie(ElemSize, NumElems) = getAllocSizeArgs();
395 :
396 44 : std::string Result = "allocsize(";
397 44 : Result += utostr(ElemSize);
398 44 : if (NumElems.hasValue()) {
399 : Result += ',';
400 40 : Result += utostr(*NumElems);
401 : }
402 : Result += ')';
403 : return Result;
404 : }
405 :
406 : // Convert target-dependent attributes to strings of the form:
407 : //
408 : // "kind"
409 : // "kind" = "value"
410 : //
411 203107 : if (isStringAttribute()) {
412 : std::string Result;
413 406214 : Result += (Twine('"') + getKindAsString() + Twine('"')).str();
414 :
415 406214 : std::string AttrVal = pImpl->getValueAsString();
416 203107 : if (AttrVal.empty()) return Result;
417 :
418 : // Since some attribute strings contain special characters that cannot be
419 : // printable, those have to be escaped to make the attribute value printable
420 : // as is. e.g. "\01__gnu_mcount_nc"
421 : {
422 201151 : raw_string_ostream OS(Result);
423 201151 : OS << "=\"";
424 201151 : printEscapedString(AttrVal, OS);
425 201151 : OS << "\"";
426 : }
427 : return Result;
428 : }
429 :
430 0 : llvm_unreachable("Unknown attribute");
431 : }
432 :
433 169215233 : bool Attribute::operator<(Attribute A) const {
434 169215233 : if (!pImpl && !A.pImpl) return false;
435 169215233 : if (!pImpl) return true;
436 169215233 : if (!A.pImpl) return false;
437 169215233 : return *pImpl < *A.pImpl;
438 : }
439 :
440 : //===----------------------------------------------------------------------===//
441 : // AttributeImpl Definition
442 : //===----------------------------------------------------------------------===//
443 :
444 : // Pin the vtables to this file.
445 : AttributeImpl::~AttributeImpl() = default;
446 :
447 0 : void EnumAttributeImpl::anchor() {}
448 :
449 0 : void IntAttributeImpl::anchor() {}
450 :
451 0 : void StringAttributeImpl::anchor() {}
452 :
453 40435035 : bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
454 40435035 : if (isStringAttribute()) return false;
455 18944859 : return getKindAsEnum() == A;
456 : }
457 :
458 2226640170 : bool AttributeImpl::hasAttribute(StringRef Kind) const {
459 2226640170 : if (!isStringAttribute()) return false;
460 2226640170 : return getKindAsString() == Kind;
461 : }
462 :
463 77106369 : Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
464 : assert(isEnumAttribute() || isIntAttribute());
465 77106369 : return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
466 : }
467 :
468 18377540 : uint64_t AttributeImpl::getValueAsInt() const {
469 : assert(isIntAttribute());
470 18377540 : return static_cast<const IntAttributeImpl *>(this)->getValue();
471 : }
472 :
473 2792479270 : StringRef AttributeImpl::getKindAsString() const {
474 : assert(isStringAttribute());
475 2792479270 : return static_cast<const StringAttributeImpl *>(this)->getStringKind();
476 : }
477 :
478 197209963 : StringRef AttributeImpl::getValueAsString() const {
479 : assert(isStringAttribute());
480 197209963 : return static_cast<const StringAttributeImpl *>(this)->getStringValue();
481 : }
482 :
483 169215233 : bool AttributeImpl::operator<(const AttributeImpl &AI) const {
484 : // This sorts the attributes with Attribute::AttrKinds coming first (sorted
485 : // relative to their enum value) and then strings.
486 169215233 : if (isEnumAttribute()) {
487 8858763 : if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
488 4611743 : if (AI.isIntAttribute()) return true;
489 4530086 : if (AI.isStringAttribute()) return true;
490 : }
491 :
492 160356470 : if (isIntAttribute()) {
493 29972 : if (AI.isEnumAttribute()) return false;
494 29869 : if (AI.isIntAttribute()) {
495 29839 : if (getKindAsEnum() == AI.getKindAsEnum())
496 1 : return getValueAsInt() < AI.getValueAsInt();
497 29838 : return getKindAsEnum() < AI.getKindAsEnum();
498 : }
499 30 : if (AI.isStringAttribute()) return true;
500 : }
501 :
502 160326498 : if (AI.isEnumAttribute()) return false;
503 107144794 : if (AI.isIntAttribute()) return false;
504 107144479 : if (getKindAsString() == AI.getKindAsString())
505 52 : return getValueAsString() < AI.getValueAsString();
506 107144427 : return getKindAsString() < AI.getKindAsString();
507 : }
508 :
509 : //===----------------------------------------------------------------------===//
510 : // AttributeSet Definition
511 : //===----------------------------------------------------------------------===//
512 :
513 16674440 : AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
514 16674440 : return AttributeSet(AttributeSetNode::get(C, B));
515 : }
516 :
517 279474 : AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
518 279474 : return AttributeSet(AttributeSetNode::get(C, Attrs));
519 : }
520 :
521 0 : AttributeSet AttributeSet::addAttribute(LLVMContext &C,
522 : Attribute::AttrKind Kind) const {
523 0 : if (hasAttribute(Kind)) return *this;
524 : AttrBuilder B;
525 0 : B.addAttribute(Kind);
526 0 : return addAttributes(C, AttributeSet::get(C, B));
527 : }
528 :
529 44 : AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
530 : StringRef Value) const {
531 : AttrBuilder B;
532 44 : B.addAttribute(Kind, Value);
533 44 : return addAttributes(C, AttributeSet::get(C, B));
534 : }
535 :
536 44 : AttributeSet AttributeSet::addAttributes(LLVMContext &C,
537 : const AttributeSet AS) const {
538 44 : if (!hasAttributes())
539 19 : return AS;
540 :
541 25 : if (!AS.hasAttributes())
542 0 : return *this;
543 :
544 25 : AttrBuilder B(AS);
545 59 : for (const auto I : *this)
546 34 : B.addAttribute(I);
547 :
548 25 : return get(C, B);
549 : }
550 :
551 20332 : AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
552 : Attribute::AttrKind Kind) const {
553 20332 : if (!hasAttribute(Kind)) return *this;
554 15711 : AttrBuilder B(*this);
555 15711 : B.removeAttribute(Kind);
556 15711 : return get(C, B);
557 : }
558 :
559 1527520 : AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
560 : StringRef Kind) const {
561 1527520 : if (!hasAttribute(Kind)) return *this;
562 1527520 : AttrBuilder B(*this);
563 1527520 : B.removeAttribute(Kind);
564 1527520 : return get(C, B);
565 : }
566 :
567 27607 : AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
568 : const AttrBuilder &Attrs) const {
569 27607 : AttrBuilder B(*this);
570 27607 : B.remove(Attrs);
571 27607 : return get(C, B);
572 : }
573 :
574 4 : unsigned AttributeSet::getNumAttributes() const {
575 4 : return SetNode ? SetNode->getNumAttributes() : 0;
576 : }
577 :
578 584268351 : bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
579 584268351 : return SetNode ? SetNode->hasAttribute(Kind) : false;
580 : }
581 :
582 110870202 : bool AttributeSet::hasAttribute(StringRef Kind) const {
583 110870202 : return SetNode ? SetNode->hasAttribute(Kind) : false;
584 : }
585 :
586 4027887 : Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
587 4027887 : return SetNode ? SetNode->getAttribute(Kind) : Attribute();
588 : }
589 :
590 104918855 : Attribute AttributeSet::getAttribute(StringRef Kind) const {
591 104918855 : return SetNode ? SetNode->getAttribute(Kind) : Attribute();
592 : }
593 :
594 8689783 : unsigned AttributeSet::getAlignment() const {
595 8689783 : return SetNode ? SetNode->getAlignment() : 0;
596 : }
597 :
598 65 : unsigned AttributeSet::getStackAlignment() const {
599 65 : return SetNode ? SetNode->getStackAlignment() : 0;
600 : }
601 :
602 2104782 : uint64_t AttributeSet::getDereferenceableBytes() const {
603 2104782 : return SetNode ? SetNode->getDereferenceableBytes() : 0;
604 : }
605 :
606 112033 : uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
607 112033 : return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
608 : }
609 :
610 83 : std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
611 83 : return SetNode ? SetNode->getAllocSizeArgs()
612 83 : : std::pair<unsigned, Optional<unsigned>>(0, 0);
613 : }
614 :
615 118399 : std::string AttributeSet::getAsString(bool InAttrGrp) const {
616 118399 : return SetNode ? SetNode->getAsString(InAttrGrp) : "";
617 : }
618 :
619 9068360 : AttributeSet::iterator AttributeSet::begin() const {
620 9068360 : return SetNode ? SetNode->begin() : nullptr;
621 : }
622 :
623 9068360 : AttributeSet::iterator AttributeSet::end() const {
624 9068360 : return SetNode ? SetNode->end() : nullptr;
625 : }
626 :
627 : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
628 : LLVM_DUMP_METHOD void AttributeSet::dump() const {
629 : dbgs() << "AS =\n";
630 : dbgs() << " { ";
631 : dbgs() << getAsString(true) << " }\n";
632 : }
633 : #endif
634 :
635 : //===----------------------------------------------------------------------===//
636 : // AttributeSetNode Definition
637 : //===----------------------------------------------------------------------===//
638 :
639 340133 : AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
640 340133 : : AvailableAttrs(0), NumAttrs(Attrs.size()) {
641 : // There's memory after the node where we can store the entries in.
642 : std::copy(Attrs.begin(), Attrs.end(), getTrailingObjects<Attribute>());
643 :
644 3082640 : for (const auto I : *this) {
645 2742507 : if (!I.isStringAttribute()) {
646 493953 : AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
647 : }
648 : }
649 340133 : }
650 :
651 16953914 : AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
652 : ArrayRef<Attribute> Attrs) {
653 16953914 : if (Attrs.empty())
654 : return nullptr;
655 :
656 : // Otherwise, build a key to look up the existing attributes.
657 10744303 : LLVMContextImpl *pImpl = C.pImpl;
658 : FoldingSetNodeID ID;
659 :
660 : SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
661 : llvm::sort(SortedAttrs);
662 :
663 97201706 : for (const auto Attr : SortedAttrs)
664 : Attr.Profile(ID);
665 :
666 : void *InsertPoint;
667 : AttributeSetNode *PA =
668 : pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
669 :
670 : // If we didn't find any existing attributes of the same shape then create a
671 : // new one and insert it.
672 10744303 : if (!PA) {
673 : // Coallocate entries after the AttributeSetNode itself.
674 680266 : void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
675 340133 : PA = new (Mem) AttributeSetNode(SortedAttrs);
676 340133 : pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
677 : }
678 :
679 : // Return the AttributeSetNode that we found or created.
680 : return PA;
681 : }
682 :
683 16674440 : AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
684 : // Add target-independent attributes.
685 : SmallVector<Attribute, 8> Attrs;
686 1000466400 : for (Attribute::AttrKind Kind = Attribute::None;
687 1017140840 : Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
688 1000466400 : if (!B.contains(Kind))
689 989425850 : continue;
690 :
691 11040550 : Attribute Attr;
692 11040550 : switch (Kind) {
693 403041 : case Attribute::Alignment:
694 403041 : Attr = Attribute::getWithAlignment(C, B.getAlignment());
695 403041 : break;
696 204 : case Attribute::StackAlignment:
697 204 : Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
698 204 : break;
699 1705277 : case Attribute::Dereferenceable:
700 : Attr = Attribute::getWithDereferenceableBytes(
701 1705277 : C, B.getDereferenceableBytes());
702 1705277 : break;
703 103 : case Attribute::DereferenceableOrNull:
704 : Attr = Attribute::getWithDereferenceableOrNullBytes(
705 103 : C, B.getDereferenceableOrNullBytes());
706 103 : break;
707 113 : case Attribute::AllocSize: {
708 113 : auto A = B.getAllocSizeArgs();
709 113 : Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
710 : break;
711 : }
712 8931812 : default:
713 8931812 : Attr = Attribute::get(C, Kind);
714 : }
715 11040550 : Attrs.push_back(Attr);
716 : }
717 :
718 : // Add target-dependent (string) attributes.
719 91631410 : for (const auto &TDA : B.td_attrs())
720 74956970 : Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
721 :
722 16674440 : return get(C, Attrs);
723 : }
724 :
725 107763462 : bool AttributeSetNode::hasAttribute(StringRef Kind) const {
726 1791598232 : for (const auto I : *this)
727 1688004349 : if (I.hasAttribute(Kind))
728 4169582 : return true;
729 103593883 : return false;
730 : }
731 :
732 4010981 : Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
733 8021962 : if (hasAttribute(Kind)) {
734 159 : for (const auto I : *this)
735 159 : if (I.hasAttribute(Kind))
736 115 : return I;
737 : }
738 4010866 : return {};
739 : }
740 :
741 103429427 : Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
742 1095264226 : for (const auto I : *this)
743 1051790384 : if (I.hasAttribute(Kind))
744 59955586 : return I;
745 43473842 : return {};
746 : }
747 :
748 2130991 : unsigned AttributeSetNode::getAlignment() const {
749 3657176 : for (const auto I : *this)
750 2386318 : if (I.hasAttribute(Attribute::Alignment))
751 860133 : return I.getAlignment();
752 1270858 : return 0;
753 : }
754 :
755 65 : unsigned AttributeSetNode::getStackAlignment() const {
756 90 : for (const auto I : *this)
757 90 : if (I.hasAttribute(Attribute::StackAlignment))
758 65 : return I.getStackAlignment();
759 0 : return 0;
760 : }
761 :
762 585123 : uint64_t AttributeSetNode::getDereferenceableBytes() const {
763 1207316 : for (const auto I : *this)
764 726328 : if (I.hasAttribute(Attribute::Dereferenceable))
765 104135 : return I.getDereferenceableBytes();
766 480988 : return 0;
767 : }
768 :
769 10930 : uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
770 26965 : for (const auto I : *this)
771 16062 : if (I.hasAttribute(Attribute::DereferenceableOrNull))
772 27 : return I.getDereferenceableOrNullBytes();
773 10903 : return 0;
774 : }
775 :
776 : std::pair<unsigned, Optional<unsigned>>
777 83 : AttributeSetNode::getAllocSizeArgs() const {
778 83 : for (const auto I : *this)
779 83 : if (I.hasAttribute(Attribute::AllocSize))
780 83 : return I.getAllocSizeArgs();
781 : return std::make_pair(0, 0);
782 : }
783 :
784 118399 : std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
785 : std::string Str;
786 482657 : for (iterator I = begin(), E = end(); I != E; ++I) {
787 364258 : if (I != begin())
788 : Str += ' ';
789 728516 : Str += I->getAsString(InAttrGrp);
790 : }
791 118399 : return Str;
792 : }
793 :
794 : //===----------------------------------------------------------------------===//
795 : // AttributeListImpl Definition
796 : //===----------------------------------------------------------------------===//
797 :
798 : /// Map from AttributeList index to the internal array index. Adding one happens
799 : /// to work, but it relies on unsigned integer wrapping. MSVC warns about
800 : /// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
801 : /// folds it to add anyway.
802 : static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
803 197240861 : return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
804 : }
805 :
806 984857 : AttributeListImpl::AttributeListImpl(LLVMContext &C,
807 984857 : ArrayRef<AttributeSet> Sets)
808 984857 : : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) {
809 : assert(!Sets.empty() && "pointless AttributeListImpl");
810 :
811 : // There's memory after the node where we can store the entries in.
812 : std::copy(Sets.begin(), Sets.end(), getTrailingObjects<AttributeSet>());
813 :
814 : // Initialize AvailableFunctionAttrs summary bitset.
815 : static_assert(Attribute::EndAttrKinds <=
816 : sizeof(AvailableFunctionAttrs) * CHAR_BIT,
817 : "Too many attributes");
818 : static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
819 : "function should be stored in slot 0");
820 11825223 : for (const auto I : Sets[0]) {
821 10840366 : if (!I.isStringAttribute())
822 1031358 : AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum();
823 : }
824 984857 : }
825 :
826 14400417 : void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
827 14400417 : Profile(ID, makeArrayRef(begin(), end()));
828 14400417 : }
829 :
830 23586683 : void AttributeListImpl::Profile(FoldingSetNodeID &ID,
831 : ArrayRef<AttributeSet> Sets) {
832 80882791 : for (const auto &Set : Sets)
833 57296108 : ID.AddPointer(Set.SetNode);
834 23586683 : }
835 :
836 : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
837 : LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
838 : AttributeList(const_cast<AttributeListImpl *>(this)).dump();
839 : }
840 : #endif
841 :
842 : //===----------------------------------------------------------------------===//
843 : // AttributeList Construction and Mutation Methods
844 : //===----------------------------------------------------------------------===//
845 :
846 9186266 : AttributeList AttributeList::getImpl(LLVMContext &C,
847 : ArrayRef<AttributeSet> AttrSets) {
848 : assert(!AttrSets.empty() && "pointless AttributeListImpl");
849 :
850 9186266 : LLVMContextImpl *pImpl = C.pImpl;
851 : FoldingSetNodeID ID;
852 9186266 : AttributeListImpl::Profile(ID, AttrSets);
853 :
854 : void *InsertPoint;
855 : AttributeListImpl *PA =
856 : pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
857 :
858 : // If we didn't find any existing attributes of the same shape then
859 : // create a new one and insert it.
860 9186266 : if (!PA) {
861 : // Coallocate entries after the AttributeListImpl itself.
862 984857 : void *Mem = ::operator new(
863 : AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
864 984857 : PA = new (Mem) AttributeListImpl(C, AttrSets);
865 984857 : pImpl->AttrsLists.InsertNode(PA, InsertPoint);
866 : }
867 :
868 : // Return the AttributesList that we found or created.
869 9186266 : return AttributeList(PA);
870 : }
871 :
872 : AttributeList
873 2358140 : AttributeList::get(LLVMContext &C,
874 : ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
875 : // If there are no attributes then return a null AttributesList pointer.
876 2358140 : if (Attrs.empty())
877 2078682 : return {};
878 :
879 : assert(std::is_sorted(Attrs.begin(), Attrs.end(),
880 : [](const std::pair<unsigned, Attribute> &LHS,
881 : const std::pair<unsigned, Attribute> &RHS) {
882 : return LHS.first < RHS.first;
883 : }) && "Misordered Attributes list!");
884 : assert(llvm::none_of(Attrs,
885 : [](const std::pair<unsigned, Attribute> &Pair) {
886 : return Pair.second.hasAttribute(Attribute::None);
887 : }) &&
888 : "Pointless attribute!");
889 :
890 : // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
891 : // list.
892 : SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
893 279459 : for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
894 558917 : E = Attrs.end(); I != E; ) {
895 279459 : unsigned Index = I->first;
896 : SmallVector<Attribute, 4> AttrVec;
897 739327 : while (I != E && I->first == Index) {
898 459868 : AttrVec.push_back(I->second);
899 459868 : ++I;
900 : }
901 :
902 279459 : AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
903 : }
904 :
905 279458 : return get(C, AttrPairVec);
906 : }
907 :
908 : AttributeList
909 773444 : AttributeList::get(LLVMContext &C,
910 : ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
911 : // If there are no attributes then return a null AttributesList pointer.
912 773444 : if (Attrs.empty())
913 0 : return {};
914 :
915 : assert(std::is_sorted(Attrs.begin(), Attrs.end(),
916 : [](const std::pair<unsigned, AttributeSet> &LHS,
917 : const std::pair<unsigned, AttributeSet> &RHS) {
918 : return LHS.first < RHS.first;
919 : }) &&
920 : "Misordered Attributes list!");
921 : assert(llvm::none_of(Attrs,
922 : [](const std::pair<unsigned, AttributeSet> &Pair) {
923 : return !Pair.second.hasAttributes();
924 : }) &&
925 : "Pointless attribute!");
926 :
927 773444 : unsigned MaxIndex = Attrs.back().first;
928 : // If the MaxIndex is FunctionIndex and there are other indices in front
929 : // of it, we need to use the largest of those to get the right size.
930 773444 : if (MaxIndex == FunctionIndex && Attrs.size() > 1)
931 2 : MaxIndex = Attrs[Attrs.size() - 2].first;
932 :
933 911132 : SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
934 1546889 : for (const auto Pair : Attrs)
935 1546890 : AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
936 :
937 773444 : return getImpl(C, AttrVec);
938 : }
939 :
940 4104487 : AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
941 : AttributeSet RetAttrs,
942 : ArrayRef<AttributeSet> ArgAttrs) {
943 : // Scan from the end to find the last argument with attributes. Most
944 : // arguments don't have attributes, so it's nice if we can have fewer unique
945 : // AttributeListImpls by dropping empty attribute sets at the end of the list.
946 : unsigned NumSets = 0;
947 9510285 : for (size_t I = ArgAttrs.size(); I != 0; --I) {
948 12711348 : if (ArgAttrs[I - 1].hasAttributes()) {
949 949876 : NumSets = I + 2;
950 949876 : break;
951 : }
952 : }
953 4104487 : if (NumSets == 0) {
954 : // Check function and return attributes if we didn't have argument
955 : // attributes.
956 3154611 : if (RetAttrs.hasAttributes())
957 : NumSets = 2;
958 2673504 : else if (FnAttrs.hasAttributes())
959 : NumSets = 1;
960 : }
961 :
962 : // If all attribute sets were empty, we can use the empty attribute list.
963 2079415 : if (NumSets == 0)
964 1129539 : return {};
965 :
966 : SmallVector<AttributeSet, 8> AttrSets;
967 2974948 : AttrSets.reserve(NumSets);
968 : // If we have any attributes, we always have function attributes.
969 2974948 : AttrSets.push_back(FnAttrs);
970 2974948 : if (NumSets > 1)
971 1430983 : AttrSets.push_back(RetAttrs);
972 2974948 : if (NumSets > 2) {
973 : // Drop the empty argument attribute sets at the end.
974 949876 : ArgAttrs = ArgAttrs.take_front(NumSets - 2);
975 949876 : AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
976 : }
977 :
978 2974948 : return getImpl(C, AttrSets);
979 : }
980 :
981 6512 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
982 : const AttrBuilder &B) {
983 6512 : if (!B.hasAttributes())
984 38 : return {};
985 : Index = attrIdxToArrayIdx(Index);
986 6474 : SmallVector<AttributeSet, 8> AttrSets(Index + 1);
987 12948 : AttrSets[Index] = AttributeSet::get(C, B);
988 6474 : return getImpl(C, AttrSets);
989 : }
990 :
991 2358139 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
992 : ArrayRef<Attribute::AttrKind> Kinds) {
993 : SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
994 2818005 : for (const auto K : Kinds)
995 459866 : Attrs.emplace_back(Index, Attribute::get(C, K));
996 2358139 : return get(C, Attrs);
997 : }
998 :
999 0 : AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1000 : ArrayRef<StringRef> Kinds) {
1001 : SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1002 0 : for (const auto K : Kinds)
1003 0 : Attrs.emplace_back(Index, Attribute::get(C, K));
1004 0 : return get(C, Attrs);
1005 : }
1006 :
1007 156332 : AttributeList AttributeList::get(LLVMContext &C,
1008 : ArrayRef<AttributeList> Attrs) {
1009 156332 : if (Attrs.empty())
1010 0 : return {};
1011 156332 : if (Attrs.size() == 1)
1012 138442 : return Attrs[0];
1013 :
1014 17890 : unsigned MaxSize = 0;
1015 62487 : for (const auto List : Attrs)
1016 72920 : MaxSize = std::max(MaxSize, List.getNumAttrSets());
1017 :
1018 : // If every list was empty, there is no point in merging the lists.
1019 17890 : if (MaxSize == 0)
1020 1 : return {};
1021 :
1022 17889 : SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1023 87997 : for (unsigned I = 0; I < MaxSize; ++I) {
1024 : AttrBuilder CurBuilder;
1025 251327 : for (const auto List : Attrs)
1026 362438 : CurBuilder.merge(List.getAttributes(I - 1));
1027 140216 : NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1028 : }
1029 :
1030 17889 : return getImpl(C, NewAttrSets);
1031 : }
1032 :
1033 1184656 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1034 : Attribute::AttrKind Kind) const {
1035 1184656 : if (hasAttribute(Index, Kind)) return *this;
1036 : AttrBuilder B;
1037 808649 : B.addAttribute(Kind);
1038 808649 : return addAttributes(C, Index, B);
1039 : }
1040 :
1041 40 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1042 : StringRef Kind,
1043 : StringRef Value) const {
1044 : AttrBuilder B;
1045 40 : B.addAttribute(Kind, Value);
1046 40 : return addAttributes(C, Index, B);
1047 : }
1048 :
1049 890863 : AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1050 : Attribute A) const {
1051 : AttrBuilder B;
1052 890863 : B.addAttribute(A);
1053 890863 : return addAttributes(C, Index, B);
1054 : }
1055 :
1056 4133478 : AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
1057 : const AttrBuilder &B) const {
1058 4133478 : if (!B.hasAttributes())
1059 468364 : return *this;
1060 :
1061 3665114 : if (!pImpl)
1062 493962 : return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1063 :
1064 : #ifndef NDEBUG
1065 : // FIXME it is not obvious how this should work for alignment. For now, say
1066 : // we can't change a known alignment.
1067 : unsigned OldAlign = getAttributes(Index).getAlignment();
1068 : unsigned NewAlign = B.getAlignment();
1069 : assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1070 : "Attempt to change alignment!");
1071 : #endif
1072 :
1073 : Index = attrIdxToArrayIdx(Index);
1074 3171152 : SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1075 3171152 : if (Index >= AttrSets.size())
1076 22659 : AttrSets.resize(Index + 1);
1077 :
1078 3171152 : AttrBuilder Merged(AttrSets[Index]);
1079 3171152 : Merged.merge(B);
1080 3171152 : AttrSets[Index] = AttributeSet::get(C, Merged);
1081 :
1082 3171152 : return getImpl(C, AttrSets);
1083 : }
1084 :
1085 554633 : AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1086 : ArrayRef<unsigned> ArgNos,
1087 : Attribute A) const {
1088 : assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
1089 :
1090 554633 : SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1091 554633 : unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1092 554633 : if (MaxIndex >= AttrSets.size())
1093 500446 : AttrSets.resize(MaxIndex + 1);
1094 :
1095 1135124 : for (unsigned ArgNo : ArgNos) {
1096 : unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1097 1160982 : AttrBuilder B(AttrSets[Index]);
1098 580491 : B.addAttribute(A);
1099 580491 : AttrSets[Index] = AttributeSet::get(C, B);
1100 : }
1101 :
1102 554633 : return getImpl(C, AttrSets);
1103 : }
1104 :
1105 931590 : AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1106 : Attribute::AttrKind Kind) const {
1107 931590 : if (!hasAttribute(Index, Kind)) return *this;
1108 :
1109 : Index = attrIdxToArrayIdx(Index);
1110 15708 : SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1111 : assert(Index < AttrSets.size());
1112 :
1113 31416 : AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1114 :
1115 15708 : return getImpl(C, AttrSets);
1116 : }
1117 :
1118 1622148 : AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1119 : StringRef Kind) const {
1120 1622148 : if (!hasAttribute(Index, Kind)) return *this;
1121 :
1122 : Index = attrIdxToArrayIdx(Index);
1123 1527520 : SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1124 : assert(Index < AttrSets.size());
1125 :
1126 3055040 : AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1127 :
1128 1527520 : return getImpl(C, AttrSets);
1129 : }
1130 :
1131 : AttributeList
1132 27860 : AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
1133 : const AttrBuilder &AttrsToRemove) const {
1134 27860 : if (!pImpl)
1135 254 : return {};
1136 :
1137 : Index = attrIdxToArrayIdx(Index);
1138 27606 : SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1139 27606 : if (Index >= AttrSets.size())
1140 101 : AttrSets.resize(Index + 1);
1141 :
1142 27606 : AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
1143 :
1144 27606 : return getImpl(C, AttrSets);
1145 : }
1146 :
1147 479239 : AttributeList AttributeList::removeAttributes(LLVMContext &C,
1148 : unsigned WithoutIndex) const {
1149 479239 : if (!pImpl)
1150 362347 : return {};
1151 : WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1152 116892 : if (WithoutIndex >= getNumAttrSets())
1153 0 : return *this;
1154 116892 : SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1155 233784 : AttrSets[WithoutIndex] = AttributeSet();
1156 116892 : return getImpl(C, AttrSets);
1157 : }
1158 :
1159 66 : AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
1160 : unsigned Index,
1161 : uint64_t Bytes) const {
1162 : AttrBuilder B;
1163 66 : B.addDereferenceableAttr(Bytes);
1164 66 : return addAttributes(C, Index, B);
1165 : }
1166 :
1167 : AttributeList
1168 0 : AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
1169 : uint64_t Bytes) const {
1170 : AttrBuilder B;
1171 0 : B.addDereferenceableOrNullAttr(Bytes);
1172 0 : return addAttributes(C, Index, B);
1173 : }
1174 :
1175 : AttributeList
1176 0 : AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
1177 : unsigned ElemSizeArg,
1178 : const Optional<unsigned> &NumElemsArg) {
1179 : AttrBuilder B;
1180 0 : B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1181 0 : return addAttributes(C, Index, B);
1182 : }
1183 :
1184 : //===----------------------------------------------------------------------===//
1185 : // AttributeList Accessor Methods
1186 : //===----------------------------------------------------------------------===//
1187 :
1188 10 : LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
1189 :
1190 2557897 : AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
1191 2557897 : return getAttributes(ArgNo + FirstArgIndex);
1192 : }
1193 :
1194 990126 : AttributeSet AttributeList::getRetAttributes() const {
1195 990126 : return getAttributes(ReturnIndex);
1196 : }
1197 :
1198 2297206 : AttributeSet AttributeList::getFnAttributes() const {
1199 2297206 : return getAttributes(FunctionIndex);
1200 : }
1201 :
1202 558957243 : bool AttributeList::hasAttribute(unsigned Index,
1203 : Attribute::AttrKind Kind) const {
1204 558957243 : return getAttributes(Index).hasAttribute(Kind);
1205 : }
1206 :
1207 108525379 : bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
1208 108525379 : return getAttributes(Index).hasAttribute(Kind);
1209 : }
1210 :
1211 2983813 : bool AttributeList::hasAttributes(unsigned Index) const {
1212 2983813 : return getAttributes(Index).hasAttributes();
1213 : }
1214 :
1215 244532811 : bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
1216 244532811 : return pImpl && pImpl->hasFnAttribute(Kind);
1217 : }
1218 :
1219 103619061 : bool AttributeList::hasFnAttribute(StringRef Kind) const {
1220 103619061 : return hasAttribute(AttributeList::FunctionIndex, Kind);
1221 : }
1222 :
1223 145792235 : bool AttributeList::hasParamAttribute(unsigned ArgNo,
1224 : Attribute::AttrKind Kind) const {
1225 145792235 : return hasAttribute(ArgNo + FirstArgIndex, Kind);
1226 : }
1227 :
1228 10783288 : bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1229 : unsigned *Index) const {
1230 10783288 : if (!pImpl) return false;
1231 :
1232 27949485 : for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
1233 17947932 : if (hasAttribute(I, Attr)) {
1234 4131 : if (Index)
1235 798 : *Index = I;
1236 4131 : return true;
1237 : }
1238 : }
1239 :
1240 : return false;
1241 : }
1242 :
1243 4027887 : Attribute AttributeList::getAttribute(unsigned Index,
1244 : Attribute::AttrKind Kind) const {
1245 4027887 : return getAttributes(Index).getAttribute(Kind);
1246 : }
1247 :
1248 104918841 : Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
1249 104918841 : return getAttributes(Index).getAttribute(Kind);
1250 : }
1251 :
1252 287070 : unsigned AttributeList::getRetAlignment() const {
1253 287070 : return getAttributes(ReturnIndex).getAlignment();
1254 : }
1255 :
1256 8402711 : unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
1257 8402711 : return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1258 : }
1259 :
1260 65 : unsigned AttributeList::getStackAlignment(unsigned Index) const {
1261 65 : return getAttributes(Index).getStackAlignment();
1262 : }
1263 :
1264 2104783 : uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
1265 2104783 : return getAttributes(Index).getDereferenceableBytes();
1266 : }
1267 :
1268 112033 : uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
1269 112033 : return getAttributes(Index).getDereferenceableOrNullBytes();
1270 : }
1271 :
1272 : std::pair<unsigned, Optional<unsigned>>
1273 83 : AttributeList::getAllocSizeArgs(unsigned Index) const {
1274 83 : return getAttributes(Index).getAllocSizeArgs();
1275 : }
1276 :
1277 9237 : std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1278 9237 : return getAttributes(Index).getAsString(InAttrGrp);
1279 : }
1280 :
1281 796415239 : AttributeSet AttributeList::getAttributes(unsigned Index) const {
1282 : Index = attrIdxToArrayIdx(Index);
1283 796415239 : if (!pImpl || Index >= getNumAttrSets())
1284 164392373 : return {};
1285 632022868 : return pImpl->begin()[Index];
1286 : }
1287 :
1288 5413511 : AttributeList::iterator AttributeList::begin() const {
1289 5413511 : return pImpl ? pImpl->begin() : nullptr;
1290 : }
1291 :
1292 5413511 : AttributeList::iterator AttributeList::end() const {
1293 5413511 : return pImpl ? pImpl->end() : nullptr;
1294 : }
1295 :
1296 : //===----------------------------------------------------------------------===//
1297 : // AttributeList Introspection Methods
1298 : //===----------------------------------------------------------------------===//
1299 :
1300 742486862 : unsigned AttributeList::getNumAttrSets() const {
1301 742486862 : return pImpl ? pImpl->NumAttrSets : 0;
1302 : }
1303 :
1304 : #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1305 : LLVM_DUMP_METHOD void AttributeList::dump() const {
1306 : dbgs() << "PAL[\n";
1307 :
1308 : for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
1309 : if (getAttributes(i).hasAttributes())
1310 : dbgs() << " { " << i << " => " << getAsString(i) << " }\n";
1311 : }
1312 :
1313 : dbgs() << "]\n";
1314 : }
1315 : #endif
1316 :
1317 : //===----------------------------------------------------------------------===//
1318 : // AttrBuilder Method Implementations
1319 : //===----------------------------------------------------------------------===//
1320 :
1321 : // FIXME: Remove this ctor, use AttributeSet.
1322 14440 : AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
1323 14440 : AttributeSet AS = AL.getAttributes(Index);
1324 16496 : for (const auto &A : AS)
1325 2056 : addAttribute(A);
1326 14440 : }
1327 :
1328 6739923 : AttrBuilder::AttrBuilder(AttributeSet AS) {
1329 70850292 : for (const auto &A : AS)
1330 64110369 : addAttribute(A);
1331 6739923 : }
1332 :
1333 1871957 : void AttrBuilder::clear() {
1334 : Attrs.reset();
1335 : TargetDepAttrs.clear();
1336 1871957 : Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
1337 1871957 : AllocSizeArgs = 0;
1338 1871957 : }
1339 :
1340 10858973 : AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
1341 : assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1342 : assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
1343 : Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
1344 : "Adding integer attribute without adding a value!");
1345 : Attrs[Val] = true;
1346 10858973 : return *this;
1347 : }
1348 :
1349 65583881 : AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1350 65583881 : if (Attr.isStringAttribute()) {
1351 60979581 : addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1352 60979581 : return *this;
1353 : }
1354 :
1355 4604300 : Attribute::AttrKind Kind = Attr.getKindAsEnum();
1356 : Attrs[Kind] = true;
1357 :
1358 4604300 : if (Kind == Attribute::Alignment)
1359 451412 : Alignment = Attr.getAlignment();
1360 4152888 : else if (Kind == Attribute::StackAlignment)
1361 119 : StackAlignment = Attr.getStackAlignment();
1362 4152769 : else if (Kind == Attribute::Dereferenceable)
1363 103684 : DerefBytes = Attr.getDereferenceableBytes();
1364 4049085 : else if (Kind == Attribute::DereferenceableOrNull)
1365 122 : DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
1366 4048963 : else if (Kind == Attribute::AllocSize)
1367 44 : AllocSizeArgs = Attr.getValueAsInt();
1368 : return *this;
1369 : }
1370 :
1371 76370516 : AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1372 152741032 : TargetDepAttrs[A] = V;
1373 76370516 : return *this;
1374 : }
1375 :
1376 351111 : AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1377 : assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1378 : Attrs[Val] = false;
1379 :
1380 351111 : if (Val == Attribute::Alignment)
1381 14666 : Alignment = 0;
1382 336445 : else if (Val == Attribute::StackAlignment)
1383 1 : StackAlignment = 0;
1384 336444 : else if (Val == Attribute::Dereferenceable)
1385 0 : DerefBytes = 0;
1386 336444 : else if (Val == Attribute::DereferenceableOrNull)
1387 0 : DerefOrNullBytes = 0;
1388 336444 : else if (Val == Attribute::AllocSize)
1389 2 : AllocSizeArgs = 0;
1390 :
1391 351111 : return *this;
1392 : }
1393 :
1394 0 : AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
1395 0 : remove(A.getAttributes(Index));
1396 0 : return *this;
1397 : }
1398 :
1399 1527520 : AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1400 1527520 : auto I = TargetDepAttrs.find(A);
1401 1527520 : if (I != TargetDepAttrs.end())
1402 : TargetDepAttrs.erase(I);
1403 1527520 : return *this;
1404 : }
1405 :
1406 113 : std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1407 113 : return unpackAllocSizeArgs(AllocSizeArgs);
1408 : }
1409 :
1410 12995 : AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
1411 12995 : if (Align == 0) return *this;
1412 :
1413 : assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1414 : assert(Align <= 0x40000000 && "Alignment too large.");
1415 :
1416 : Attrs[Attribute::Alignment] = true;
1417 12995 : Alignment = Align;
1418 12995 : return *this;
1419 : }
1420 :
1421 87 : AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
1422 : // Default alignment, allow the target to define how to align it.
1423 87 : if (Align == 0) return *this;
1424 :
1425 : assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1426 : assert(Align <= 0x100 && "Alignment too large.");
1427 :
1428 : Attrs[Attribute::StackAlignment] = true;
1429 87 : StackAlignment = Align;
1430 87 : return *this;
1431 : }
1432 :
1433 1753004 : AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1434 1753004 : if (Bytes == 0) return *this;
1435 :
1436 : Attrs[Attribute::Dereferenceable] = true;
1437 1751121 : DerefBytes = Bytes;
1438 1751121 : return *this;
1439 : }
1440 :
1441 115527 : AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1442 115527 : if (Bytes == 0)
1443 : return *this;
1444 :
1445 : Attrs[Attribute::DereferenceableOrNull] = true;
1446 115527 : DerefOrNullBytes = Bytes;
1447 115527 : return *this;
1448 : }
1449 :
1450 58 : AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1451 : const Optional<unsigned> &NumElems) {
1452 58 : return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1453 : }
1454 :
1455 68 : AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1456 : // (0, 0) is our "not present" value, so we need to check for it here.
1457 : assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1458 :
1459 : Attrs[Attribute::AllocSize] = true;
1460 : // Reuse existing machinery to store this as a single 64-bit integer so we can
1461 : // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1462 68 : AllocSizeArgs = RawArgs;
1463 68 : return *this;
1464 : }
1465 :
1466 3890886 : AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1467 : // FIXME: What if both have alignments, but they don't match?!
1468 3890886 : if (!Alignment)
1469 3890426 : Alignment = B.Alignment;
1470 :
1471 3890886 : if (!StackAlignment)
1472 3890819 : StackAlignment = B.StackAlignment;
1473 :
1474 3890886 : if (!DerefBytes)
1475 3873420 : DerefBytes = B.DerefBytes;
1476 :
1477 3890886 : if (!DerefOrNullBytes)
1478 3890881 : DerefOrNullBytes = B.DerefOrNullBytes;
1479 :
1480 3890886 : if (!AllocSizeArgs)
1481 3890872 : AllocSizeArgs = B.AllocSizeArgs;
1482 :
1483 : Attrs |= B.Attrs;
1484 :
1485 9477840 : for (auto I : B.td_attrs())
1486 2793477 : TargetDepAttrs[I.first] = I.second;
1487 :
1488 3890886 : return *this;
1489 : }
1490 :
1491 31710 : AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1492 : // FIXME: What if both have alignments, but they don't match?!
1493 31710 : if (B.Alignment)
1494 2 : Alignment = 0;
1495 :
1496 31710 : if (B.StackAlignment)
1497 1 : StackAlignment = 0;
1498 :
1499 31710 : if (B.DerefBytes)
1500 4102 : DerefBytes = 0;
1501 :
1502 31710 : if (B.DerefOrNullBytes)
1503 4098 : DerefOrNullBytes = 0;
1504 :
1505 31710 : if (B.AllocSizeArgs)
1506 0 : AllocSizeArgs = 0;
1507 :
1508 : Attrs &= ~B.Attrs;
1509 :
1510 31774 : for (auto I : B.td_attrs())
1511 : TargetDepAttrs.erase(I.first);
1512 :
1513 31710 : return *this;
1514 : }
1515 :
1516 273188 : bool AttrBuilder::overlaps(const AttrBuilder &B) const {
1517 : // First check if any of the target independent attributes overlap.
1518 273188 : if ((Attrs & B.Attrs).any())
1519 : return true;
1520 :
1521 : // Then check if any target dependent ones do.
1522 273249 : for (const auto &I : td_attrs())
1523 66 : if (B.contains(I.first))
1524 : return true;
1525 :
1526 : return false;
1527 : }
1528 :
1529 66 : bool AttrBuilder::contains(StringRef A) const {
1530 66 : return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1531 : }
1532 :
1533 10574744 : bool AttrBuilder::hasAttributes() const {
1534 10574744 : return !Attrs.none() || !TargetDepAttrs.empty();
1535 : }
1536 :
1537 0 : bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const {
1538 0 : AttributeSet AS = AL.getAttributes(Index);
1539 :
1540 0 : for (const auto Attr : AS) {
1541 0 : if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
1542 0 : if (contains(Attr.getKindAsEnum()))
1543 0 : return true;
1544 : } else {
1545 : assert(Attr.isStringAttribute() && "Invalid attribute kind!");
1546 0 : return contains(Attr.getKindAsString());
1547 : }
1548 : }
1549 :
1550 0 : return false;
1551 : }
1552 :
1553 802553 : bool AttrBuilder::hasAlignmentAttr() const {
1554 802553 : return Alignment != 0;
1555 : }
1556 :
1557 3497 : bool AttrBuilder::operator==(const AttrBuilder &B) {
1558 3497 : if (Attrs != B.Attrs)
1559 : return false;
1560 :
1561 : for (td_const_iterator I = TargetDepAttrs.begin(),
1562 3420 : E = TargetDepAttrs.end(); I != E; ++I)
1563 0 : if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1564 : return false;
1565 :
1566 3420 : return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
1567 3419 : DerefBytes == B.DerefBytes;
1568 : }
1569 :
1570 : //===----------------------------------------------------------------------===//
1571 : // AttributeFuncs Function Defintions
1572 : //===----------------------------------------------------------------------===//
1573 :
1574 : /// Which attributes cannot be applied to a type.
1575 277480 : AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
1576 : AttrBuilder Incompatible;
1577 :
1578 277480 : if (!Ty->isIntegerTy())
1579 : // Attribute that only apply to integers.
1580 172083 : Incompatible.addAttribute(Attribute::SExt)
1581 172083 : .addAttribute(Attribute::ZExt);
1582 :
1583 277480 : if (!Ty->isPointerTy())
1584 : // Attribute that only apply to pointers.
1585 115435 : Incompatible.addAttribute(Attribute::ByVal)
1586 115435 : .addAttribute(Attribute::Nest)
1587 115435 : .addAttribute(Attribute::NoAlias)
1588 115435 : .addAttribute(Attribute::NoCapture)
1589 115435 : .addAttribute(Attribute::NonNull)
1590 115435 : .addDereferenceableAttr(1) // the int here is ignored
1591 115435 : .addDereferenceableOrNullAttr(1) // the int here is ignored
1592 115435 : .addAttribute(Attribute::ReadNone)
1593 115435 : .addAttribute(Attribute::ReadOnly)
1594 115435 : .addAttribute(Attribute::StructRet)
1595 115435 : .addAttribute(Attribute::InAlloca);
1596 :
1597 277480 : return Incompatible;
1598 : }
1599 :
1600 : template<typename AttrClass>
1601 2008752 : static bool isEqual(const Function &Caller, const Function &Callee) {
1602 : return Caller.getFnAttribute(AttrClass::getKind()) ==
1603 2008752 : Callee.getFnAttribute(AttrClass::getKind());
1604 : }
1605 334792 :
1606 : /// Compute the logical AND of the attributes of the caller and the
1607 334792 : /// callee.
1608 : ///
1609 334792 : /// This function sets the caller's attribute to false if the callee's attribute
1610 : /// is false.
1611 334792 : template<typename AttrClass>
1612 : static void setAND(Function &Caller, const Function &Callee) {
1613 334792 : if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1614 : !AttrClass::isSet(Callee, AttrClass::getKind()))
1615 334792 : AttrClass::set(Caller, AttrClass::getKind(), false);
1616 : }
1617 334792 :
1618 : /// Compute the logical OR of the attributes of the caller and the
1619 334792 : /// callee.
1620 : ///
1621 334792 : /// This function sets the caller's attribute to true if the callee's attribute
1622 : /// is true.
1623 334792 : template<typename AttrClass>
1624 : static void setOR(Function &Caller, const Function &Callee) {
1625 334792 : if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1626 : AttrClass::isSet(Callee, AttrClass::getKind()))
1627 334792 : AttrClass::set(Caller, AttrClass::getKind(), true);
1628 : }
1629 :
1630 : /// If the inlined function had a higher stack protection level than the
1631 : /// calling function, then bump up the caller's stack protection level.
1632 : static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1633 : // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1634 : // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1635 : // clutter to the IR.
1636 5596516 : AttrBuilder OldSSPAttr;
1637 5596532 : OldSSPAttr.addAttribute(Attribute::StackProtect)
1638 16 : .addAttribute(Attribute::StackProtectStrong)
1639 8 : .addAttribute(Attribute::StackProtectReq);
1640 5596516 :
1641 1399129 : if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
1642 1399132 : Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1643 3 : Caller.addFnAttr(Attribute::StackProtectReq);
1644 2 : } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
1645 1399129 : !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
1646 1399129 : Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
1647 1399132 : Caller.addFnAttr(Attribute::StackProtectStrong);
1648 3 : } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
1649 1 : !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1650 1399129 : !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1651 1399129 : Caller.addFnAttr(Attribute::StackProtect);
1652 1399132 : }
1653 3 :
1654 1 : /// If the inlined function required stack probes, then ensure that
1655 1399129 : /// the calling function has those too.
1656 1399129 : static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
1657 1399136 : if (!Caller.hasFnAttribute("probe-stack") &&
1658 7 : Callee.hasFnAttribute("probe-stack")) {
1659 4 : Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
1660 1399129 : }
1661 : }
1662 :
1663 : /// If the inlined function defines the size of guard region
1664 : /// on the stack, then ensure that the calling function defines a guard region
1665 : /// that is no larger.
1666 : static void
1667 : adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
1668 5596516 : if (Callee.hasFnAttribute("stack-probe-size")) {
1669 11193021 : uint64_t CalleeStackProbeSize;
1670 2798254 : Callee.getFnAttribute("stack-probe-size")
1671 2 : .getValueAsString()
1672 5596516 : .getAsInteger(0, CalleeStackProbeSize);
1673 1399129 : if (Caller.hasFnAttribute("stack-probe-size")) {
1674 2798256 : uint64_t CallerStackProbeSize;
1675 : Caller.getFnAttribute("stack-probe-size")
1676 : .getValueAsString()
1677 1399129 : .getAsInteger(0, CallerStackProbeSize);
1678 1399129 : if (CallerStackProbeSize > CalleeStackProbeSize) {
1679 2798258 : Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1680 1399129 : }
1681 0 : } else {
1682 1399129 : Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1683 1399129 : }
1684 2798254 : }
1685 1399125 : }
1686 2 :
1687 1399129 : /// If the inlined function defines a min legal vector width, then ensure
1688 1399129 : /// the calling function has the same or larger min legal vector width. This
1689 2798253 : /// function is called after the inlining decision has been made so we have to
1690 : /// merge the attribute this way. Heuristics that would use
1691 : /// min-legal-vector-width to determine inline compatibility would need to be
1692 1399129 : /// handled as part of inline cost analysis.
1693 : static void
1694 : adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
1695 : if (Callee.hasFnAttribute("min-legal-vector-width")) {
1696 1399129 : uint64_t CalleeVectorWidth;
1697 : Callee.getFnAttribute("min-legal-vector-width")
1698 : .getValueAsString()
1699 : .getAsInteger(0, CalleeVectorWidth);
1700 : if (Caller.hasFnAttribute("min-legal-vector-width")) {
1701 1399129 : uint64_t CallerVectorWidth;
1702 1399129 : Caller.getFnAttribute("min-legal-vector-width")
1703 1399129 : .getValueAsString()
1704 : .getAsInteger(0, CallerVectorWidth);
1705 1399129 : if (CallerVectorWidth < CalleeVectorWidth) {
1706 8 : Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
1707 : }
1708 1426076 : } else {
1709 : Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
1710 26953 : }
1711 : }
1712 87 : }
1713 1372253 :
1714 : /// If the inlined function has "null-pointer-is-valid=true" attribute,
1715 : /// set this attribute in the caller post inlining.
1716 1399129 : static void
1717 : adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
1718 : if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
1719 : Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid"));
1720 1399129 : }
1721 1399129 : }
1722 1399128 :
1723 1 : #define GET_ATTR_COMPAT_FUNC
1724 : #include "AttributesCompatFunc.inc"
1725 1399129 :
1726 : bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1727 : const Function &Callee) {
1728 : return hasCompatibleFnAttrs(Caller, Callee);
1729 : }
1730 :
1731 1399129 : void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
1732 1399129 : const Function &Callee) {
1733 : mergeFnAttrs(Caller, Callee);
1734 6 : }
|