Coverage Report

Created: 2024-01-17 10:31

/src/llvm-project/llvm/lib/IR/Attributes.cpp
Line
Count
Source (jump to first uncovered line)
1
//===- Attributes.cpp - Implement AttributesList --------------------------===//
2
//
3
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4
// See https://llvm.org/LICENSE.txt for license information.
5
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6
//
7
//===----------------------------------------------------------------------===//
8
//
9
// \file
10
// This file implements the Attribute, AttributeImpl, AttrBuilder,
11
// AttributeListImpl, and AttributeList classes.
12
//
13
//===----------------------------------------------------------------------===//
14
15
#include "llvm/IR/Attributes.h"
16
#include "AttributeImpl.h"
17
#include "LLVMContextImpl.h"
18
#include "llvm/ADT/ArrayRef.h"
19
#include "llvm/ADT/FoldingSet.h"
20
#include "llvm/ADT/STLExtras.h"
21
#include "llvm/ADT/SmallVector.h"
22
#include "llvm/ADT/StringExtras.h"
23
#include "llvm/ADT/StringRef.h"
24
#include "llvm/ADT/StringSwitch.h"
25
#include "llvm/Config/llvm-config.h"
26
#include "llvm/IR/AttributeMask.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/ErrorHandling.h"
32
#include "llvm/Support/ModRef.h"
33
#include "llvm/Support/raw_ostream.h"
34
#include <algorithm>
35
#include <cassert>
36
#include <cstddef>
37
#include <cstdint>
38
#include <limits>
39
#include <optional>
40
#include <string>
41
#include <tuple>
42
#include <utility>
43
44
using namespace llvm;
45
46
//===----------------------------------------------------------------------===//
47
// Attribute Construction Methods
48
//===----------------------------------------------------------------------===//
49
50
// allocsize has two integer arguments, but because they're both 32 bits, we can
51
// pack them into one 64-bit value, at the cost of making said value
52
// nonsensical.
53
//
54
// In order to do this, we need to reserve one value of the second (optional)
55
// allocsize argument to signify "not present."
56
static const unsigned AllocSizeNumElemsNotPresent = -1;
57
58
static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
59
6
                                  const std::optional<unsigned> &NumElemsArg) {
60
6
  assert((!NumElemsArg || *NumElemsArg != AllocSizeNumElemsNotPresent) &&
61
6
         "Attempting to pack a reserved value");
62
63
0
  return uint64_t(ElemSizeArg) << 32 |
64
6
         NumElemsArg.value_or(AllocSizeNumElemsNotPresent);
65
6
}
66
67
static std::pair<unsigned, std::optional<unsigned>>
68
2.33k
unpackAllocSizeArgs(uint64_t Num) {
69
2.33k
  unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
70
2.33k
  unsigned ElemSizeArg = Num >> 32;
71
72
2.33k
  std::optional<unsigned> NumElemsArg;
73
2.33k
  if (NumElems != AllocSizeNumElemsNotPresent)
74
877
    NumElemsArg = NumElems;
75
2.33k
  return std::make_pair(ElemSizeArg, NumElemsArg);
76
2.33k
}
77
78
static uint64_t packVScaleRangeArgs(unsigned MinValue,
79
0
                                    std::optional<unsigned> MaxValue) {
80
0
  return uint64_t(MinValue) << 32 | MaxValue.value_or(0);
81
0
}
82
83
static std::pair<unsigned, std::optional<unsigned>>
84
0
unpackVScaleRangeArgs(uint64_t Value) {
85
0
  unsigned MaxValue = Value & std::numeric_limits<unsigned>::max();
86
0
  unsigned MinValue = Value >> 32;
87
88
0
  return std::make_pair(MinValue,
89
0
                        MaxValue > 0 ? MaxValue : std::optional<unsigned>());
90
0
}
91
92
Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
93
4.22M
                         uint64_t Val) {
94
4.22M
  bool IsIntAttr = Attribute::isIntAttrKind(Kind);
95
4.22M
  assert((IsIntAttr || Attribute::isEnumAttrKind(Kind)) &&
96
4.22M
         "Not an enum or int attribute");
97
98
0
  LLVMContextImpl *pImpl = Context.pImpl;
99
4.22M
  FoldingSetNodeID ID;
100
4.22M
  ID.AddInteger(Kind);
101
4.22M
  if (IsIntAttr)
102
557k
    ID.AddInteger(Val);
103
3.66M
  else
104
3.66M
    assert(Val == 0 && "Value must be zero for enum attributes");
105
106
0
  void *InsertPoint;
107
4.22M
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
108
109
4.22M
  if (!PA) {
110
    // If we didn't find any existing attributes of the same shape then create a
111
    // new one and insert it.
112
290k
    if (!IsIntAttr)
113
245k
      PA = new (pImpl->Alloc) EnumAttributeImpl(Kind);
114
45.2k
    else
115
45.2k
      PA = new (pImpl->Alloc) IntAttributeImpl(Kind, Val);
116
290k
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
117
290k
  }
118
119
  // Return the Attribute that we found or created.
120
4.22M
  return Attribute(PA);
121
4.22M
}
122
123
396k
Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
124
396k
  LLVMContextImpl *pImpl = Context.pImpl;
125
396k
  FoldingSetNodeID ID;
126
396k
  ID.AddString(Kind);
127
396k
  if (!Val.empty()) ID.AddString(Val);
128
129
396k
  void *InsertPoint;
130
396k
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
131
132
396k
  if (!PA) {
133
    // If we didn't find any existing attributes of the same shape then create a
134
    // new one and insert it.
135
39.4k
    void *Mem =
136
39.4k
        pImpl->Alloc.Allocate(StringAttributeImpl::totalSizeToAlloc(Kind, Val),
137
39.4k
                              alignof(StringAttributeImpl));
138
39.4k
    PA = new (Mem) StringAttributeImpl(Kind, Val);
139
39.4k
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
140
39.4k
  }
141
142
  // Return the Attribute that we found or created.
143
396k
  return Attribute(PA);
144
396k
}
145
146
Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
147
1.86k
                         Type *Ty) {
148
1.86k
  assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
149
0
  LLVMContextImpl *pImpl = Context.pImpl;
150
1.86k
  FoldingSetNodeID ID;
151
1.86k
  ID.AddInteger(Kind);
152
1.86k
  ID.AddPointer(Ty);
153
154
1.86k
  void *InsertPoint;
155
1.86k
  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
156
157
1.86k
  if (!PA) {
158
    // If we didn't find any existing attributes of the same shape then create a
159
    // new one and insert it.
160
1.24k
    PA = new (pImpl->Alloc) TypeAttributeImpl(Kind, Ty);
161
1.24k
    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
162
1.24k
  }
163
164
  // Return the Attribute that we found or created.
165
1.86k
  return Attribute(PA);
166
1.86k
}
167
168
2.14k
Attribute Attribute::getWithAlignment(LLVMContext &Context, Align A) {
169
2.14k
  assert(A <= llvm::Value::MaximumAlignment && "Alignment too large.");
170
0
  return get(Context, Alignment, A.value());
171
2.14k
}
172
173
0
Attribute Attribute::getWithStackAlignment(LLVMContext &Context, Align A) {
174
0
  assert(A <= 0x100 && "Alignment too large.");
175
0
  return get(Context, StackAlignment, A.value());
176
0
}
177
178
Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
179
3.79k
                                                uint64_t Bytes) {
180
3.79k
  assert(Bytes && "Bytes must be non-zero.");
181
0
  return get(Context, Dereferenceable, Bytes);
182
3.79k
}
183
184
Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
185
738
                                                       uint64_t Bytes) {
186
738
  assert(Bytes && "Bytes must be non-zero.");
187
0
  return get(Context, DereferenceableOrNull, Bytes);
188
738
}
189
190
60
Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
191
60
  return get(Context, ByVal, Ty);
192
60
}
193
194
90
Attribute Attribute::getWithStructRetType(LLVMContext &Context, Type *Ty) {
195
90
  return get(Context, StructRet, Ty);
196
90
}
197
198
0
Attribute Attribute::getWithByRefType(LLVMContext &Context, Type *Ty) {
199
0
  return get(Context, ByRef, Ty);
200
0
}
201
202
0
Attribute Attribute::getWithPreallocatedType(LLVMContext &Context, Type *Ty) {
203
0
  return get(Context, Preallocated, Ty);
204
0
}
205
206
34
Attribute Attribute::getWithInAllocaType(LLVMContext &Context, Type *Ty) {
207
34
  return get(Context, InAlloca, Ty);
208
34
}
209
210
Attribute Attribute::getWithUWTableKind(LLVMContext &Context,
211
0
                                        UWTableKind Kind) {
212
0
  return get(Context, UWTable, uint64_t(Kind));
213
0
}
214
215
Attribute Attribute::getWithMemoryEffects(LLVMContext &Context,
216
511k
                                          MemoryEffects ME) {
217
511k
  return get(Context, Memory, ME.toIntValue());
218
511k
}
219
220
Attribute Attribute::getWithNoFPClass(LLVMContext &Context,
221
0
                                      FPClassTest ClassMask) {
222
0
  return get(Context, NoFPClass, ClassMask);
223
0
}
224
225
Attribute
226
Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
227
6
                                const std::optional<unsigned> &NumElemsArg) {
228
6
  assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
229
6
         "Invalid allocsize arguments -- given allocsize(0, 0)");
230
0
  return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
231
6
}
232
233
Attribute Attribute::getWithVScaleRangeArgs(LLVMContext &Context,
234
                                            unsigned MinValue,
235
0
                                            unsigned MaxValue) {
236
0
  return get(Context, VScaleRange, packVScaleRangeArgs(MinValue, MaxValue));
237
0
}
238
239
707
Attribute::AttrKind Attribute::getAttrKindFromName(StringRef AttrName) {
240
707
  return StringSwitch<Attribute::AttrKind>(AttrName)
241
707
#define GET_ATTR_NAMES
242
707
#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
243
62.2k
  .Case(#DISPLAY_NAME, Attribute::ENUM_NAME)
244
707
#include "llvm/IR/Attributes.inc"
245
707
      .Default(Attribute::None);
246
707
}
247
248
187
StringRef Attribute::getNameFromAttrKind(Attribute::AttrKind AttrKind) {
249
187
  switch (AttrKind) {
250
0
#define GET_ATTR_NAMES
251
0
#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
252
187
  case Attribute::ENUM_NAME:                                                   \
253
187
    return #DISPLAY_NAME;
254
0
#include "llvm/IR/Attributes.inc"
255
0
  case Attribute::None:
256
0
    return "none";
257
0
  default:
258
0
    llvm_unreachable("invalid Kind");
259
187
  }
260
187
}
261
262
586
bool Attribute::isExistingAttribute(StringRef Name) {
263
586
  return StringSwitch<bool>(Name)
264
586
#define GET_ATTR_NAMES
265
58.6k
#define ATTRIBUTE_ALL(ENUM_NAME, DISPLAY_NAME) .Case(#DISPLAY_NAME, true)
266
586
#include "llvm/IR/Attributes.inc"
267
586
      .Default(false);
268
586
}
269
270
//===----------------------------------------------------------------------===//
271
// Attribute Accessor Methods
272
//===----------------------------------------------------------------------===//
273
274
9.16M
bool Attribute::isEnumAttribute() const {
275
9.16M
  return pImpl && pImpl->isEnumAttribute();
276
9.16M
}
277
278
3.61M
bool Attribute::isIntAttribute() const {
279
3.61M
  return pImpl && pImpl->isIntAttribute();
280
3.61M
}
281
282
16.3M
bool Attribute::isStringAttribute() const {
283
16.3M
  return pImpl && pImpl->isStringAttribute();
284
16.3M
}
285
286
34.6k
bool Attribute::isTypeAttribute() const {
287
34.6k
  return pImpl && pImpl->isTypeAttribute();
288
34.6k
}
289
290
9.16M
Attribute::AttrKind Attribute::getKindAsEnum() const {
291
9.16M
  if (!pImpl) return None;
292
9.16M
  assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
293
9.16M
         "Invalid attribute type to get the kind as an enum!");
294
0
  return pImpl->getKindAsEnum();
295
9.16M
}
296
297
110
uint64_t Attribute::getValueAsInt() const {
298
110
  if (!pImpl) return 0;
299
110
  assert(isIntAttribute() &&
300
110
         "Expected the attribute to be an integer attribute!");
301
0
  return pImpl->getValueAsInt();
302
110
}
303
304
3.65M
bool Attribute::getValueAsBool() const {
305
3.65M
  if (!pImpl) return false;
306
18.1k
  assert(isStringAttribute() &&
307
18.1k
         "Expected the attribute to be a string attribute!");
308
0
  return pImpl->getValueAsBool();
309
3.65M
}
310
311
3.16M
StringRef Attribute::getKindAsString() const {
312
3.16M
  if (!pImpl) return {};
313
3.16M
  assert(isStringAttribute() &&
314
3.16M
         "Invalid attribute type to get the kind as a string!");
315
0
  return pImpl->getKindAsString();
316
3.16M
}
317
318
1.15M
StringRef Attribute::getValueAsString() const {
319
1.15M
  if (!pImpl) return {};
320
243k
  assert(isStringAttribute() &&
321
243k
         "Invalid attribute type to get the value as a string!");
322
0
  return pImpl->getValueAsString();
323
1.15M
}
324
325
8.22k
Type *Attribute::getValueAsType() const {
326
8.22k
  if (!pImpl) return {};
327
8.22k
  assert(isTypeAttribute() &&
328
8.22k
         "Invalid attribute type to get the value as a type!");
329
0
  return pImpl->getValueAsType();
330
8.22k
}
331
332
333
593k
bool Attribute::hasAttribute(AttrKind Kind) const {
334
593k
  return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
335
593k
}
336
337
339k
bool Attribute::hasAttribute(StringRef Kind) const {
338
339k
  if (!isStringAttribute()) return false;
339
339k
  return pImpl && pImpl->hasAttribute(Kind);
340
339k
}
341
342
28.8k
MaybeAlign Attribute::getAlignment() const {
343
28.8k
  assert(hasAttribute(Attribute::Alignment) &&
344
28.8k
         "Trying to get alignment from non-alignment attribute!");
345
0
  return MaybeAlign(pImpl->getValueAsInt());
346
28.8k
}
347
348
0
MaybeAlign Attribute::getStackAlignment() const {
349
0
  assert(hasAttribute(Attribute::StackAlignment) &&
350
0
         "Trying to get alignment from non-alignment attribute!");
351
0
  return MaybeAlign(pImpl->getValueAsInt());
352
0
}
353
354
9.57k
uint64_t Attribute::getDereferenceableBytes() const {
355
9.57k
  assert(hasAttribute(Attribute::Dereferenceable) &&
356
9.57k
         "Trying to get dereferenceable bytes from "
357
9.57k
         "non-dereferenceable attribute!");
358
0
  return pImpl->getValueAsInt();
359
9.57k
}
360
361
688
uint64_t Attribute::getDereferenceableOrNullBytes() const {
362
688
  assert(hasAttribute(Attribute::DereferenceableOrNull) &&
363
688
         "Trying to get dereferenceable bytes from "
364
688
         "non-dereferenceable attribute!");
365
0
  return pImpl->getValueAsInt();
366
688
}
367
368
std::pair<unsigned, std::optional<unsigned>>
369
2.33k
Attribute::getAllocSizeArgs() const {
370
2.33k
  assert(hasAttribute(Attribute::AllocSize) &&
371
2.33k
         "Trying to get allocsize args from non-allocsize attribute");
372
0
  return unpackAllocSizeArgs(pImpl->getValueAsInt());
373
2.33k
}
374
375
0
unsigned Attribute::getVScaleRangeMin() const {
376
0
  assert(hasAttribute(Attribute::VScaleRange) &&
377
0
         "Trying to get vscale args from non-vscale attribute");
378
0
  return unpackVScaleRangeArgs(pImpl->getValueAsInt()).first;
379
0
}
380
381
0
std::optional<unsigned> Attribute::getVScaleRangeMax() const {
382
0
  assert(hasAttribute(Attribute::VScaleRange) &&
383
0
         "Trying to get vscale args from non-vscale attribute");
384
0
  return unpackVScaleRangeArgs(pImpl->getValueAsInt()).second;
385
0
}
386
387
31.6k
UWTableKind Attribute::getUWTableKind() const {
388
31.6k
  assert(hasAttribute(Attribute::UWTable) &&
389
31.6k
         "Trying to get unwind table kind from non-uwtable attribute");
390
0
  return UWTableKind(pImpl->getValueAsInt());
391
31.6k
}
392
393
31
AllocFnKind Attribute::getAllocKind() const {
394
31
  assert(hasAttribute(Attribute::AllocKind) &&
395
31
         "Trying to get allockind value from non-allockind attribute");
396
0
  return AllocFnKind(pImpl->getValueAsInt());
397
31
}
398
399
205k
MemoryEffects Attribute::getMemoryEffects() const {
400
205k
  assert(hasAttribute(Attribute::Memory) &&
401
205k
         "Can only call getMemoryEffects() on memory attribute");
402
0
  return MemoryEffects::createFromIntValue(pImpl->getValueAsInt());
403
205k
}
404
405
0
FPClassTest Attribute::getNoFPClass() const {
406
0
  assert(hasAttribute(Attribute::NoFPClass) &&
407
0
         "Can only call getNoFPClass() on nofpclass attribute");
408
0
  return static_cast<FPClassTest>(pImpl->getValueAsInt());
409
0
}
410
411
0
static const char *getModRefStr(ModRefInfo MR) {
412
0
  switch (MR) {
413
0
  case ModRefInfo::NoModRef:
414
0
    return "none";
415
0
  case ModRefInfo::Ref:
416
0
    return "read";
417
0
  case ModRefInfo::Mod:
418
0
    return "write";
419
0
  case ModRefInfo::ModRef:
420
0
    return "readwrite";
421
0
  }
422
0
  llvm_unreachable("Invalid ModRefInfo");
423
0
}
424
425
245
std::string Attribute::getAsString(bool InAttrGrp) const {
426
245
  if (!pImpl) return {};
427
428
245
  if (isEnumAttribute())
429
187
    return getNameFromAttrKind(getKindAsEnum()).str();
430
431
58
  if (isTypeAttribute()) {
432
0
    std::string Result = getNameFromAttrKind(getKindAsEnum()).str();
433
0
    Result += '(';
434
0
    raw_string_ostream OS(Result);
435
0
    getValueAsType()->print(OS, false, true);
436
0
    OS.flush();
437
0
    Result += ')';
438
0
    return Result;
439
0
  }
440
441
  // FIXME: These should be output like this:
442
  //
443
  //   align=4
444
  //   alignstack=8
445
  //
446
58
  if (hasAttribute(Attribute::Alignment))
447
58
    return (InAttrGrp ? "align=" + Twine(getValueAsInt())
448
58
                      : "align " + Twine(getValueAsInt()))
449
58
        .str();
450
451
0
  auto AttrWithBytesToString = [&](const char *Name) {
452
0
    return (InAttrGrp ? Name + ("=" + Twine(getValueAsInt()))
453
0
                      : Name + ("(" + Twine(getValueAsInt())) + ")")
454
0
        .str();
455
0
  };
456
457
0
  if (hasAttribute(Attribute::StackAlignment))
458
0
    return AttrWithBytesToString("alignstack");
459
460
0
  if (hasAttribute(Attribute::Dereferenceable))
461
0
    return AttrWithBytesToString("dereferenceable");
462
463
0
  if (hasAttribute(Attribute::DereferenceableOrNull))
464
0
    return AttrWithBytesToString("dereferenceable_or_null");
465
466
0
  if (hasAttribute(Attribute::AllocSize)) {
467
0
    unsigned ElemSize;
468
0
    std::optional<unsigned> NumElems;
469
0
    std::tie(ElemSize, NumElems) = getAllocSizeArgs();
470
471
0
    return (NumElems
472
0
                ? "allocsize(" + Twine(ElemSize) + "," + Twine(*NumElems) + ")"
473
0
                : "allocsize(" + Twine(ElemSize) + ")")
474
0
        .str();
475
0
  }
476
477
0
  if (hasAttribute(Attribute::VScaleRange)) {
478
0
    unsigned MinValue = getVScaleRangeMin();
479
0
    std::optional<unsigned> MaxValue = getVScaleRangeMax();
480
0
    return ("vscale_range(" + Twine(MinValue) + "," +
481
0
            Twine(MaxValue.value_or(0)) + ")")
482
0
        .str();
483
0
  }
484
485
0
  if (hasAttribute(Attribute::UWTable)) {
486
0
    UWTableKind Kind = getUWTableKind();
487
0
    if (Kind != UWTableKind::None) {
488
0
      return Kind == UWTableKind::Default
489
0
                 ? "uwtable"
490
0
                 : ("uwtable(" +
491
0
                    Twine(Kind == UWTableKind::Sync ? "sync" : "async") + ")")
492
0
                       .str();
493
0
    }
494
0
  }
495
496
0
  if (hasAttribute(Attribute::AllocKind)) {
497
0
    AllocFnKind Kind = getAllocKind();
498
0
    SmallVector<StringRef> parts;
499
0
    if ((Kind & AllocFnKind::Alloc) != AllocFnKind::Unknown)
500
0
      parts.push_back("alloc");
501
0
    if ((Kind & AllocFnKind::Realloc) != AllocFnKind::Unknown)
502
0
      parts.push_back("realloc");
503
0
    if ((Kind & AllocFnKind::Free) != AllocFnKind::Unknown)
504
0
      parts.push_back("free");
505
0
    if ((Kind & AllocFnKind::Uninitialized) != AllocFnKind::Unknown)
506
0
      parts.push_back("uninitialized");
507
0
    if ((Kind & AllocFnKind::Zeroed) != AllocFnKind::Unknown)
508
0
      parts.push_back("zeroed");
509
0
    if ((Kind & AllocFnKind::Aligned) != AllocFnKind::Unknown)
510
0
      parts.push_back("aligned");
511
0
    return ("allockind(\"" +
512
0
            Twine(llvm::join(parts.begin(), parts.end(), ",")) + "\")")
513
0
        .str();
514
0
  }
515
516
0
  if (hasAttribute(Attribute::Memory)) {
517
0
    std::string Result;
518
0
    raw_string_ostream OS(Result);
519
0
    bool First = true;
520
0
    OS << "memory(";
521
522
0
    MemoryEffects ME = getMemoryEffects();
523
524
    // Print access kind for "other" as the default access kind. This way it
525
    // will apply to any new location kinds that get split out of "other".
526
0
    ModRefInfo OtherMR = ME.getModRef(IRMemLocation::Other);
527
0
    if (OtherMR != ModRefInfo::NoModRef || ME.getModRef() == OtherMR) {
528
0
      First = false;
529
0
      OS << getModRefStr(OtherMR);
530
0
    }
531
532
0
    for (auto Loc : MemoryEffects::locations()) {
533
0
      ModRefInfo MR = ME.getModRef(Loc);
534
0
      if (MR == OtherMR)
535
0
        continue;
536
537
0
      if (!First)
538
0
        OS << ", ";
539
0
      First = false;
540
541
0
      switch (Loc) {
542
0
      case IRMemLocation::ArgMem:
543
0
        OS << "argmem: ";
544
0
        break;
545
0
      case IRMemLocation::InaccessibleMem:
546
0
        OS << "inaccessiblemem: ";
547
0
        break;
548
0
      case IRMemLocation::Other:
549
0
        llvm_unreachable("This is represented as the default access kind");
550
0
      }
551
0
      OS << getModRefStr(MR);
552
0
    }
553
0
    OS << ")";
554
0
    OS.flush();
555
0
    return Result;
556
0
  }
557
558
0
  if (hasAttribute(Attribute::NoFPClass)) {
559
0
    std::string Result = "nofpclass";
560
0
    raw_string_ostream OS(Result);
561
0
    OS << getNoFPClass();
562
0
    return Result;
563
0
  }
564
565
  // Convert target-dependent attributes to strings of the form:
566
  //
567
  //   "kind"
568
  //   "kind" = "value"
569
  //
570
0
  if (isStringAttribute()) {
571
0
    std::string Result;
572
0
    {
573
0
      raw_string_ostream OS(Result);
574
0
      OS << '"' << getKindAsString() << '"';
575
576
      // Since some attribute strings contain special characters that cannot be
577
      // printable, those have to be escaped to make the attribute value
578
      // printable as is.  e.g. "\01__gnu_mcount_nc"
579
0
      const auto &AttrVal = pImpl->getValueAsString();
580
0
      if (!AttrVal.empty()) {
581
0
        OS << "=\"";
582
0
        printEscapedString(AttrVal, OS);
583
0
        OS << "\"";
584
0
      }
585
0
    }
586
0
    return Result;
587
0
  }
588
589
0
  llvm_unreachable("Unknown attribute");
590
0
}
591
592
729k
bool Attribute::hasParentContext(LLVMContext &C) const {
593
729k
  assert(isValid() && "invalid Attribute doesn't refer to any context");
594
0
  FoldingSetNodeID ID;
595
729k
  pImpl->Profile(ID);
596
729k
  void *Unused;
597
729k
  return C.pImpl->AttrsSet.FindNodeOrInsertPos(ID, Unused) == pImpl;
598
729k
}
599
600
10.5M
bool Attribute::operator<(Attribute A) const {
601
10.5M
  if (!pImpl && !A.pImpl) return false;
602
10.5M
  if (!pImpl) return true;
603
10.5M
  if (!A.pImpl) return false;
604
10.5M
  return *pImpl < *A.pImpl;
605
10.5M
}
606
607
10.2M
void Attribute::Profile(FoldingSetNodeID &ID) const {
608
10.2M
  ID.AddPointer(pImpl);
609
10.2M
}
610
611
enum AttributeProperty {
612
  FnAttr = (1 << 0),
613
  ParamAttr = (1 << 1),
614
  RetAttr = (1 << 2),
615
};
616
617
#define GET_ATTR_PROP_TABLE
618
#include "llvm/IR/Attributes.inc"
619
620
static bool hasAttributeProperty(Attribute::AttrKind Kind,
621
2.29M
                                 AttributeProperty Prop) {
622
2.29M
  unsigned Index = Kind - 1;
623
2.29M
  assert(Index < std::size(AttrPropTable) && "Invalid attribute kind");
624
0
  return AttrPropTable[Index] & Prop;
625
2.29M
}
626
627
1.68M
bool Attribute::canUseAsFnAttr(AttrKind Kind) {
628
1.68M
  return hasAttributeProperty(Kind, AttributeProperty::FnAttr);
629
1.68M
}
630
631
580k
bool Attribute::canUseAsParamAttr(AttrKind Kind) {
632
580k
  return hasAttributeProperty(Kind, AttributeProperty::ParamAttr);
633
580k
}
634
635
22.4k
bool Attribute::canUseAsRetAttr(AttrKind Kind) {
636
22.4k
  return hasAttributeProperty(Kind, AttributeProperty::RetAttr);
637
22.4k
}
638
639
//===----------------------------------------------------------------------===//
640
// AttributeImpl Definition
641
//===----------------------------------------------------------------------===//
642
643
593k
bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
644
593k
  if (isStringAttribute()) return false;
645
589k
  return getKindAsEnum() == A;
646
593k
}
647
648
339k
bool AttributeImpl::hasAttribute(StringRef Kind) const {
649
339k
  if (!isStringAttribute()) return false;
650
339k
  return getKindAsString() == Kind;
651
339k
}
652
653
56.9M
Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
654
56.9M
  assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
655
0
  return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
656
56.9M
}
657
658
989k
uint64_t AttributeImpl::getValueAsInt() const {
659
989k
  assert(isIntAttribute());
660
0
  return static_cast<const IntAttributeImpl *>(this)->getValue();
661
989k
}
662
663
18.1k
bool AttributeImpl::getValueAsBool() const {
664
18.1k
  assert(getValueAsString().empty() || getValueAsString() == "false" || getValueAsString() == "true");
665
0
  return getValueAsString() == "true";
666
18.1k
}
667
668
4.65M
StringRef AttributeImpl::getKindAsString() const {
669
4.65M
  assert(isStringAttribute());
670
0
  return static_cast<const StringAttributeImpl *>(this)->getStringKind();
671
4.65M
}
672
673
1.00M
StringRef AttributeImpl::getValueAsString() const {
674
1.00M
  assert(isStringAttribute());
675
0
  return static_cast<const StringAttributeImpl *>(this)->getStringValue();
676
1.00M
}
677
678
13.1k
Type *AttributeImpl::getValueAsType() const {
679
13.1k
  assert(isTypeAttribute());
680
0
  return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
681
13.1k
}
682
683
10.5M
bool AttributeImpl::operator<(const AttributeImpl &AI) const {
684
10.5M
  if (this == &AI)
685
0
    return false;
686
687
  // This sorts the attributes with Attribute::AttrKinds coming first (sorted
688
  // relative to their enum value) and then strings.
689
10.5M
  if (!isStringAttribute()) {
690
10.4M
    if (AI.isStringAttribute())
691
42
      return true;
692
10.4M
    if (getKindAsEnum() != AI.getKindAsEnum())
693
10.4M
      return getKindAsEnum() < AI.getKindAsEnum();
694
0
    assert(!AI.isEnumAttribute() && "Non-unique attribute");
695
0
    assert(!AI.isTypeAttribute() && "Comparison of types would be unstable");
696
    // TODO: Is this actually needed?
697
0
    assert(AI.isIntAttribute() && "Only possibility left");
698
0
    return getValueAsInt() < AI.getValueAsInt();
699
10.4M
  }
700
701
123k
  if (!AI.isStringAttribute())
702
10.6k
    return false;
703
112k
  if (getKindAsString() == AI.getKindAsString())
704
0
    return getValueAsString() < AI.getValueAsString();
705
112k
  return getKindAsString() < AI.getKindAsString();
706
112k
}
707
708
//===----------------------------------------------------------------------===//
709
// AttributeSet Definition
710
//===----------------------------------------------------------------------===//
711
712
21.1M
AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
713
21.1M
  return AttributeSet(AttributeSetNode::get(C, B));
714
21.1M
}
715
716
1.11M
AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
717
1.11M
  return AttributeSet(AttributeSetNode::get(C, Attrs));
718
1.11M
}
719
720
AttributeSet AttributeSet::addAttribute(LLVMContext &C,
721
0
                                        Attribute::AttrKind Kind) const {
722
0
  if (hasAttribute(Kind)) return *this;
723
0
  AttrBuilder B(C);
724
0
  B.addAttribute(Kind);
725
0
  return addAttributes(C, AttributeSet::get(C, B));
726
0
}
727
728
AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
729
0
                                        StringRef Value) const {
730
0
  AttrBuilder B(C);
731
0
  B.addAttribute(Kind, Value);
732
0
  return addAttributes(C, AttributeSet::get(C, B));
733
0
}
734
735
AttributeSet AttributeSet::addAttributes(LLVMContext &C,
736
0
                                         const AttributeSet AS) const {
737
0
  if (!hasAttributes())
738
0
    return AS;
739
740
0
  if (!AS.hasAttributes())
741
0
    return *this;
742
743
0
  AttrBuilder B(C, *this);
744
0
  B.merge(AttrBuilder(C, AS));
745
0
  return get(C, B);
746
0
}
747
748
AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
749
10.1k
                                             Attribute::AttrKind Kind) const {
750
10.1k
  if (!hasAttribute(Kind)) return *this;
751
1.85k
  AttrBuilder B(C, *this);
752
1.85k
  B.removeAttribute(Kind);
753
1.85k
  return get(C, B);
754
10.1k
}
755
756
AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
757
15.5k
                                             StringRef Kind) const {
758
15.5k
  if (!hasAttribute(Kind)) return *this;
759
0
  AttrBuilder B(C, *this);
760
0
  B.removeAttribute(Kind);
761
0
  return get(C, B);
762
15.5k
}
763
764
AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
765
13.5M
                                            const AttributeMask &Attrs) const {
766
13.5M
  AttrBuilder B(C, *this);
767
  // If there is nothing to remove, directly return the original set.
768
13.5M
  if (!B.overlaps(Attrs))
769
13.5M
    return *this;
770
771
61
  B.remove(Attrs);
772
61
  return get(C, B);
773
13.5M
}
774
775
144k
unsigned AttributeSet::getNumAttributes() const {
776
144k
  return SetNode ? SetNode->getNumAttributes() : 0;
777
144k
}
778
779
60.1M
bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
780
60.1M
  return SetNode ? SetNode->hasAttribute(Kind) : false;
781
60.1M
}
782
783
25.6M
bool AttributeSet::hasAttribute(StringRef Kind) const {
784
25.6M
  return SetNode ? SetNode->hasAttribute(Kind) : false;
785
25.6M
}
786
787
906k
Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
788
906k
  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
789
906k
}
790
791
18.5M
Attribute AttributeSet::getAttribute(StringRef Kind) const {
792
18.5M
  return SetNode ? SetNode->getAttribute(Kind) : Attribute();
793
18.5M
}
794
795
122k
MaybeAlign AttributeSet::getAlignment() const {
796
122k
  return SetNode ? SetNode->getAlignment() : std::nullopt;
797
122k
}
798
799
354k
MaybeAlign AttributeSet::getStackAlignment() const {
800
354k
  return SetNode ? SetNode->getStackAlignment() : std::nullopt;
801
354k
}
802
803
515k
uint64_t AttributeSet::getDereferenceableBytes() const {
804
515k
  return SetNode ? SetNode->getDereferenceableBytes() : 0;
805
515k
}
806
807
497k
uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
808
497k
  return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
809
497k
}
810
811
484k
Type *AttributeSet::getByRefType() const {
812
484k
  return SetNode ? SetNode->getAttributeType(Attribute::ByRef) : nullptr;
813
484k
}
814
815
488k
Type *AttributeSet::getByValType() const {
816
488k
  return SetNode ? SetNode->getAttributeType(Attribute::ByVal) : nullptr;
817
488k
}
818
819
484k
Type *AttributeSet::getStructRetType() const {
820
484k
  return SetNode ? SetNode->getAttributeType(Attribute::StructRet) : nullptr;
821
484k
}
822
823
484k
Type *AttributeSet::getPreallocatedType() const {
824
484k
  return SetNode ? SetNode->getAttributeType(Attribute::Preallocated) : nullptr;
825
484k
}
826
827
485k
Type *AttributeSet::getInAllocaType() const {
828
485k
  return SetNode ? SetNode->getAttributeType(Attribute::InAlloca) : nullptr;
829
485k
}
830
831
716
Type *AttributeSet::getElementType() const {
832
716
  return SetNode ? SetNode->getAttributeType(Attribute::ElementType) : nullptr;
833
716
}
834
835
std::optional<std::pair<unsigned, std::optional<unsigned>>>
836
462k
AttributeSet::getAllocSizeArgs() const {
837
462k
  if (SetNode)
838
462k
    return SetNode->getAllocSizeArgs();
839
0
  return std::nullopt;
840
462k
}
841
842
0
unsigned AttributeSet::getVScaleRangeMin() const {
843
0
  return SetNode ? SetNode->getVScaleRangeMin() : 1;
844
0
}
845
846
0
std::optional<unsigned> AttributeSet::getVScaleRangeMax() const {
847
0
  return SetNode ? SetNode->getVScaleRangeMax() : std::nullopt;
848
0
}
849
850
709k
UWTableKind AttributeSet::getUWTableKind() const {
851
709k
  return SetNode ? SetNode->getUWTableKind() : UWTableKind::None;
852
709k
}
853
854
11.6k
AllocFnKind AttributeSet::getAllocKind() const {
855
11.6k
  return SetNode ? SetNode->getAllocKind() : AllocFnKind::Unknown;
856
11.6k
}
857
858
575k
MemoryEffects AttributeSet::getMemoryEffects() const {
859
575k
  return SetNode ? SetNode->getMemoryEffects() : MemoryEffects::unknown();
860
575k
}
861
862
19.2k
FPClassTest AttributeSet::getNoFPClass() const {
863
19.2k
  return SetNode ? SetNode->getNoFPClass() : fcNone;
864
19.2k
}
865
866
0
std::string AttributeSet::getAsString(bool InAttrGrp) const {
867
0
  return SetNode ? SetNode->getAsString(InAttrGrp) : "";
868
0
}
869
870
268k
bool AttributeSet::hasParentContext(LLVMContext &C) const {
871
268k
  assert(hasAttributes() && "empty AttributeSet doesn't refer to any context");
872
0
  FoldingSetNodeID ID;
873
268k
  SetNode->Profile(ID);
874
268k
  void *Unused;
875
268k
  return C.pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, Unused) == SetNode;
876
268k
}
877
878
306M
AttributeSet::iterator AttributeSet::begin() const {
879
306M
  return SetNode ? SetNode->begin() : nullptr;
880
306M
}
881
882
306M
AttributeSet::iterator AttributeSet::end() const {
883
306M
  return SetNode ? SetNode->end() : nullptr;
884
306M
}
885
886
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
887
0
LLVM_DUMP_METHOD void AttributeSet::dump() const {
888
0
  dbgs() << "AS =\n";
889
0
    dbgs() << "  { ";
890
0
    dbgs() << getAsString(true) << " }\n";
891
0
}
892
#endif
893
894
//===----------------------------------------------------------------------===//
895
// AttributeSetNode Definition
896
//===----------------------------------------------------------------------===//
897
898
AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
899
152k
    : NumAttrs(Attrs.size()) {
900
  // There's memory after the node where we can store the entries in.
901
152k
  llvm::copy(Attrs, getTrailingObjects<Attribute>());
902
903
477k
  for (const auto &I : *this) {
904
477k
    if (I.isStringAttribute())
905
64.2k
      StringAttrs.insert({ I.getKindAsString(), I });
906
413k
    else
907
413k
      AvailableAttrs.addAttribute(I.getKindAsEnum());
908
477k
  }
909
152k
}
910
911
AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
912
1.11M
                                        ArrayRef<Attribute> Attrs) {
913
1.11M
  SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
914
1.11M
  llvm::sort(SortedAttrs);
915
1.11M
  return getSorted(C, SortedAttrs);
916
1.11M
}
917
918
AttributeSetNode *AttributeSetNode::getSorted(LLVMContext &C,
919
22.3M
                                              ArrayRef<Attribute> SortedAttrs) {
920
22.3M
  if (SortedAttrs.empty())
921
20.9M
    return nullptr;
922
923
  // Build a key to look up the existing attributes.
924
1.36M
  LLVMContextImpl *pImpl = C.pImpl;
925
1.36M
  FoldingSetNodeID ID;
926
927
1.36M
  assert(llvm::is_sorted(SortedAttrs) && "Expected sorted attributes!");
928
0
  for (const auto &Attr : SortedAttrs)
929
4.56M
    Attr.Profile(ID);
930
931
1.36M
  void *InsertPoint;
932
1.36M
  AttributeSetNode *PA =
933
1.36M
    pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
934
935
  // If we didn't find any existing attributes of the same shape then create a
936
  // new one and insert it.
937
1.36M
  if (!PA) {
938
    // Coallocate entries after the AttributeSetNode itself.
939
152k
    void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
940
152k
    PA = new (Mem) AttributeSetNode(SortedAttrs);
941
152k
    pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
942
152k
  }
943
944
  // Return the AttributeSetNode that we found or created.
945
1.36M
  return PA;
946
22.3M
}
947
948
21.1M
AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
949
21.1M
  return getSorted(C, B.attrs());
950
21.1M
}
951
952
7.84M
bool AttributeSetNode::hasAttribute(StringRef Kind) const {
953
7.84M
  return StringAttrs.count(Kind);
954
7.84M
}
955
956
std::optional<Attribute>
957
1.59M
AttributeSetNode::findEnumAttribute(Attribute::AttrKind Kind) const {
958
  // Do a quick presence check.
959
1.59M
  if (!hasAttribute(Kind))
960
1.31M
    return std::nullopt;
961
962
  // Attributes in a set are sorted by enum value, followed by string
963
  // attributes. Binary search the one we want.
964
286k
  const Attribute *I =
965
286k
      std::lower_bound(begin(), end() - StringAttrs.size(), Kind,
966
698k
                       [](Attribute A, Attribute::AttrKind Kind) {
967
698k
                         return A.getKindAsEnum() < Kind;
968
698k
                       });
969
286k
  assert(I != end() && I->hasAttribute(Kind) && "Presence check failed?");
970
0
  return *I;
971
1.59M
}
972
973
459k
Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
974
459k
  if (auto A = findEnumAttribute(Kind))
975
2.20k
    return *A;
976
457k
  return {};
977
459k
}
978
979
4.20M
Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
980
4.20M
  return StringAttrs.lookup(Kind);
981
4.20M
}
982
983
78.9k
MaybeAlign AttributeSetNode::getAlignment() const {
984
78.9k
  if (auto A = findEnumAttribute(Attribute::Alignment))
985
28.8k
    return A->getAlignment();
986
50.1k
  return std::nullopt;
987
78.9k
}
988
989
37.9k
MaybeAlign AttributeSetNode::getStackAlignment() const {
990
37.9k
  if (auto A = findEnumAttribute(Attribute::StackAlignment))
991
0
    return A->getStackAlignment();
992
37.9k
  return std::nullopt;
993
37.9k
}
994
995
169k
Type *AttributeSetNode::getAttributeType(Attribute::AttrKind Kind) const {
996
169k
  if (auto A = findEnumAttribute(Kind))
997
7.24k
    return A->getValueAsType();
998
161k
  return nullptr;
999
169k
}
1000
1001
39.0k
uint64_t AttributeSetNode::getDereferenceableBytes() const {
1002
39.0k
  if (auto A = findEnumAttribute(Attribute::Dereferenceable))
1003
9.57k
    return A->getDereferenceableBytes();
1004
29.4k
  return 0;
1005
39.0k
}
1006
1007
30.0k
uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
1008
30.0k
  if (auto A = findEnumAttribute(Attribute::DereferenceableOrNull))
1009
688
    return A->getDereferenceableOrNullBytes();
1010
29.3k
  return 0;
1011
30.0k
}
1012
1013
std::optional<std::pair<unsigned, std::optional<unsigned>>>
1014
462k
AttributeSetNode::getAllocSizeArgs() const {
1015
462k
  if (auto A = findEnumAttribute(Attribute::AllocSize))
1016
1.15k
    return A->getAllocSizeArgs();
1017
461k
  return std::nullopt;
1018
462k
}
1019
1020
0
unsigned AttributeSetNode::getVScaleRangeMin() const {
1021
0
  if (auto A = findEnumAttribute(Attribute::VScaleRange))
1022
0
    return A->getVScaleRangeMin();
1023
0
  return 1;
1024
0
}
1025
1026
0
std::optional<unsigned> AttributeSetNode::getVScaleRangeMax() const {
1027
0
  if (auto A = findEnumAttribute(Attribute::VScaleRange))
1028
0
    return A->getVScaleRangeMax();
1029
0
  return std::nullopt;
1030
0
}
1031
1032
73.8k
UWTableKind AttributeSetNode::getUWTableKind() const {
1033
73.8k
  if (auto A = findEnumAttribute(Attribute::UWTable))
1034
31.6k
    return A->getUWTableKind();
1035
42.1k
  return UWTableKind::None;
1036
73.8k
}
1037
1038
3.83k
AllocFnKind AttributeSetNode::getAllocKind() const {
1039
3.83k
  if (auto A = findEnumAttribute(Attribute::AllocKind))
1040
31
    return A->getAllocKind();
1041
3.80k
  return AllocFnKind::Unknown;
1042
3.83k
}
1043
1044
242k
MemoryEffects AttributeSetNode::getMemoryEffects() const {
1045
242k
  if (auto A = findEnumAttribute(Attribute::Memory))
1046
205k
    return A->getMemoryEffects();
1047
36.9k
  return MemoryEffects::unknown();
1048
242k
}
1049
1050
44
FPClassTest AttributeSetNode::getNoFPClass() const {
1051
44
  if (auto A = findEnumAttribute(Attribute::NoFPClass))
1052
0
    return A->getNoFPClass();
1053
44
  return fcNone;
1054
44
}
1055
1056
0
std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
1057
0
  std::string Str;
1058
0
  for (iterator I = begin(), E = end(); I != E; ++I) {
1059
0
    if (I != begin())
1060
0
      Str += ' ';
1061
0
    Str += I->getAsString(InAttrGrp);
1062
0
  }
1063
0
  return Str;
1064
0
}
1065
1066
//===----------------------------------------------------------------------===//
1067
// AttributeListImpl Definition
1068
//===----------------------------------------------------------------------===//
1069
1070
/// Map from AttributeList index to the internal array index. Adding one happens
1071
/// to work, because -1 wraps around to 0.
1072
221M
static unsigned attrIdxToArrayIdx(unsigned Index) {
1073
221M
  return Index + 1;
1074
221M
}
1075
1076
AttributeListImpl::AttributeListImpl(ArrayRef<AttributeSet> Sets)
1077
204k
    : NumAttrSets(Sets.size()) {
1078
204k
  assert(!Sets.empty() && "pointless AttributeListImpl");
1079
1080
  // There's memory after the node where we can store the entries in.
1081
0
  llvm::copy(Sets, getTrailingObjects<AttributeSet>());
1082
1083
  // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
1084
  // summary bitsets.
1085
204k
  for (const auto &I : Sets[attrIdxToArrayIdx(AttributeList::FunctionIndex)])
1086
485k
    if (!I.isStringAttribute())
1087
449k
      AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
1088
1089
204k
  for (const auto &Set : Sets)
1090
175M
    for (const auto &I : Set)
1091
747k
      if (!I.isStringAttribute())
1092
702k
        AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
1093
204k
}
1094
1095
910k
void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
1096
910k
  Profile(ID, ArrayRef(begin(), end()));
1097
910k
}
1098
1099
void AttributeListImpl::Profile(FoldingSetNodeID &ID,
1100
1.67M
                                ArrayRef<AttributeSet> Sets) {
1101
1.67M
  for (const auto &Set : Sets)
1102
184M
    ID.AddPointer(Set.SetNode);
1103
1.67M
}
1104
1105
bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind,
1106
2.54M
                                        unsigned *Index) const {
1107
2.54M
  if (!AvailableSomewhereAttrs.hasAttribute(Kind))
1108
2.54M
    return false;
1109
1110
1.82k
  if (Index) {
1111
5.15k
    for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
1112
5.15k
      if (begin()[I].hasAttribute(Kind)) {
1113
1.71k
        *Index = I - 1;
1114
1.71k
        break;
1115
1.71k
      }
1116
5.15k
    }
1117
1.71k
  }
1118
1119
1.82k
  return true;
1120
2.54M
}
1121
1122
1123
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1124
0
LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
1125
0
  AttributeList(const_cast<AttributeListImpl *>(this)).dump();
1126
0
}
1127
#endif
1128
1129
//===----------------------------------------------------------------------===//
1130
// AttributeList Construction and Mutation Methods
1131
//===----------------------------------------------------------------------===//
1132
1133
AttributeList AttributeList::getImpl(LLVMContext &C,
1134
761k
                                     ArrayRef<AttributeSet> AttrSets) {
1135
761k
  assert(!AttrSets.empty() && "pointless AttributeListImpl");
1136
1137
0
  LLVMContextImpl *pImpl = C.pImpl;
1138
761k
  FoldingSetNodeID ID;
1139
761k
  AttributeListImpl::Profile(ID, AttrSets);
1140
1141
761k
  void *InsertPoint;
1142
761k
  AttributeListImpl *PA =
1143
761k
      pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
1144
1145
  // If we didn't find any existing attributes of the same shape then
1146
  // create a new one and insert it.
1147
761k
  if (!PA) {
1148
    // Coallocate entries after the AttributeListImpl itself.
1149
204k
    void *Mem = pImpl->Alloc.Allocate(
1150
204k
        AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()),
1151
204k
        alignof(AttributeListImpl));
1152
204k
    PA = new (Mem) AttributeListImpl(AttrSets);
1153
204k
    pImpl->AttrsLists.InsertNode(PA, InsertPoint);
1154
204k
  }
1155
1156
  // Return the AttributesList that we found or created.
1157
761k
  return AttributeList(PA);
1158
761k
}
1159
1160
AttributeList
1161
AttributeList::get(LLVMContext &C,
1162
90.4k
                   ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
1163
  // If there are no attributes then return a null AttributesList pointer.
1164
90.4k
  if (Attrs.empty())
1165
19.6k
    return {};
1166
1167
70.8k
  assert(llvm::is_sorted(Attrs, llvm::less_first()) &&
1168
70.8k
         "Misordered Attributes list!");
1169
0
  assert(llvm::all_of(Attrs,
1170
70.8k
                      [](const std::pair<unsigned, Attribute> &Pair) {
1171
70.8k
                        return Pair.second.isValid();
1172
70.8k
                      }) &&
1173
70.8k
         "Pointless attribute!");
1174
1175
  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
1176
  // list.
1177
0
  SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
1178
70.8k
  for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
1179
141k
         E = Attrs.end(); I != E; ) {
1180
70.8k
    unsigned Index = I->first;
1181
70.8k
    SmallVector<Attribute, 4> AttrVec;
1182
141k
    while (I != E && I->first == Index) {
1183
70.8k
      AttrVec.push_back(I->second);
1184
70.8k
      ++I;
1185
70.8k
    }
1186
1187
70.8k
    AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
1188
70.8k
  }
1189
1190
70.8k
  return get(C, AttrPairVec);
1191
90.4k
}
1192
1193
AttributeList
1194
AttributeList::get(LLVMContext &C,
1195
594k
                   ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
1196
  // If there are no attributes then return a null AttributesList pointer.
1197
594k
  if (Attrs.empty())
1198
0
    return {};
1199
1200
594k
  assert(llvm::is_sorted(Attrs, llvm::less_first()) &&
1201
594k
         "Misordered Attributes list!");
1202
0
  assert(llvm::none_of(Attrs,
1203
594k
                       [](const std::pair<unsigned, AttributeSet> &Pair) {
1204
594k
                         return !Pair.second.hasAttributes();
1205
594k
                       }) &&
1206
594k
         "Pointless attribute!");
1207
1208
0
  unsigned MaxIndex = Attrs.back().first;
1209
  // If the MaxIndex is FunctionIndex and there are other indices in front
1210
  // of it, we need to use the largest of those to get the right size.
1211
594k
  if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1212
256k
    MaxIndex = Attrs[Attrs.size() - 2].first;
1213
1214
594k
  SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
1215
594k
  for (const auto &Pair : Attrs)
1216
1.11M
    AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1217
1218
594k
  return getImpl(C, AttrVec);
1219
594k
}
1220
1221
AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
1222
                                 AttributeSet RetAttrs,
1223
3.16k
                                 ArrayRef<AttributeSet> ArgAttrs) {
1224
  // Scan from the end to find the last argument with attributes.  Most
1225
  // arguments don't have attributes, so it's nice if we can have fewer unique
1226
  // AttributeListImpls by dropping empty attribute sets at the end of the list.
1227
3.16k
  unsigned NumSets = 0;
1228
8.13k
  for (size_t I = ArgAttrs.size(); I != 0; --I) {
1229
5.09k
    if (ArgAttrs[I - 1].hasAttributes()) {
1230
127
      NumSets = I + 2;
1231
127
      break;
1232
127
    }
1233
5.09k
  }
1234
3.16k
  if (NumSets == 0) {
1235
    // Check function and return attributes if we didn't have argument
1236
    // attributes.
1237
3.03k
    if (RetAttrs.hasAttributes())
1238
728
      NumSets = 2;
1239
2.30k
    else if (FnAttrs.hasAttributes())
1240
17
      NumSets = 1;
1241
3.03k
  }
1242
1243
  // If all attribute sets were empty, we can use the empty attribute list.
1244
3.16k
  if (NumSets == 0)
1245
2.28k
    return {};
1246
1247
872
  SmallVector<AttributeSet, 8> AttrSets;
1248
872
  AttrSets.reserve(NumSets);
1249
  // If we have any attributes, we always have function attributes.
1250
872
  AttrSets.push_back(FnAttrs);
1251
872
  if (NumSets > 1)
1252
855
    AttrSets.push_back(RetAttrs);
1253
872
  if (NumSets > 2) {
1254
    // Drop the empty argument attribute sets at the end.
1255
127
    ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1256
127
    llvm::append_range(AttrSets, ArgAttrs);
1257
127
  }
1258
1259
872
  return getImpl(C, AttrSets);
1260
3.16k
}
1261
1262
AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1263
112k
                                 AttributeSet Attrs) {
1264
112k
  if (!Attrs.hasAttributes())
1265
342
    return {};
1266
111k
  Index = attrIdxToArrayIdx(Index);
1267
111k
  SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1268
111k
  AttrSets[Index] = Attrs;
1269
111k
  return getImpl(C, AttrSets);
1270
112k
}
1271
1272
AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1273
112k
                                 const AttrBuilder &B) {
1274
112k
  return get(C, Index, AttributeSet::get(C, B));
1275
112k
}
1276
1277
AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1278
90.4k
                                 ArrayRef<Attribute::AttrKind> Kinds) {
1279
90.4k
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1280
90.4k
  for (const auto K : Kinds)
1281
70.8k
    Attrs.emplace_back(Index, Attribute::get(C, K));
1282
90.4k
  return get(C, Attrs);
1283
90.4k
}
1284
1285
AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1286
                                 ArrayRef<Attribute::AttrKind> Kinds,
1287
0
                                 ArrayRef<uint64_t> Values) {
1288
0
  assert(Kinds.size() == Values.size() && "Mismatched attribute values.");
1289
0
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1290
0
  auto VI = Values.begin();
1291
0
  for (const auto K : Kinds)
1292
0
    Attrs.emplace_back(Index, Attribute::get(C, K, *VI++));
1293
0
  return get(C, Attrs);
1294
0
}
1295
1296
AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1297
0
                                 ArrayRef<StringRef> Kinds) {
1298
0
  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
1299
0
  for (const auto &K : Kinds)
1300
0
    Attrs.emplace_back(Index, Attribute::get(C, K));
1301
0
  return get(C, Attrs);
1302
0
}
1303
1304
AttributeList AttributeList::get(LLVMContext &C,
1305
81.5k
                                 ArrayRef<AttributeList> Attrs) {
1306
81.5k
  if (Attrs.empty())
1307
9
    return {};
1308
81.5k
  if (Attrs.size() == 1)
1309
46.8k
    return Attrs[0];
1310
1311
34.7k
  unsigned MaxSize = 0;
1312
34.7k
  for (const auto &List : Attrs)
1313
101k
    MaxSize = std::max(MaxSize, List.getNumAttrSets());
1314
1315
  // If every list was empty, there is no point in merging the lists.
1316
34.7k
  if (MaxSize == 0)
1317
98
    return {};
1318
1319
34.6k
  SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1320
21.0M
  for (unsigned I = 0; I < MaxSize; ++I) {
1321
21.0M
    AttrBuilder CurBuilder(C);
1322
21.0M
    for (const auto &List : Attrs)
1323
111M
      CurBuilder.merge(AttrBuilder(C, List.getAttributes(I - 1)));
1324
21.0M
    NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
1325
21.0M
  }
1326
1327
34.6k
  return getImpl(C, NewAttrSets);
1328
34.7k
}
1329
1330
AttributeList
1331
AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1332
5.37k
                                   Attribute::AttrKind Kind) const {
1333
5.37k
  AttributeSet Attrs = getAttributes(Index);
1334
5.37k
  if (Attrs.hasAttribute(Kind))
1335
107
    return *this;
1336
  // TODO: Insert at correct position and avoid sort.
1337
5.26k
  SmallVector<Attribute, 8> NewAttrs(Attrs.begin(), Attrs.end());
1338
5.26k
  NewAttrs.push_back(Attribute::get(C, Kind));
1339
5.26k
  return setAttributesAtIndex(C, Index, AttributeSet::get(C, NewAttrs));
1340
5.37k
}
1341
1342
AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1343
                                                 StringRef Kind,
1344
7.76k
                                                 StringRef Value) const {
1345
7.76k
  AttrBuilder B(C);
1346
7.76k
  B.addAttribute(Kind, Value);
1347
7.76k
  return addAttributesAtIndex(C, Index, B);
1348
7.76k
}
1349
1350
AttributeList AttributeList::addAttributeAtIndex(LLVMContext &C, unsigned Index,
1351
1.36k
                                                 Attribute A) const {
1352
1.36k
  AttrBuilder B(C);
1353
1.36k
  B.addAttribute(A);
1354
1.36k
  return addAttributesAtIndex(C, Index, B);
1355
1.36k
}
1356
1357
AttributeList AttributeList::setAttributesAtIndex(LLVMContext &C,
1358
                                                  unsigned Index,
1359
10.2k
                                                  AttributeSet Attrs) const {
1360
10.2k
  Index = attrIdxToArrayIdx(Index);
1361
10.2k
  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1362
10.2k
  if (Index >= AttrSets.size())
1363
1.91k
    AttrSets.resize(Index + 1);
1364
10.2k
  AttrSets[Index] = Attrs;
1365
1366
  // Remove trailing empty attribute sets.
1367
10.8k
  while (!AttrSets.empty() && !AttrSets.back().hasAttributes())
1368
629
    AttrSets.pop_back();
1369
10.2k
  if (AttrSets.empty())
1370
139
    return {};
1371
10.0k
  return AttributeList::getImpl(C, AttrSets);
1372
10.2k
}
1373
1374
AttributeList AttributeList::addAttributesAtIndex(LLVMContext &C,
1375
                                                  unsigned Index,
1376
806k
                                                  const AttrBuilder &B) const {
1377
806k
  if (!B.hasAttributes())
1378
796k
    return *this;
1379
1380
9.12k
  if (!pImpl)
1381
6.09k
    return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
1382
1383
3.02k
  AttrBuilder Merged(C, getAttributes(Index));
1384
3.02k
  Merged.merge(B);
1385
3.02k
  return setAttributesAtIndex(C, Index, AttributeSet::get(C, Merged));
1386
9.12k
}
1387
1388
AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1389
                                               ArrayRef<unsigned> ArgNos,
1390
9.56k
                                               Attribute A) const {
1391
9.56k
  assert(llvm::is_sorted(ArgNos));
1392
1393
0
  SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1394
9.56k
  unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1395
9.56k
  if (MaxIndex >= AttrSets.size())
1396
4.74k
    AttrSets.resize(MaxIndex + 1);
1397
1398
10.4k
  for (unsigned ArgNo : ArgNos) {
1399
10.4k
    unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1400
10.4k
    AttrBuilder B(C, AttrSets[Index]);
1401
10.4k
    B.addAttribute(A);
1402
10.4k
    AttrSets[Index] = AttributeSet::get(C, B);
1403
10.4k
  }
1404
1405
9.56k
  return getImpl(C, AttrSets);
1406
9.56k
}
1407
1408
AttributeList
1409
AttributeList::removeAttributeAtIndex(LLVMContext &C, unsigned Index,
1410
10.1k
                                      Attribute::AttrKind Kind) const {
1411
10.1k
  AttributeSet Attrs = getAttributes(Index);
1412
10.1k
  AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1413
10.1k
  if (Attrs == NewAttrs)
1414
8.27k
    return *this;
1415
1.85k
  return setAttributesAtIndex(C, Index, NewAttrs);
1416
10.1k
}
1417
1418
AttributeList AttributeList::removeAttributeAtIndex(LLVMContext &C,
1419
                                                    unsigned Index,
1420
15.5k
                                                    StringRef Kind) const {
1421
15.5k
  AttributeSet Attrs = getAttributes(Index);
1422
15.5k
  AttributeSet NewAttrs = Attrs.removeAttribute(C, Kind);
1423
15.5k
  if (Attrs == NewAttrs)
1424
15.5k
    return *this;
1425
0
  return setAttributesAtIndex(C, Index, NewAttrs);
1426
15.5k
}
1427
1428
AttributeList AttributeList::removeAttributesAtIndex(
1429
13.5M
    LLVMContext &C, unsigned Index, const AttributeMask &AttrsToRemove) const {
1430
13.5M
  AttributeSet Attrs = getAttributes(Index);
1431
13.5M
  AttributeSet NewAttrs = Attrs.removeAttributes(C, AttrsToRemove);
1432
  // If nothing was removed, return the original list.
1433
13.5M
  if (Attrs == NewAttrs)
1434
13.5M
    return *this;
1435
61
  return setAttributesAtIndex(C, Index, NewAttrs);
1436
13.5M
}
1437
1438
AttributeList
1439
AttributeList::removeAttributesAtIndex(LLVMContext &C,
1440
1.86k
                                       unsigned WithoutIndex) const {
1441
1.86k
  if (!pImpl)
1442
1.86k
    return {};
1443
2
  if (attrIdxToArrayIdx(WithoutIndex) >= getNumAttrSets())
1444
0
    return *this;
1445
2
  return setAttributesAtIndex(C, WithoutIndex, AttributeSet());
1446
2
}
1447
1448
AttributeList AttributeList::addDereferenceableRetAttr(LLVMContext &C,
1449
0
                                                       uint64_t Bytes) const {
1450
0
  AttrBuilder B(C);
1451
0
  B.addDereferenceableAttr(Bytes);
1452
0
  return addRetAttributes(C, B);
1453
0
}
1454
1455
AttributeList AttributeList::addDereferenceableParamAttr(LLVMContext &C,
1456
                                                         unsigned Index,
1457
0
                                                         uint64_t Bytes) const {
1458
0
  AttrBuilder B(C);
1459
0
  B.addDereferenceableAttr(Bytes);
1460
0
  return addParamAttributes(C, Index, B);
1461
0
}
1462
1463
AttributeList
1464
AttributeList::addDereferenceableOrNullParamAttr(LLVMContext &C, unsigned Index,
1465
0
                                                 uint64_t Bytes) const {
1466
0
  AttrBuilder B(C);
1467
0
  B.addDereferenceableOrNullAttr(Bytes);
1468
0
  return addParamAttributes(C, Index, B);
1469
0
}
1470
1471
AttributeList AttributeList::addAllocSizeParamAttr(
1472
    LLVMContext &C, unsigned Index, unsigned ElemSizeArg,
1473
0
    const std::optional<unsigned> &NumElemsArg) {
1474
0
  AttrBuilder B(C);
1475
0
  B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
1476
0
  return addParamAttributes(C, Index, B);
1477
0
}
1478
1479
//===----------------------------------------------------------------------===//
1480
// AttributeList Accessor Methods
1481
//===----------------------------------------------------------------------===//
1482
1483
2.73M
AttributeSet AttributeList::getParamAttrs(unsigned ArgNo) const {
1484
2.73M
  return getAttributes(ArgNo + FirstArgIndex);
1485
2.73M
}
1486
1487
766k
AttributeSet AttributeList::getRetAttrs() const {
1488
766k
  return getAttributes(ReturnIndex);
1489
766k
}
1490
1491
5.75M
AttributeSet AttributeList::getFnAttrs() const {
1492
5.75M
  return getAttributes(FunctionIndex);
1493
5.75M
}
1494
1495
bool AttributeList::hasAttributeAtIndex(unsigned Index,
1496
39.7M
                                        Attribute::AttrKind Kind) const {
1497
39.7M
  return getAttributes(Index).hasAttribute(Kind);
1498
39.7M
}
1499
1500
24.5M
bool AttributeList::hasAttributeAtIndex(unsigned Index, StringRef Kind) const {
1501
24.5M
  return getAttributes(Index).hasAttribute(Kind);
1502
24.5M
}
1503
1504
549k
bool AttributeList::hasAttributesAtIndex(unsigned Index) const {
1505
549k
  return getAttributes(Index).hasAttributes();
1506
549k
}
1507
1508
50.2M
bool AttributeList::hasFnAttr(Attribute::AttrKind Kind) const {
1509
50.2M
  return pImpl && pImpl->hasFnAttribute(Kind);
1510
50.2M
}
1511
1512
24.5M
bool AttributeList::hasFnAttr(StringRef Kind) const {
1513
24.5M
  return hasAttributeAtIndex(AttributeList::FunctionIndex, Kind);
1514
24.5M
}
1515
1516
bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1517
6.34M
                                     unsigned *Index) const {
1518
6.34M
  return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
1519
6.34M
}
1520
1521
Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1522
905k
                                             Attribute::AttrKind Kind) const {
1523
905k
  return getAttributes(Index).getAttribute(Kind);
1524
905k
}
1525
1526
Attribute AttributeList::getAttributeAtIndex(unsigned Index,
1527
18.5M
                                             StringRef Kind) const {
1528
18.5M
  return getAttributes(Index).getAttribute(Kind);
1529
18.5M
}
1530
1531
8.93k
MaybeAlign AttributeList::getRetAlignment() const {
1532
8.93k
  return getAttributes(ReturnIndex).getAlignment();
1533
8.93k
}
1534
1535
113k
MaybeAlign AttributeList::getParamAlignment(unsigned ArgNo) const {
1536
113k
  return getAttributes(ArgNo + FirstArgIndex).getAlignment();
1537
113k
}
1538
1539
224k
MaybeAlign AttributeList::getParamStackAlignment(unsigned ArgNo) const {
1540
224k
  return getAttributes(ArgNo + FirstArgIndex).getStackAlignment();
1541
224k
}
1542
1543
27
Type *AttributeList::getParamByValType(unsigned Index) const {
1544
27
  return getAttributes(Index+FirstArgIndex).getByValType();
1545
27
}
1546
1547
44
Type *AttributeList::getParamStructRetType(unsigned Index) const {
1548
44
  return getAttributes(Index + FirstArgIndex).getStructRetType();
1549
44
}
1550
1551
0
Type *AttributeList::getParamByRefType(unsigned Index) const {
1552
0
  return getAttributes(Index + FirstArgIndex).getByRefType();
1553
0
}
1554
1555
0
Type *AttributeList::getParamPreallocatedType(unsigned Index) const {
1556
0
  return getAttributes(Index + FirstArgIndex).getPreallocatedType();
1557
0
}
1558
1559
1
Type *AttributeList::getParamInAllocaType(unsigned Index) const {
1560
1
  return getAttributes(Index + FirstArgIndex).getInAllocaType();
1561
1
}
1562
1563
716
Type *AttributeList::getParamElementType(unsigned Index) const {
1564
716
  return getAttributes(Index + FirstArgIndex).getElementType();
1565
716
}
1566
1567
130k
MaybeAlign AttributeList::getFnStackAlignment() const {
1568
130k
  return getFnAttrs().getStackAlignment();
1569
130k
}
1570
1571
0
MaybeAlign AttributeList::getRetStackAlignment() const {
1572
0
  return getRetAttrs().getStackAlignment();
1573
0
}
1574
1575
90.4k
uint64_t AttributeList::getRetDereferenceableBytes() const {
1576
90.4k
  return getRetAttrs().getDereferenceableBytes();
1577
90.4k
}
1578
1579
425k
uint64_t AttributeList::getParamDereferenceableBytes(unsigned Index) const {
1580
425k
  return getParamAttrs(Index).getDereferenceableBytes();
1581
425k
}
1582
1583
89.0k
uint64_t AttributeList::getRetDereferenceableOrNullBytes() const {
1584
89.0k
  return getRetAttrs().getDereferenceableOrNullBytes();
1585
89.0k
}
1586
1587
uint64_t
1588
408k
AttributeList::getParamDereferenceableOrNullBytes(unsigned Index) const {
1589
408k
  return getParamAttrs(Index).getDereferenceableOrNullBytes();
1590
408k
}
1591
1592
4.96k
FPClassTest AttributeList::getRetNoFPClass() const {
1593
4.96k
  return getRetAttrs().getNoFPClass();
1594
4.96k
}
1595
1596
14.3k
FPClassTest AttributeList::getParamNoFPClass(unsigned Index) const {
1597
14.3k
  return getParamAttrs(Index).getNoFPClass();
1598
14.3k
}
1599
1600
709k
UWTableKind AttributeList::getUWTableKind() const {
1601
709k
  return getFnAttrs().getUWTableKind();
1602
709k
}
1603
1604
11.6k
AllocFnKind AttributeList::getAllocKind() const {
1605
11.6k
  return getFnAttrs().getAllocKind();
1606
11.6k
}
1607
1608
575k
MemoryEffects AttributeList::getMemoryEffects() const {
1609
575k
  return getFnAttrs().getMemoryEffects();
1610
575k
}
1611
1612
0
std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
1613
0
  return getAttributes(Index).getAsString(InAttrGrp);
1614
0
}
1615
1616
219M
AttributeSet AttributeList::getAttributes(unsigned Index) const {
1617
219M
  Index = attrIdxToArrayIdx(Index);
1618
219M
  if (!pImpl || Index >= getNumAttrSets())
1619
170M
    return {};
1620
48.7M
  return pImpl->begin()[Index];
1621
219M
}
1622
1623
150k
bool AttributeList::hasParentContext(LLVMContext &C) const {
1624
150k
  assert(!isEmpty() && "an empty attribute list has no parent context");
1625
0
  FoldingSetNodeID ID;
1626
150k
  pImpl->Profile(ID);
1627
150k
  void *Unused;
1628
150k
  return C.pImpl->AttrsLists.FindNodeOrInsertPos(ID, Unused) == pImpl;
1629
150k
}
1630
1631
169k
AttributeList::iterator AttributeList::begin() const {
1632
169k
  return pImpl ? pImpl->begin() : nullptr;
1633
169k
}
1634
1635
169k
AttributeList::iterator AttributeList::end() const {
1636
169k
  return pImpl ? pImpl->end() : nullptr;
1637
169k
}
1638
1639
//===----------------------------------------------------------------------===//
1640
// AttributeList Introspection Methods
1641
//===----------------------------------------------------------------------===//
1642
1643
112M
unsigned AttributeList::getNumAttrSets() const {
1644
112M
  return pImpl ? pImpl->NumAttrSets : 0;
1645
112M
}
1646
1647
0
void AttributeList::print(raw_ostream &O) const {
1648
0
  O << "AttributeList[\n";
1649
1650
0
  for (unsigned i : indexes()) {
1651
0
    if (!getAttributes(i).hasAttributes())
1652
0
      continue;
1653
0
    O << "  { ";
1654
0
    switch (i) {
1655
0
    case AttrIndex::ReturnIndex:
1656
0
      O << "return";
1657
0
      break;
1658
0
    case AttrIndex::FunctionIndex:
1659
0
      O << "function";
1660
0
      break;
1661
0
    default:
1662
0
      O << "arg(" << i - AttrIndex::FirstArgIndex << ")";
1663
0
    }
1664
0
    O << " => " << getAsString(i) << " }\n";
1665
0
  }
1666
1667
0
  O << "]\n";
1668
0
}
1669
1670
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
1671
0
LLVM_DUMP_METHOD void AttributeList::dump() const { print(dbgs()); }
1672
#endif
1673
1674
//===----------------------------------------------------------------------===//
1675
// AttrBuilder Method Implementations
1676
//===----------------------------------------------------------------------===//
1677
1678
125M
AttrBuilder::AttrBuilder(LLVMContext &Ctx, AttributeSet AS) : Ctx(Ctx) {
1679
125M
  append_range(Attrs, AS);
1680
125M
  assert(is_sorted(Attrs) && "AttributeSet should be sorted");
1681
125M
}
1682
1683
61.1k
void AttrBuilder::clear() { Attrs.clear(); }
1684
1685
/// Attribute comparator that only compares attribute keys. Enum attributes are
1686
/// sorted before string attributes.
1687
struct AttributeComparator {
1688
0
  bool operator()(Attribute A0, Attribute A1) const {
1689
0
    bool A0IsString = A0.isStringAttribute();
1690
0
    bool A1IsString = A1.isStringAttribute();
1691
0
    if (A0IsString) {
1692
0
      if (A1IsString)
1693
0
        return A0.getKindAsString() < A1.getKindAsString();
1694
0
      else
1695
0
        return false;
1696
0
    }
1697
0
    if (A1IsString)
1698
0
      return true;
1699
0
    return A0.getKindAsEnum() < A1.getKindAsEnum();
1700
0
  }
1701
458k
  bool operator()(Attribute A0, Attribute::AttrKind Kind) const {
1702
458k
    if (A0.isStringAttribute())
1703
71.3k
      return false;
1704
386k
    return A0.getKindAsEnum() < Kind;
1705
458k
  }
1706
2.09M
  bool operator()(Attribute A0, StringRef Kind) const {
1707
2.09M
    if (A0.isStringAttribute())
1708
1.50M
      return A0.getKindAsString() < Kind;
1709
588k
    return true;
1710
2.09M
  }
1711
};
1712
1713
template <typename K>
1714
static void addAttributeImpl(SmallVectorImpl<Attribute> &Attrs, K Kind,
1715
896k
                             Attribute Attr) {
1716
896k
  auto It = lower_bound(Attrs, Kind, AttributeComparator());
1717
896k
  if (It != Attrs.end() && It->hasAttribute(Kind))
1718
281k
    std::swap(*It, Attr);
1719
615k
  else
1720
615k
    Attrs.insert(It, Attr);
1721
896k
}
Attributes.cpp:void addAttributeImpl<llvm::StringRef>(llvm::SmallVectorImpl<llvm::Attribute>&, llvm::StringRef, llvm::Attribute)
Line
Count
Source
1715
410k
                             Attribute Attr) {
1716
410k
  auto It = lower_bound(Attrs, Kind, AttributeComparator());
1717
410k
  if (It != Attrs.end() && It->hasAttribute(Kind))
1718
261k
    std::swap(*It, Attr);
1719
148k
  else
1720
148k
    Attrs.insert(It, Attr);
1721
410k
}
Attributes.cpp:void addAttributeImpl<llvm::Attribute::AttrKind>(llvm::SmallVectorImpl<llvm::Attribute>&, llvm::Attribute::AttrKind, llvm::Attribute)
Line
Count
Source
1715
486k
                             Attribute Attr) {
1716
486k
  auto It = lower_bound(Attrs, Kind, AttributeComparator());
1717
486k
  if (It != Attrs.end() && It->hasAttribute(Kind))
1718
19.8k
    std::swap(*It, Attr);
1719
466k
  else
1720
466k
    Attrs.insert(It, Attr);
1721
486k
}
1722
1723
261k
AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
1724
261k
  if (Attr.isStringAttribute())
1725
13.7k
    addAttributeImpl(Attrs, Attr.getKindAsString(), Attr);
1726
247k
  else
1727
247k
    addAttributeImpl(Attrs, Attr.getKindAsEnum(), Attr);
1728
261k
  return *this;
1729
261k
}
1730
1731
238k
AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Kind) {
1732
238k
  addAttributeImpl(Attrs, Kind, Attribute::get(Ctx, Kind));
1733
238k
  return *this;
1734
238k
}
1735
1736
396k
AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1737
396k
  addAttributeImpl(Attrs, A, Attribute::get(Ctx, A, V));
1738
396k
  return *this;
1739
396k
}
1740
1741
209k
AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
1742
209k
  assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1743
0
  auto It = lower_bound(Attrs, Val, AttributeComparator());
1744
209k
  if (It != Attrs.end() && It->hasAttribute(Val))
1745
2.05k
    Attrs.erase(It);
1746
209k
  return *this;
1747
209k
}
1748
1749
518
AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
1750
518
  auto It = lower_bound(Attrs, A, AttributeComparator());
1751
518
  if (It != Attrs.end() && It->hasAttribute(A))
1752
518
    Attrs.erase(It);
1753
518
  return *this;
1754
518
}
1755
1756
std::optional<uint64_t>
1757
4.70k
AttrBuilder::getRawIntAttr(Attribute::AttrKind Kind) const {
1758
4.70k
  assert(Attribute::isIntAttrKind(Kind) && "Not an int attribute");
1759
0
  Attribute A = getAttribute(Kind);
1760
4.70k
  if (A.isValid())
1761
0
    return A.getValueAsInt();
1762
4.70k
  return std::nullopt;
1763
4.70k
}
1764
1765
AttrBuilder &AttrBuilder::addRawIntAttr(Attribute::AttrKind Kind,
1766
40.0k
                                        uint64_t Value) {
1767
40.0k
  return addAttribute(Attribute::get(Ctx, Kind, Value));
1768
40.0k
}
1769
1770
std::optional<std::pair<unsigned, std::optional<unsigned>>>
1771
0
AttrBuilder::getAllocSizeArgs() const {
1772
0
  Attribute A = getAttribute(Attribute::AllocSize);
1773
0
  if (A.isValid())
1774
0
    return A.getAllocSizeArgs();
1775
0
  return std::nullopt;
1776
0
}
1777
1778
4.44k
AttrBuilder &AttrBuilder::addAlignmentAttr(MaybeAlign Align) {
1779
4.44k
  if (!Align)
1780
0
    return *this;
1781
1782
4.44k
  assert(*Align <= llvm::Value::MaximumAlignment && "Alignment too large.");
1783
0
  return addRawIntAttr(Attribute::Alignment, Align->value());
1784
4.44k
}
1785
1786
1
AttrBuilder &AttrBuilder::addStackAlignmentAttr(MaybeAlign Align) {
1787
  // Default alignment, allow the target to define how to align it.
1788
1
  if (!Align)
1789
0
    return *this;
1790
1791
1
  assert(*Align <= 0x100 && "Alignment too large.");
1792
0
  return addRawIntAttr(Attribute::StackAlignment, Align->value());
1793
1
}
1794
1795
1.06k
AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1796
1.06k
  if (Bytes == 0) return *this;
1797
1798
1.06k
  return addRawIntAttr(Attribute::Dereferenceable, Bytes);
1799
1.06k
}
1800
1801
195
AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1802
195
  if (Bytes == 0)
1803
0
    return *this;
1804
1805
195
  return addRawIntAttr(Attribute::DereferenceableOrNull, Bytes);
1806
195
}
1807
1808
AttrBuilder &
1809
AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1810
0
                              const std::optional<unsigned> &NumElems) {
1811
0
  return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1812
0
}
1813
1814
471
AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1815
  // (0, 0) is our "not present" value, so we need to check for it here.
1816
471
  assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1817
0
  return addRawIntAttr(Attribute::AllocSize, RawArgs);
1818
471
}
1819
1820
AttrBuilder &AttrBuilder::addVScaleRangeAttr(unsigned MinValue,
1821
0
                                             std::optional<unsigned> MaxValue) {
1822
0
  return addVScaleRangeAttrFromRawRepr(packVScaleRangeArgs(MinValue, MaxValue));
1823
0
}
1824
1825
0
AttrBuilder &AttrBuilder::addVScaleRangeAttrFromRawRepr(uint64_t RawArgs) {
1826
  // (0, 0) is not present hence ignore this case
1827
0
  if (RawArgs == 0)
1828
0
    return *this;
1829
1830
0
  return addRawIntAttr(Attribute::VScaleRange, RawArgs);
1831
0
}
1832
1833
5.85k
AttrBuilder &AttrBuilder::addUWTableAttr(UWTableKind Kind) {
1834
5.85k
  if (Kind == UWTableKind::None)
1835
0
    return *this;
1836
5.85k
  return addRawIntAttr(Attribute::UWTable, uint64_t(Kind));
1837
5.85k
}
1838
1839
28.0k
AttrBuilder &AttrBuilder::addMemoryAttr(MemoryEffects ME) {
1840
28.0k
  return addRawIntAttr(Attribute::Memory, ME.toIntValue());
1841
28.0k
}
1842
1843
1
AttrBuilder &AttrBuilder::addNoFPClassAttr(FPClassTest Mask) {
1844
1
  if (Mask == fcNone)
1845
0
    return *this;
1846
1847
1
  return addRawIntAttr(Attribute::NoFPClass, Mask);
1848
1
}
1849
1850
0
AttrBuilder &AttrBuilder::addAllocKindAttr(AllocFnKind Kind) {
1851
0
  return addRawIntAttr(Attribute::AllocKind, static_cast<uint64_t>(Kind));
1852
0
}
1853
1854
0
Type *AttrBuilder::getTypeAttr(Attribute::AttrKind Kind) const {
1855
0
  assert(Attribute::isTypeAttrKind(Kind) && "Not a type attribute");
1856
0
  Attribute A = getAttribute(Kind);
1857
0
  return A.isValid() ? A.getValueAsType() : nullptr;
1858
0
}
1859
1860
1.47k
AttrBuilder &AttrBuilder::addTypeAttr(Attribute::AttrKind Kind, Type *Ty) {
1861
1.47k
  return addAttribute(Attribute::get(Ctx, Kind, Ty));
1862
1.47k
}
1863
1864
51
AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1865
51
  return addTypeAttr(Attribute::ByVal, Ty);
1866
51
}
1867
1868
40
AttrBuilder &AttrBuilder::addStructRetAttr(Type *Ty) {
1869
40
  return addTypeAttr(Attribute::StructRet, Ty);
1870
40
}
1871
1872
0
AttrBuilder &AttrBuilder::addByRefAttr(Type *Ty) {
1873
0
  return addTypeAttr(Attribute::ByRef, Ty);
1874
0
}
1875
1876
0
AttrBuilder &AttrBuilder::addPreallocatedAttr(Type *Ty) {
1877
0
  return addTypeAttr(Attribute::Preallocated, Ty);
1878
0
}
1879
1880
21
AttrBuilder &AttrBuilder::addInAllocaAttr(Type *Ty) {
1881
21
  return addTypeAttr(Attribute::InAlloca, Ty);
1882
21
}
1883
1884
111M
AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1885
  // TODO: Could make this O(n) as we're merging two sorted lists.
1886
111M
  for (const auto &I : B.attrs())
1887
208k
    addAttribute(I);
1888
1889
111M
  return *this;
1890
111M
}
1891
1892
109
AttrBuilder &AttrBuilder::remove(const AttributeMask &AM) {
1893
109
  erase_if(Attrs, [&](Attribute A) { return AM.contains(A); });
1894
109
  return *this;
1895
109
}
1896
1897
13.5M
bool AttrBuilder::overlaps(const AttributeMask &AM) const {
1898
13.5M
  return any_of(Attrs, [&](Attribute A) { return AM.contains(A); });
1899
13.5M
}
1900
1901
76.0k
Attribute AttrBuilder::getAttribute(Attribute::AttrKind A) const {
1902
76.0k
  assert((unsigned)A < Attribute::EndAttrKinds && "Attribute out of range!");
1903
0
  auto It = lower_bound(Attrs, A, AttributeComparator());
1904
76.0k
  if (It != Attrs.end() && It->hasAttribute(A))
1905
21
    return *It;
1906
76.0k
  return {};
1907
76.0k
}
1908
1909
332k
Attribute AttrBuilder::getAttribute(StringRef A) const {
1910
332k
  auto It = lower_bound(Attrs, A, AttributeComparator());
1911
332k
  if (It != Attrs.end() && It->hasAttribute(A))
1912
518
    return *It;
1913
331k
  return {};
1914
332k
}
1915
1916
71.3k
bool AttrBuilder::contains(Attribute::AttrKind A) const {
1917
71.3k
  return getAttribute(A).isValid();
1918
71.3k
}
1919
1920
110k
bool AttrBuilder::contains(StringRef A) const {
1921
110k
  return getAttribute(A).isValid();
1922
110k
}
1923
1924
350
bool AttrBuilder::operator==(const AttrBuilder &B) const {
1925
350
  return Attrs == B.Attrs;
1926
350
}
1927
1928
//===----------------------------------------------------------------------===//
1929
// AttributeFuncs Function Defintions
1930
//===----------------------------------------------------------------------===//
1931
1932
/// Returns true if this is a type legal for the 'nofpclass' attribute. This
1933
/// follows the same type rules as FPMathOperator.
1934
///
1935
/// TODO: Consider relaxing to any FP type struct fields.
1936
14.0M
bool AttributeFuncs::isNoFPClassCompatibleType(Type *Ty) {
1937
14.0M
  while (ArrayType *ArrTy = dyn_cast<ArrayType>(Ty))
1938
16.0k
    Ty = ArrTy->getElementType();
1939
14.0M
  return Ty->isFPOrFPVectorTy();
1940
14.0M
}
1941
1942
/// Which attributes cannot be applied to a type.
1943
AttributeMask AttributeFuncs::typeIncompatible(Type *Ty,
1944
14.0M
                                               AttributeSafetyKind ASK) {
1945
14.0M
  AttributeMask Incompatible;
1946
1947
14.0M
  if (!Ty->isIntegerTy()) {
1948
    // Attributes that only apply to integers.
1949
8.84M
    if (ASK & ASK_SAFE_TO_DROP)
1950
8.84M
      Incompatible.addAttribute(Attribute::AllocAlign);
1951
8.84M
    if (ASK & ASK_UNSAFE_TO_DROP)
1952
8.84M
      Incompatible.addAttribute(Attribute::SExt).addAttribute(Attribute::ZExt);
1953
8.84M
  }
1954
1955
14.0M
  if (!Ty->isPointerTy()) {
1956
    // Attributes that only apply to pointers.
1957
12.5M
    if (ASK & ASK_SAFE_TO_DROP)
1958
12.5M
      Incompatible.addAttribute(Attribute::NoAlias)
1959
12.5M
          .addAttribute(Attribute::NoCapture)
1960
12.5M
          .addAttribute(Attribute::NonNull)
1961
12.5M
          .addAttribute(Attribute::ReadNone)
1962
12.5M
          .addAttribute(Attribute::ReadOnly)
1963
12.5M
          .addAttribute(Attribute::Dereferenceable)
1964
12.5M
          .addAttribute(Attribute::DereferenceableOrNull)
1965
12.5M
          .addAttribute(Attribute::Writable)
1966
12.5M
          .addAttribute(Attribute::DeadOnUnwind);
1967
12.5M
    if (ASK & ASK_UNSAFE_TO_DROP)
1968
12.5M
      Incompatible.addAttribute(Attribute::Nest)
1969
12.5M
          .addAttribute(Attribute::SwiftError)
1970
12.5M
          .addAttribute(Attribute::Preallocated)
1971
12.5M
          .addAttribute(Attribute::InAlloca)
1972
12.5M
          .addAttribute(Attribute::ByVal)
1973
12.5M
          .addAttribute(Attribute::StructRet)
1974
12.5M
          .addAttribute(Attribute::ByRef)
1975
12.5M
          .addAttribute(Attribute::ElementType)
1976
12.5M
          .addAttribute(Attribute::AllocatedPointer);
1977
12.5M
  }
1978
1979
    // Attributes that only apply to pointers or vectors of pointers.
1980
14.0M
  if (!Ty->isPtrOrPtrVectorTy()) {
1981
12.5M
    if (ASK & ASK_SAFE_TO_DROP)
1982
12.5M
      Incompatible.addAttribute(Attribute::Alignment);
1983
12.5M
  }
1984
1985
14.0M
  if (ASK & ASK_SAFE_TO_DROP) {
1986
14.0M
    if (!isNoFPClassCompatibleType(Ty))
1987
10.1M
      Incompatible.addAttribute(Attribute::NoFPClass);
1988
14.0M
  }
1989
1990
  // Some attributes can apply to all "values" but there are no `void` values.
1991
14.0M
  if (Ty->isVoidTy()) {
1992
839k
    if (ASK & ASK_SAFE_TO_DROP)
1993
839k
      Incompatible.addAttribute(Attribute::NoUndef);
1994
839k
  }
1995
1996
14.0M
  return Incompatible;
1997
14.0M
}
1998
1999
97
AttributeMask AttributeFuncs::getUBImplyingAttributes() {
2000
97
  AttributeMask AM;
2001
97
  AM.addAttribute(Attribute::NoUndef);
2002
97
  AM.addAttribute(Attribute::Dereferenceable);
2003
97
  AM.addAttribute(Attribute::DereferenceableOrNull);
2004
97
  return AM;
2005
97
}
2006
2007
/// Callees with dynamic denormal modes are compatible with any caller mode.
2008
static bool denormModeCompatible(DenormalMode CallerMode,
2009
0
                                 DenormalMode CalleeMode) {
2010
0
  if (CallerMode == CalleeMode || CalleeMode == DenormalMode::getDynamic())
2011
0
    return true;
2012
2013
  // If they don't exactly match, it's OK if the mismatched component is
2014
  // dynamic.
2015
0
  if (CalleeMode.Input == CallerMode.Input &&
2016
0
      CalleeMode.Output == DenormalMode::Dynamic)
2017
0
    return true;
2018
2019
0
  if (CalleeMode.Output == CallerMode.Output &&
2020
0
      CalleeMode.Input == DenormalMode::Dynamic)
2021
0
    return true;
2022
0
  return false;
2023
0
}
2024
2025
0
static bool checkDenormMode(const Function &Caller, const Function &Callee) {
2026
0
  DenormalMode CallerMode = Caller.getDenormalModeRaw();
2027
0
  DenormalMode CalleeMode = Callee.getDenormalModeRaw();
2028
2029
0
  if (denormModeCompatible(CallerMode, CalleeMode)) {
2030
0
    DenormalMode CallerModeF32 = Caller.getDenormalModeF32Raw();
2031
0
    DenormalMode CalleeModeF32 = Callee.getDenormalModeF32Raw();
2032
0
    if (CallerModeF32 == DenormalMode::getInvalid())
2033
0
      CallerModeF32 = CallerMode;
2034
0
    if (CalleeModeF32 == DenormalMode::getInvalid())
2035
0
      CalleeModeF32 = CalleeMode;
2036
0
    return denormModeCompatible(CallerModeF32, CalleeModeF32);
2037
0
  }
2038
2039
0
  return false;
2040
0
}
2041
2042
template<typename AttrClass>
2043
0
static bool isEqual(const Function &Caller, const Function &Callee) {
2044
0
  return Caller.getFnAttribute(AttrClass::getKind()) ==
2045
0
         Callee.getFnAttribute(AttrClass::getKind());
2046
0
}
Unexecuted instantiation: Attributes.cpp:bool isEqual<SanitizeAddressAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<SanitizeThreadAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<SanitizeMemoryAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<SanitizeHWAddressAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<SanitizeMemTagAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<SafeStackAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<ShadowCallStackAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<UseSampleProfileAttr>(llvm::Function const&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:bool isEqual<NoProfileAttr>(llvm::Function const&, llvm::Function const&)
2047
2048
/// Compute the logical AND of the attributes of the caller and the
2049
/// callee.
2050
///
2051
/// This function sets the caller's attribute to false if the callee's attribute
2052
/// is false.
2053
template<typename AttrClass>
2054
0
static void setAND(Function &Caller, const Function &Callee) {
2055
0
  if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
2056
0
      !AttrClass::isSet(Callee, AttrClass::getKind()))
2057
0
    AttrClass::set(Caller, AttrClass::getKind(), false);
2058
0
}
Unexecuted instantiation: Attributes.cpp:void setAND<LessPreciseFPMADAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setAND<NoInfsFPMathAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setAND<NoNansFPMathAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setAND<ApproxFuncFPMathAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setAND<NoSignedZerosFPMathAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setAND<UnsafeFPMathAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setAND<MustProgressAttr>(llvm::Function&, llvm::Function const&)
2059
2060
/// Compute the logical OR of the attributes of the caller and the
2061
/// callee.
2062
///
2063
/// This function sets the caller's attribute to true if the callee's attribute
2064
/// is true.
2065
template<typename AttrClass>
2066
0
static void setOR(Function &Caller, const Function &Callee) {
2067
0
  if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
2068
0
      AttrClass::isSet(Callee, AttrClass::getKind()))
2069
0
    AttrClass::set(Caller, AttrClass::getKind(), true);
2070
0
}
Unexecuted instantiation: Attributes.cpp:void setOR<NoImplicitFloatAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setOR<NoJumpTablesAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setOR<ProfileSampleAccurateAttr>(llvm::Function&, llvm::Function const&)
Unexecuted instantiation: Attributes.cpp:void setOR<SpeculativeLoadHardeningAttr>(llvm::Function&, llvm::Function const&)
2071
2072
/// If the inlined function had a higher stack protection level than the
2073
/// calling function, then bump up the caller's stack protection level.
2074
0
static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
2075
  // If the calling function has *no* stack protection level (e.g. it was built
2076
  // with Clang's -fno-stack-protector or no_stack_protector attribute), don't
2077
  // change it as that could change the program's semantics.
2078
0
  if (!Caller.hasStackProtectorFnAttr())
2079
0
    return;
2080
2081
  // If upgrading the SSP attribute, clear out the old SSP Attributes first.
2082
  // Having multiple SSP attributes doesn't actually hurt, but it adds useless
2083
  // clutter to the IR.
2084
0
  AttributeMask OldSSPAttr;
2085
0
  OldSSPAttr.addAttribute(Attribute::StackProtect)
2086
0
      .addAttribute(Attribute::StackProtectStrong)
2087
0
      .addAttribute(Attribute::StackProtectReq);
2088
2089
0
  if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
2090
0
    Caller.removeFnAttrs(OldSSPAttr);
2091
0
    Caller.addFnAttr(Attribute::StackProtectReq);
2092
0
  } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
2093
0
             !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
2094
0
    Caller.removeFnAttrs(OldSSPAttr);
2095
0
    Caller.addFnAttr(Attribute::StackProtectStrong);
2096
0
  } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
2097
0
             !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
2098
0
             !Caller.hasFnAttribute(Attribute::StackProtectStrong))
2099
0
    Caller.addFnAttr(Attribute::StackProtect);
2100
0
}
2101
2102
/// If the inlined function required stack probes, then ensure that
2103
/// the calling function has those too.
2104
0
static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
2105
0
  if (!Caller.hasFnAttribute("probe-stack") &&
2106
0
      Callee.hasFnAttribute("probe-stack")) {
2107
0
    Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
2108
0
  }
2109
0
}
2110
2111
/// If the inlined function defines the size of guard region
2112
/// on the stack, then ensure that the calling function defines a guard region
2113
/// that is no larger.
2114
static void
2115
0
adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
2116
0
  Attribute CalleeAttr = Callee.getFnAttribute("stack-probe-size");
2117
0
  if (CalleeAttr.isValid()) {
2118
0
    Attribute CallerAttr = Caller.getFnAttribute("stack-probe-size");
2119
0
    if (CallerAttr.isValid()) {
2120
0
      uint64_t CallerStackProbeSize, CalleeStackProbeSize;
2121
0
      CallerAttr.getValueAsString().getAsInteger(0, CallerStackProbeSize);
2122
0
      CalleeAttr.getValueAsString().getAsInteger(0, CalleeStackProbeSize);
2123
2124
0
      if (CallerStackProbeSize > CalleeStackProbeSize) {
2125
0
        Caller.addFnAttr(CalleeAttr);
2126
0
      }
2127
0
    } else {
2128
0
      Caller.addFnAttr(CalleeAttr);
2129
0
    }
2130
0
  }
2131
0
}
2132
2133
/// If the inlined function defines a min legal vector width, then ensure
2134
/// the calling function has the same or larger min legal vector width. If the
2135
/// caller has the attribute, but the callee doesn't, we need to remove the
2136
/// attribute from the caller since we can't make any guarantees about the
2137
/// caller's requirements.
2138
/// This function is called after the inlining decision has been made so we have
2139
/// to merge the attribute this way. Heuristics that would use
2140
/// min-legal-vector-width to determine inline compatibility would need to be
2141
/// handled as part of inline cost analysis.
2142
static void
2143
0
adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
2144
0
  Attribute CallerAttr = Caller.getFnAttribute("min-legal-vector-width");
2145
0
  if (CallerAttr.isValid()) {
2146
0
    Attribute CalleeAttr = Callee.getFnAttribute("min-legal-vector-width");
2147
0
    if (CalleeAttr.isValid()) {
2148
0
      uint64_t CallerVectorWidth, CalleeVectorWidth;
2149
0
      CallerAttr.getValueAsString().getAsInteger(0, CallerVectorWidth);
2150
0
      CalleeAttr.getValueAsString().getAsInteger(0, CalleeVectorWidth);
2151
0
      if (CallerVectorWidth < CalleeVectorWidth)
2152
0
        Caller.addFnAttr(CalleeAttr);
2153
0
    } else {
2154
      // If the callee doesn't have the attribute then we don't know anything
2155
      // and must drop the attribute from the caller.
2156
0
      Caller.removeFnAttr("min-legal-vector-width");
2157
0
    }
2158
0
  }
2159
0
}
2160
2161
/// If the inlined function has null_pointer_is_valid attribute,
2162
/// set this attribute in the caller post inlining.
2163
static void
2164
0
adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
2165
0
  if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
2166
0
    Caller.addFnAttr(Attribute::NullPointerIsValid);
2167
0
  }
2168
0
}
2169
2170
struct EnumAttr {
2171
  static bool isSet(const Function &Fn,
2172
0
                    Attribute::AttrKind Kind) {
2173
0
    return Fn.hasFnAttribute(Kind);
2174
0
  }
2175
2176
  static void set(Function &Fn,
2177
0
                  Attribute::AttrKind Kind, bool Val) {
2178
0
    if (Val)
2179
0
      Fn.addFnAttr(Kind);
2180
0
    else
2181
0
      Fn.removeFnAttr(Kind);
2182
0
  }
2183
};
2184
2185
struct StrBoolAttr {
2186
  static bool isSet(const Function &Fn,
2187
0
                    StringRef Kind) {
2188
0
    auto A = Fn.getFnAttribute(Kind);
2189
0
    return A.getValueAsString().equals("true");
2190
0
  }
2191
2192
  static void set(Function &Fn,
2193
0
                  StringRef Kind, bool Val) {
2194
0
    Fn.addFnAttr(Kind, Val ? "true" : "false");
2195
0
  }
2196
};
2197
2198
#define GET_ATTR_NAMES
2199
#define ATTRIBUTE_ENUM(ENUM_NAME, DISPLAY_NAME)                                \
2200
  struct ENUM_NAME##Attr : EnumAttr {                                          \
2201
0
    static enum Attribute::AttrKind getKind() {                                \
2202
0
      return llvm::Attribute::ENUM_NAME;                                       \
2203
0
    }                                                                          \
Unexecuted instantiation: SanitizeAddressAttr::getKind()
Unexecuted instantiation: SanitizeThreadAttr::getKind()
Unexecuted instantiation: SanitizeMemoryAttr::getKind()
Unexecuted instantiation: SanitizeHWAddressAttr::getKind()
Unexecuted instantiation: SanitizeMemTagAttr::getKind()
Unexecuted instantiation: SafeStackAttr::getKind()
Unexecuted instantiation: ShadowCallStackAttr::getKind()
Unexecuted instantiation: NoProfileAttr::getKind()
Unexecuted instantiation: NoImplicitFloatAttr::getKind()
Unexecuted instantiation: SpeculativeLoadHardeningAttr::getKind()
Unexecuted instantiation: MustProgressAttr::getKind()
Unexecuted instantiation: AllocAlignAttr::getKind()
Unexecuted instantiation: AllocatedPointerAttr::getKind()
Unexecuted instantiation: AlwaysInlineAttr::getKind()
Unexecuted instantiation: BuiltinAttr::getKind()
Unexecuted instantiation: ColdAttr::getKind()
Unexecuted instantiation: ConvergentAttr::getKind()
Unexecuted instantiation: CoroDestroyOnlyWhenCompleteAttr::getKind()
Unexecuted instantiation: DeadOnUnwindAttr::getKind()
Unexecuted instantiation: DisableSanitizerInstrumentationAttr::getKind()
Unexecuted instantiation: FnRetThunkExternAttr::getKind()
Unexecuted instantiation: HotAttr::getKind()
Unexecuted instantiation: ImmArgAttr::getKind()
Unexecuted instantiation: InRegAttr::getKind()
Unexecuted instantiation: InlineHintAttr::getKind()
Unexecuted instantiation: JumpTableAttr::getKind()
Unexecuted instantiation: MinSizeAttr::getKind()
Unexecuted instantiation: NakedAttr::getKind()
Unexecuted instantiation: NestAttr::getKind()
Unexecuted instantiation: NoAliasAttr::getKind()
Unexecuted instantiation: NoBuiltinAttr::getKind()
Unexecuted instantiation: NoCallbackAttr::getKind()
Unexecuted instantiation: NoCaptureAttr::getKind()
Unexecuted instantiation: NoCfCheckAttr::getKind()
Unexecuted instantiation: NoDuplicateAttr::getKind()
Unexecuted instantiation: NoFreeAttr::getKind()
Unexecuted instantiation: NoInlineAttr::getKind()
Unexecuted instantiation: NoMergeAttr::getKind()
Unexecuted instantiation: NoRecurseAttr::getKind()
Unexecuted instantiation: NoRedZoneAttr::getKind()
Unexecuted instantiation: NoReturnAttr::getKind()
Unexecuted instantiation: NoSanitizeBoundsAttr::getKind()
Unexecuted instantiation: NoSanitizeCoverageAttr::getKind()
Unexecuted instantiation: NoSyncAttr::getKind()
Unexecuted instantiation: NoUndefAttr::getKind()
Unexecuted instantiation: NoUnwindAttr::getKind()
Unexecuted instantiation: NonLazyBindAttr::getKind()
Unexecuted instantiation: NonNullAttr::getKind()
Unexecuted instantiation: NullPointerIsValidAttr::getKind()
Unexecuted instantiation: OptForFuzzingAttr::getKind()
Unexecuted instantiation: OptimizeForDebuggingAttr::getKind()
Unexecuted instantiation: OptimizeForSizeAttr::getKind()
Unexecuted instantiation: OptimizeNoneAttr::getKind()
Unexecuted instantiation: PresplitCoroutineAttr::getKind()
Unexecuted instantiation: ReadNoneAttr::getKind()
Unexecuted instantiation: ReadOnlyAttr::getKind()
Unexecuted instantiation: ReturnedAttr::getKind()
Unexecuted instantiation: ReturnsTwiceAttr::getKind()
Unexecuted instantiation: SExtAttr::getKind()
Unexecuted instantiation: SkipProfileAttr::getKind()
Unexecuted instantiation: SpeculatableAttr::getKind()
Unexecuted instantiation: StackProtectAttr::getKind()
Unexecuted instantiation: StackProtectReqAttr::getKind()
Unexecuted instantiation: StackProtectStrongAttr::getKind()
Unexecuted instantiation: StrictFPAttr::getKind()
Unexecuted instantiation: SwiftAsyncAttr::getKind()
Unexecuted instantiation: SwiftErrorAttr::getKind()
Unexecuted instantiation: SwiftSelfAttr::getKind()
Unexecuted instantiation: WillReturnAttr::getKind()
Unexecuted instantiation: WritableAttr::getKind()
Unexecuted instantiation: WriteOnlyAttr::getKind()
Unexecuted instantiation: ZExtAttr::getKind()
Unexecuted instantiation: ByRefAttr::getKind()
Unexecuted instantiation: ByValAttr::getKind()
Unexecuted instantiation: ElementTypeAttr::getKind()
Unexecuted instantiation: InAllocaAttr::getKind()
Unexecuted instantiation: PreallocatedAttr::getKind()
Unexecuted instantiation: StructRetAttr::getKind()
Unexecuted instantiation: AlignmentAttr::getKind()
Unexecuted instantiation: AllocKindAttr::getKind()
Unexecuted instantiation: AllocSizeAttr::getKind()
Unexecuted instantiation: DereferenceableAttr::getKind()
Unexecuted instantiation: DereferenceableOrNullAttr::getKind()
Unexecuted instantiation: MemoryAttr::getKind()
Unexecuted instantiation: NoFPClassAttr::getKind()
Unexecuted instantiation: StackAlignmentAttr::getKind()
Unexecuted instantiation: UWTableAttr::getKind()
Unexecuted instantiation: VScaleRangeAttr::getKind()
2204
  };
2205
#define ATTRIBUTE_STRBOOL(ENUM_NAME, DISPLAY_NAME)                             \
2206
  struct ENUM_NAME##Attr : StrBoolAttr {                                       \
2207
0
    static StringRef getKind() { return #DISPLAY_NAME; }                       \
Unexecuted instantiation: UseSampleProfileAttr::getKind()
Unexecuted instantiation: LessPreciseFPMADAttr::getKind()
Unexecuted instantiation: NoInfsFPMathAttr::getKind()
Unexecuted instantiation: NoNansFPMathAttr::getKind()
Unexecuted instantiation: ApproxFuncFPMathAttr::getKind()
Unexecuted instantiation: NoSignedZerosFPMathAttr::getKind()
Unexecuted instantiation: UnsafeFPMathAttr::getKind()
Unexecuted instantiation: NoJumpTablesAttr::getKind()
Unexecuted instantiation: ProfileSampleAccurateAttr::getKind()
Unexecuted instantiation: NoInlineLineTablesAttr::getKind()
2208
  };
2209
#include "llvm/IR/Attributes.inc"
2210
2211
#define GET_ATTR_COMPAT_FUNC
2212
#include "llvm/IR/Attributes.inc"
2213
2214
bool AttributeFuncs::areInlineCompatible(const Function &Caller,
2215
0
                                         const Function &Callee) {
2216
0
  return hasCompatibleFnAttrs(Caller, Callee);
2217
0
}
2218
2219
bool AttributeFuncs::areOutlineCompatible(const Function &A,
2220
0
                                          const Function &B) {
2221
0
  return hasCompatibleFnAttrs(A, B);
2222
0
}
2223
2224
void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
2225
0
                                                const Function &Callee) {
2226
0
  mergeFnAttrs(Caller, Callee);
2227
0
}
2228
2229
void AttributeFuncs::mergeAttributesForOutlining(Function &Base,
2230
0
                                                const Function &ToMerge) {
2231
2232
  // We merge functions so that they meet the most general case.
2233
  // For example, if the NoNansFPMathAttr is set in one function, but not in
2234
  // the other, in the merged function we can say that the NoNansFPMathAttr
2235
  // is not set.
2236
  // However if we have the SpeculativeLoadHardeningAttr set true in one
2237
  // function, but not the other, we make sure that the function retains
2238
  // that aspect in the merged function.
2239
0
  mergeFnAttrs(Base, ToMerge);
2240
0
}
2241
2242
void AttributeFuncs::updateMinLegalVectorWidthAttr(Function &Fn,
2243
0
                                                   uint64_t Width) {
2244
0
  Attribute Attr = Fn.getFnAttribute("min-legal-vector-width");
2245
0
  if (Attr.isValid()) {
2246
0
    uint64_t OldWidth;
2247
0
    Attr.getValueAsString().getAsInteger(0, OldWidth);
2248
0
    if (Width > OldWidth)
2249
0
      Fn.addFnAttr("min-legal-vector-width", llvm::utostr(Width));
2250
0
  }
2251
0
}