blob: 99fc447c5af9cf3f2c4c4de9b68d7913e38418dc [file] [log] [blame]
Eugene Zelenkodeaf6952017-02-17 00:00:09 +00001//===- Attributes.cpp - Implement AttributesList --------------------------===//
Chris Lattner3e13b8c2008-01-02 23:42:30 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Chris Lattner3e13b8c2008-01-02 23:42:30 +00006//
7//===----------------------------------------------------------------------===//
8//
Bill Wendlingec454542013-01-28 21:55:20 +00009// \file
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000010// This file implements the Attribute, AttributeImpl, AttrBuilder,
Reid Klecknerb5180542017-03-21 16:57:19 +000011// AttributeListImpl, and AttributeList classes.
Chris Lattner3e13b8c2008-01-02 23:42:30 +000012//
13//===----------------------------------------------------------------------===//
14
Chandler Carruth6bda14b2017-06-06 11:49:48 +000015#include "llvm/IR/Attributes.h"
Bill Wendling4607f4b2012-12-20 01:36:59 +000016#include "AttributeImpl.h"
Bill Wendlinge38b8042012-09-26 21:07:29 +000017#include "LLVMContextImpl.h"
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000018#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/FoldingSet.h"
20#include "llvm/ADT/Optional.h"
Benjamin Kramer502b9e12014-04-12 16:15:53 +000021#include "llvm/ADT/STLExtras.h"
Chandler Carruth6bda14b2017-06-06 11:49:48 +000022#include "llvm/ADT/SmallVector.h"
Chandler Carruthed0881b2012-12-03 16:50:05 +000023#include "llvm/ADT/StringExtras.h"
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000024#include "llvm/ADT/StringRef.h"
25#include "llvm/ADT/Twine.h"
Nico Weber432a3882018-04-30 14:59:11 +000026#include "llvm/Config/llvm-config.h"
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000027#include "llvm/IR/Function.h"
28#include "llvm/IR/LLVMContext.h"
Chandler Carruth9fb823b2013-01-02 11:36:10 +000029#include "llvm/IR/Type.h"
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000030#include "llvm/Support/Compiler.h"
David Greenef7014732010-01-05 01:29:58 +000031#include "llvm/Support/Debug.h"
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000032#include "llvm/Support/ErrorHandling.h"
33#include "llvm/Support/MathExtras.h"
Benjamin Kramer1a25d732009-08-23 11:37:21 +000034#include "llvm/Support/raw_ostream.h"
Bill Wendlingd2e493b2013-01-24 00:06:56 +000035#include <algorithm>
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000036#include <cassert>
Eugene Zelenkod761e2c2017-05-15 21:57:41 +000037#include <climits>
38#include <cstddef>
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000039#include <cstdint>
40#include <limits>
Eugene Zelenkodeaf6952017-02-17 00:00:09 +000041#include <string>
42#include <tuple>
43#include <utility>
44
Chris Lattner3e13b8c2008-01-02 23:42:30 +000045using namespace llvm;
46
Chris Lattner8a923e72008-03-12 17:45:29 +000047//===----------------------------------------------------------------------===//
Bill Wendling7707c5a2013-01-29 00:48:16 +000048// Attribute Construction Methods
Chris Lattner8a923e72008-03-12 17:45:29 +000049//===----------------------------------------------------------------------===//
Chris Lattnerd0e1f102008-01-03 00:10:22 +000050
George Burgess IV278199f2016-04-12 01:05:35 +000051// allocsize has two integer arguments, but because they're both 32 bits, we can
52// pack them into one 64-bit value, at the cost of making said value
53// nonsensical.
54//
55// In order to do this, we need to reserve one value of the second (optional)
56// allocsize argument to signify "not present."
George Burgess IV381fc0e2016-08-25 01:05:08 +000057static const unsigned AllocSizeNumElemsNotPresent = -1;
George Burgess IV278199f2016-04-12 01:05:35 +000058
59static uint64_t packAllocSizeArgs(unsigned ElemSizeArg,
60 const Optional<unsigned> &NumElemsArg) {
61 assert((!NumElemsArg.hasValue() ||
62 *NumElemsArg != AllocSizeNumElemsNotPresent) &&
63 "Attempting to pack a reserved value");
64
65 return uint64_t(ElemSizeArg) << 32 |
66 NumElemsArg.getValueOr(AllocSizeNumElemsNotPresent);
67}
68
69static std::pair<unsigned, Optional<unsigned>>
70unpackAllocSizeArgs(uint64_t Num) {
71 unsigned NumElems = Num & std::numeric_limits<unsigned>::max();
72 unsigned ElemSizeArg = Num >> 32;
73
74 Optional<unsigned> NumElemsArg;
75 if (NumElems != AllocSizeNumElemsNotPresent)
76 NumElemsArg = NumElems;
77 return std::make_pair(ElemSizeArg, NumElemsArg);
78}
79
Matt Arsenaulte1cef6e2014-09-03 23:24:31 +000080Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
81 uint64_t Val) {
82 LLVMContextImpl *pImpl = Context.pImpl;
83 FoldingSetNodeID ID;
84 ID.AddInteger(Kind);
Matt Arsenaultfb4308e2014-09-03 23:38:05 +000085 if (Val) ID.AddInteger(Val);
Matt Arsenaulte1cef6e2014-09-03 23:24:31 +000086
87 void *InsertPoint;
88 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
89
90 if (!PA) {
91 // If we didn't find any existing attributes of the same shape then create a
92 // new one and insert it.
Matt Arsenaultfb4308e2014-09-03 23:38:05 +000093 if (!Val)
94 PA = new EnumAttributeImpl(Kind);
95 else
96 PA = new IntAttributeImpl(Kind, Val);
Bill Wendling3f12ac22013-02-05 22:37:24 +000097 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
98 }
99
100 // Return the Attribute that we found or created.
101 return Attribute(PA);
102}
103
104Attribute Attribute::get(LLVMContext &Context, StringRef Kind, StringRef Val) {
105 LLVMContextImpl *pImpl = Context.pImpl;
106 FoldingSetNodeID ID;
107 ID.AddString(Kind);
108 if (!Val.empty()) ID.AddString(Val);
Bill Wendling73ea2de2012-10-08 21:47:17 +0000109
110 void *InsertPoint;
Bill Wendling4607f4b2012-12-20 01:36:59 +0000111 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
Bill Wendling73ea2de2012-10-08 21:47:17 +0000112
113 if (!PA) {
114 // If we didn't find any existing attributes of the same shape then create a
115 // new one and insert it.
Benjamin Kramer741146b2013-07-11 12:13:16 +0000116 PA = new StringAttributeImpl(Kind, Val);
Bill Wendling73ea2de2012-10-08 21:47:17 +0000117 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
118 }
119
Bill Wendlingb9c5b1a2013-02-05 08:09:32 +0000120 // Return the Attribute that we found or created.
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000121 return Attribute(PA);
Bill Wendling73ea2de2012-10-08 21:47:17 +0000122}
123
Tim Northoverb7141202019-05-30 18:48:23 +0000124Attribute Attribute::get(LLVMContext &Context, Attribute::AttrKind Kind,
125 Type *Ty) {
126 LLVMContextImpl *pImpl = Context.pImpl;
127 FoldingSetNodeID ID;
128 ID.AddInteger(Kind);
129 ID.AddPointer(Ty);
130
131 void *InsertPoint;
132 AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
133
134 if (!PA) {
135 // If we didn't find any existing attributes of the same shape then create a
136 // new one and insert it.
137 PA = new TypeAttributeImpl(Kind, Ty);
138 pImpl->AttrsSet.InsertNode(PA, InsertPoint);
139 }
140
141 // Return the Attribute that we found or created.
142 return Attribute(PA);
143}
144
Bill Wendling4bbe9db2013-01-27 22:43:04 +0000145Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
Bill Wendling1c7cc8a2013-01-31 23:16:25 +0000146 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
147 assert(Align <= 0x40000000 && "Alignment too large.");
Bill Wendling3f12ac22013-02-05 22:37:24 +0000148 return get(Context, Alignment, Align);
Bill Wendling4bbe9db2013-01-27 22:43:04 +0000149}
150
151Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
152 uint64_t Align) {
Bill Wendling1c7cc8a2013-01-31 23:16:25 +0000153 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
154 assert(Align <= 0x100 && "Alignment too large.");
Bill Wendling3f12ac22013-02-05 22:37:24 +0000155 return get(Context, StackAlignment, Align);
Bill Wendling4bbe9db2013-01-27 22:43:04 +0000156}
157
Hal Finkelb0407ba2014-07-18 15:51:28 +0000158Attribute Attribute::getWithDereferenceableBytes(LLVMContext &Context,
159 uint64_t Bytes) {
160 assert(Bytes && "Bytes must be non-zero.");
161 return get(Context, Dereferenceable, Bytes);
162}
163
Sanjoy Das31ea6d12015-04-16 20:29:50 +0000164Attribute Attribute::getWithDereferenceableOrNullBytes(LLVMContext &Context,
165 uint64_t Bytes) {
166 assert(Bytes && "Bytes must be non-zero.");
167 return get(Context, DereferenceableOrNull, Bytes);
168}
169
Tim Northoverb7141202019-05-30 18:48:23 +0000170Attribute Attribute::getWithByValType(LLVMContext &Context, Type *Ty) {
171 return get(Context, ByVal, Ty);
172}
173
George Burgess IV278199f2016-04-12 01:05:35 +0000174Attribute
175Attribute::getWithAllocSizeArgs(LLVMContext &Context, unsigned ElemSizeArg,
176 const Optional<unsigned> &NumElemsArg) {
177 assert(!(ElemSizeArg == 0 && NumElemsArg && *NumElemsArg == 0) &&
178 "Invalid allocsize arguments -- given allocsize(0, 0)");
179 return get(Context, AllocSize, packAllocSizeArgs(ElemSizeArg, NumElemsArg));
180}
181
Bill Wendling7707c5a2013-01-29 00:48:16 +0000182//===----------------------------------------------------------------------===//
183// Attribute Accessor Methods
184//===----------------------------------------------------------------------===//
185
Bill Wendling3f12ac22013-02-05 22:37:24 +0000186bool Attribute::isEnumAttribute() const {
187 return pImpl && pImpl->isEnumAttribute();
188}
189
Hal Finkele15442c2014-07-18 06:51:55 +0000190bool Attribute::isIntAttribute() const {
191 return pImpl && pImpl->isIntAttribute();
Bill Wendling3f12ac22013-02-05 22:37:24 +0000192}
193
194bool Attribute::isStringAttribute() const {
195 return pImpl && pImpl->isStringAttribute();
196}
197
Tim Northoverb7141202019-05-30 18:48:23 +0000198bool Attribute::isTypeAttribute() const {
199 return pImpl && pImpl->isTypeAttribute();
200}
201
Bill Wendling3f12ac22013-02-05 22:37:24 +0000202Attribute::AttrKind Attribute::getKindAsEnum() const {
Bill Wendling440e9d82013-07-25 00:34:29 +0000203 if (!pImpl) return None;
Tim Northoverb7141202019-05-30 18:48:23 +0000204 assert((isEnumAttribute() || isIntAttribute() || isTypeAttribute()) &&
Bill Wendling3f12ac22013-02-05 22:37:24 +0000205 "Invalid attribute type to get the kind as an enum!");
George Burgess IV500d3032015-12-16 05:21:02 +0000206 return pImpl->getKindAsEnum();
Bill Wendling3f12ac22013-02-05 22:37:24 +0000207}
208
209uint64_t Attribute::getValueAsInt() const {
Bill Wendling440e9d82013-07-25 00:34:29 +0000210 if (!pImpl) return 0;
Hal Finkele15442c2014-07-18 06:51:55 +0000211 assert(isIntAttribute() &&
212 "Expected the attribute to be an integer attribute!");
George Burgess IV500d3032015-12-16 05:21:02 +0000213 return pImpl->getValueAsInt();
Bill Wendling3f12ac22013-02-05 22:37:24 +0000214}
215
216StringRef Attribute::getKindAsString() const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000217 if (!pImpl) return {};
Bill Wendling3f12ac22013-02-05 22:37:24 +0000218 assert(isStringAttribute() &&
219 "Invalid attribute type to get the kind as a string!");
George Burgess IV500d3032015-12-16 05:21:02 +0000220 return pImpl->getKindAsString();
Bill Wendling3f12ac22013-02-05 22:37:24 +0000221}
222
223StringRef Attribute::getValueAsString() const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000224 if (!pImpl) return {};
Bill Wendling3f12ac22013-02-05 22:37:24 +0000225 assert(isStringAttribute() &&
226 "Invalid attribute type to get the value as a string!");
George Burgess IV500d3032015-12-16 05:21:02 +0000227 return pImpl->getValueAsString();
Bill Wendling3f12ac22013-02-05 22:37:24 +0000228}
229
Tim Northoverb7141202019-05-30 18:48:23 +0000230Type *Attribute::getValueAsType() const {
231 if (!pImpl) return {};
232 assert(isTypeAttribute() &&
233 "Invalid attribute type to get the value as a type!");
234 return pImpl->getValueAsType();
235}
236
237
Bill Wendlingae89a0f2013-02-05 23:48:36 +0000238bool Attribute::hasAttribute(AttrKind Kind) const {
239 return (pImpl && pImpl->hasAttribute(Kind)) || (!pImpl && Kind == None);
240}
241
242bool Attribute::hasAttribute(StringRef Kind) const {
243 if (!isStringAttribute()) return false;
244 return pImpl && pImpl->hasAttribute(Kind);
Bill Wendling03eefb32013-01-29 20:45:34 +0000245}
246
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000247unsigned Attribute::getAlignment() const {
Bill Wendlingc79cdff2013-02-01 01:04:27 +0000248 assert(hasAttribute(Attribute::Alignment) &&
249 "Trying to get alignment from non-alignment attribute!");
Bill Wendling3f12ac22013-02-05 22:37:24 +0000250 return pImpl->getValueAsInt();
Bill Wendlingabf3feb2012-10-05 06:44:41 +0000251}
252
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000253unsigned Attribute::getStackAlignment() const {
Bill Wendlingc79cdff2013-02-01 01:04:27 +0000254 assert(hasAttribute(Attribute::StackAlignment) &&
255 "Trying to get alignment from non-alignment attribute!");
Bill Wendling3f12ac22013-02-05 22:37:24 +0000256 return pImpl->getValueAsInt();
Bill Wendlingabf3feb2012-10-05 06:44:41 +0000257}
258
Hal Finkelb0407ba2014-07-18 15:51:28 +0000259uint64_t Attribute::getDereferenceableBytes() const {
260 assert(hasAttribute(Attribute::Dereferenceable) &&
261 "Trying to get dereferenceable bytes from "
262 "non-dereferenceable attribute!");
263 return pImpl->getValueAsInt();
264}
265
Sanjoy Das31ea6d12015-04-16 20:29:50 +0000266uint64_t Attribute::getDereferenceableOrNullBytes() const {
267 assert(hasAttribute(Attribute::DereferenceableOrNull) &&
268 "Trying to get dereferenceable bytes from "
269 "non-dereferenceable attribute!");
270 return pImpl->getValueAsInt();
271}
272
George Burgess IV278199f2016-04-12 01:05:35 +0000273std::pair<unsigned, Optional<unsigned>> Attribute::getAllocSizeArgs() const {
274 assert(hasAttribute(Attribute::AllocSize) &&
275 "Trying to get allocsize args from non-allocsize attribute");
276 return unpackAllocSizeArgs(pImpl->getValueAsInt());
277}
278
Bill Wendling829b4782013-02-11 08:43:33 +0000279std::string Attribute::getAsString(bool InAttrGrp) const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000280 if (!pImpl) return {};
Bill Wendling9c2eba92013-01-31 20:59:05 +0000281
Kostya Serebryanycf880b92013-02-26 06:58:09 +0000282 if (hasAttribute(Attribute::SanitizeAddress))
283 return "sanitize_address";
Evgeniy Stepanovc667c1f2017-12-09 00:21:41 +0000284 if (hasAttribute(Attribute::SanitizeHWAddress))
285 return "sanitize_hwaddress";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000286 if (hasAttribute(Attribute::AlwaysInline))
287 return "alwaysinline";
Igor Laevsky39d662f2015-07-11 10:30:36 +0000288 if (hasAttribute(Attribute::ArgMemOnly))
289 return "argmemonly";
Michael Gottesman41748d72013-06-27 00:25:01 +0000290 if (hasAttribute(Attribute::Builtin))
291 return "builtin";
Owen Anderson85fa7d52015-05-26 23:48:40 +0000292 if (hasAttribute(Attribute::Convergent))
293 return "convergent";
Manman Ren9bfd0d02016-04-01 21:41:15 +0000294 if (hasAttribute(Attribute::SwiftError))
295 return "swifterror";
Manman Renf46262e2016-03-29 17:37:21 +0000296 if (hasAttribute(Attribute::SwiftSelf))
297 return "swiftself";
Vaivaswatha Nagarajfb3f4902015-12-16 16:16:19 +0000298 if (hasAttribute(Attribute::InaccessibleMemOnly))
299 return "inaccessiblememonly";
300 if (hasAttribute(Attribute::InaccessibleMemOrArgMemOnly))
301 return "inaccessiblemem_or_argmemonly";
Reid Klecknera534a382013-12-19 02:14:12 +0000302 if (hasAttribute(Attribute::InAlloca))
303 return "inalloca";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000304 if (hasAttribute(Attribute::InlineHint))
305 return "inlinehint";
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000306 if (hasAttribute(Attribute::InReg))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000307 return "inreg";
Tom Roeder44cb65f2014-06-05 19:29:43 +0000308 if (hasAttribute(Attribute::JumpTable))
309 return "jumptable";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000310 if (hasAttribute(Attribute::MinSize))
311 return "minsize";
312 if (hasAttribute(Attribute::Naked))
313 return "naked";
314 if (hasAttribute(Attribute::Nest))
315 return "nest";
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000316 if (hasAttribute(Attribute::NoAlias))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000317 return "noalias";
Bill Wendling09bd1f72013-02-22 00:12:35 +0000318 if (hasAttribute(Attribute::NoBuiltin))
319 return "nobuiltin";
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000320 if (hasAttribute(Attribute::NoCapture))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000321 return "nocapture";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000322 if (hasAttribute(Attribute::NoDuplicate))
323 return "noduplicate";
324 if (hasAttribute(Attribute::NoImplicitFloat))
325 return "noimplicitfloat";
326 if (hasAttribute(Attribute::NoInline))
327 return "noinline";
328 if (hasAttribute(Attribute::NonLazyBind))
329 return "nonlazybind";
Nick Lewyckyd52b1522014-05-20 01:23:40 +0000330 if (hasAttribute(Attribute::NonNull))
331 return "nonnull";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000332 if (hasAttribute(Attribute::NoRedZone))
333 return "noredzone";
334 if (hasAttribute(Attribute::NoReturn))
335 return "noreturn";
Johannes Doerfert3b775832019-06-27 15:51:40 +0000336 if (hasAttribute(Attribute::WillReturn))
337 return "willreturn";
Oren Ben Simhonfdd72fd2018-03-17 13:29:46 +0000338 if (hasAttribute(Attribute::NoCfCheck))
339 return "nocf_check";
James Molloye6f87ca2015-11-06 10:32:53 +0000340 if (hasAttribute(Attribute::NoRecurse))
341 return "norecurse";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000342 if (hasAttribute(Attribute::NoUnwind))
343 return "nounwind";
Matt Morehouse236cdaf2018-03-22 17:07:51 +0000344 if (hasAttribute(Attribute::OptForFuzzing))
345 return "optforfuzzing";
Andrea Di Biagio377496b2013-08-23 11:53:55 +0000346 if (hasAttribute(Attribute::OptimizeNone))
347 return "optnone";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000348 if (hasAttribute(Attribute::OptimizeForSize))
349 return "optsize";
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000350 if (hasAttribute(Attribute::ReadNone))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000351 return "readnone";
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000352 if (hasAttribute(Attribute::ReadOnly))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000353 return "readonly";
Nicolai Haehnle84c9f992016-07-04 08:01:29 +0000354 if (hasAttribute(Attribute::WriteOnly))
355 return "writeonly";
Stephen Linb8bd2322013-04-20 05:14:40 +0000356 if (hasAttribute(Attribute::Returned))
357 return "returned";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000358 if (hasAttribute(Attribute::ReturnsTwice))
359 return "returns_twice";
360 if (hasAttribute(Attribute::SExt))
361 return "signext";
Chandler Carruth664aa862018-09-04 12:38:00 +0000362 if (hasAttribute(Attribute::SpeculativeLoadHardening))
363 return "speculative_load_hardening";
Matt Arsenaultb19b57e2017-04-28 20:25:27 +0000364 if (hasAttribute(Attribute::Speculatable))
365 return "speculatable";
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000366 if (hasAttribute(Attribute::StackProtect))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000367 return "ssp";
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000368 if (hasAttribute(Attribute::StackProtectReq))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000369 return "sspreq";
Bill Wendlingd154e2832013-01-23 06:41:41 +0000370 if (hasAttribute(Attribute::StackProtectStrong))
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000371 return "sspstrong";
Peter Collingbourne82437bf2015-06-15 21:07:11 +0000372 if (hasAttribute(Attribute::SafeStack))
373 return "safestack";
Vlad Tsyrklevichd17f61e2018-04-03 20:10:40 +0000374 if (hasAttribute(Attribute::ShadowCallStack))
375 return "shadowcallstack";
Andrew Kaylor53a5fbb2017-08-14 21:15:13 +0000376 if (hasAttribute(Attribute::StrictFP))
377 return "strictfp";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000378 if (hasAttribute(Attribute::StructRet))
379 return "sret";
Kostya Serebryanycf880b92013-02-26 06:58:09 +0000380 if (hasAttribute(Attribute::SanitizeThread))
381 return "sanitize_thread";
382 if (hasAttribute(Attribute::SanitizeMemory))
383 return "sanitize_memory";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000384 if (hasAttribute(Attribute::UWTable))
385 return "uwtable";
386 if (hasAttribute(Attribute::ZExt))
387 return "zeroext";
Diego Novilloc6399532013-05-24 12:26:52 +0000388 if (hasAttribute(Attribute::Cold))
389 return "cold";
Matt Arsenaultcaf13162019-03-12 21:02:54 +0000390 if (hasAttribute(Attribute::ImmArg))
391 return "immarg";
Bill Wendling9c2eba92013-01-31 20:59:05 +0000392
Tim Northoverb7141202019-05-30 18:48:23 +0000393 if (hasAttribute(Attribute::ByVal)) {
394 std::string Result;
395 Result += "byval";
396 if (Type *Ty = getValueAsType()) {
397 raw_string_ostream OS(Result);
398 Result += '(';
399 Ty->print(OS, false, true);
400 OS.flush();
401 Result += ')';
402 }
403 return Result;
404 }
405
Bill Wendling9c2eba92013-01-31 20:59:05 +0000406 // FIXME: These should be output like this:
407 //
408 // align=4
409 // alignstack=8
410 //
Bill Wendling3d7b0b82012-12-19 07:18:57 +0000411 if (hasAttribute(Attribute::Alignment)) {
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000412 std::string Result;
Bill Wendling829b4782013-02-11 08:43:33 +0000413 Result += "align";
414 Result += (InAttrGrp) ? "=" : " ";
Bill Wendling3f12ac22013-02-05 22:37:24 +0000415 Result += utostr(getValueAsInt());
416 return Result;
417 }
Bill Wendling829b4782013-02-11 08:43:33 +0000418
Sanjoy Das31ea6d12015-04-16 20:29:50 +0000419 auto AttrWithBytesToString = [&](const char *Name) {
Bill Wendling3f12ac22013-02-05 22:37:24 +0000420 std::string Result;
Sanjoy Das31ea6d12015-04-16 20:29:50 +0000421 Result += Name;
Bill Wendling829b4782013-02-11 08:43:33 +0000422 if (InAttrGrp) {
423 Result += "=";
424 Result += utostr(getValueAsInt());
425 } else {
426 Result += "(";
427 Result += utostr(getValueAsInt());
428 Result += ")";
429 }
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000430 return Result;
Sanjoy Das31ea6d12015-04-16 20:29:50 +0000431 };
Bill Wendling9c2eba92013-01-31 20:59:05 +0000432
Sanjoy Das31ea6d12015-04-16 20:29:50 +0000433 if (hasAttribute(Attribute::StackAlignment))
434 return AttrWithBytesToString("alignstack");
435
436 if (hasAttribute(Attribute::Dereferenceable))
437 return AttrWithBytesToString("dereferenceable");
438
439 if (hasAttribute(Attribute::DereferenceableOrNull))
440 return AttrWithBytesToString("dereferenceable_or_null");
Hal Finkelb0407ba2014-07-18 15:51:28 +0000441
George Burgess IV278199f2016-04-12 01:05:35 +0000442 if (hasAttribute(Attribute::AllocSize)) {
443 unsigned ElemSize;
444 Optional<unsigned> NumElems;
445 std::tie(ElemSize, NumElems) = getAllocSizeArgs();
446
447 std::string Result = "allocsize(";
448 Result += utostr(ElemSize);
449 if (NumElems.hasValue()) {
450 Result += ',';
451 Result += utostr(*NumElems);
452 }
453 Result += ')';
454 return Result;
455 }
456
Bill Wendling9c2eba92013-01-31 20:59:05 +0000457 // Convert target-dependent attributes to strings of the form:
458 //
459 // "kind"
460 // "kind" = "value"
Bill Wendling9c2eba92013-01-31 20:59:05 +0000461 //
Bill Wendling3f12ac22013-02-05 22:37:24 +0000462 if (isStringAttribute()) {
Bill Wendling9c2eba92013-01-31 20:59:05 +0000463 std::string Result;
Yaron Keren075759a2015-03-30 15:42:36 +0000464 Result += (Twine('"') + getKindAsString() + Twine('"')).str();
Bill Wendling9c2eba92013-01-31 20:59:05 +0000465
Honggyu Kim9eb6a102016-09-01 11:44:06 +0000466 std::string AttrVal = pImpl->getValueAsString();
467 if (AttrVal.empty()) return Result;
Bill Wendling7a33f772013-02-01 22:32:30 +0000468
Honggyu Kim9eb6a102016-09-01 11:44:06 +0000469 // Since some attribute strings contain special characters that cannot be
470 // printable, those have to be escaped to make the attribute value printable
471 // as is. e.g. "\01__gnu_mcount_nc"
472 {
473 raw_string_ostream OS(Result);
474 OS << "=\"";
Jonas Devlieghere745918ff2018-05-31 17:01:42 +0000475 printEscapedString(AttrVal, OS);
Honggyu Kim9eb6a102016-09-01 11:44:06 +0000476 OS << "\"";
477 }
Bill Wendlingc79cdff2013-02-01 01:04:27 +0000478 return Result;
Bill Wendling9c2eba92013-01-31 20:59:05 +0000479 }
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000480
481 llvm_unreachable("Unknown attribute");
Chris Lattner3e13b8c2008-01-02 23:42:30 +0000482}
483
Bill Wendlingd509a662013-01-29 00:34:06 +0000484bool Attribute::operator<(Attribute A) const {
485 if (!pImpl && !A.pImpl) return false;
486 if (!pImpl) return true;
487 if (!A.pImpl) return false;
488 return *pImpl < *A.pImpl;
489}
490
Bill Wendlingd509a662013-01-29 00:34:06 +0000491//===----------------------------------------------------------------------===//
492// AttributeImpl Definition
493//===----------------------------------------------------------------------===//
494
Eric Christopher0eaa5412014-07-02 22:05:40 +0000495// Pin the vtables to this file.
Eugene Zelenkodeaf6952017-02-17 00:00:09 +0000496AttributeImpl::~AttributeImpl() = default;
497
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +0000498void EnumAttributeImpl::anchor() {}
Eugene Zelenkodeaf6952017-02-17 00:00:09 +0000499
Hal Finkele15442c2014-07-18 06:51:55 +0000500void IntAttributeImpl::anchor() {}
Eugene Zelenkodeaf6952017-02-17 00:00:09 +0000501
Juergen Ributzkad12ccbd2013-11-19 00:57:56 +0000502void StringAttributeImpl::anchor() {}
Alexey Samsonov49109a22013-11-18 09:31:53 +0000503
Tim Northoverb7141202019-05-30 18:48:23 +0000504void TypeAttributeImpl::anchor() {}
505
Bill Wendlingd509a662013-01-29 00:34:06 +0000506bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
Bill Wendling3f12ac22013-02-05 22:37:24 +0000507 if (isStringAttribute()) return false;
508 return getKindAsEnum() == A;
Bill Wendlingd509a662013-01-29 00:34:06 +0000509}
510
Bill Wendling3f12ac22013-02-05 22:37:24 +0000511bool AttributeImpl::hasAttribute(StringRef Kind) const {
512 if (!isStringAttribute()) return false;
513 return getKindAsString() == Kind;
Bill Wendlingd509a662013-01-29 00:34:06 +0000514}
515
Bill Wendling3f12ac22013-02-05 22:37:24 +0000516Attribute::AttrKind AttributeImpl::getKindAsEnum() const {
Tim Northoverb7141202019-05-30 18:48:23 +0000517 assert(isEnumAttribute() || isIntAttribute() || isTypeAttribute());
Benjamin Kramer741146b2013-07-11 12:13:16 +0000518 return static_cast<const EnumAttributeImpl *>(this)->getEnumKind();
Bill Wendlingd509a662013-01-29 00:34:06 +0000519}
520
Bill Wendling3f12ac22013-02-05 22:37:24 +0000521uint64_t AttributeImpl::getValueAsInt() const {
Hal Finkele15442c2014-07-18 06:51:55 +0000522 assert(isIntAttribute());
523 return static_cast<const IntAttributeImpl *>(this)->getValue();
Bill Wendlingd509a662013-01-29 00:34:06 +0000524}
525
Bill Wendling3f12ac22013-02-05 22:37:24 +0000526StringRef AttributeImpl::getKindAsString() const {
Benjamin Kramer741146b2013-07-11 12:13:16 +0000527 assert(isStringAttribute());
528 return static_cast<const StringAttributeImpl *>(this)->getStringKind();
Bill Wendlingd509a662013-01-29 00:34:06 +0000529}
530
Bill Wendling3f12ac22013-02-05 22:37:24 +0000531StringRef AttributeImpl::getValueAsString() const {
Benjamin Kramer741146b2013-07-11 12:13:16 +0000532 assert(isStringAttribute());
533 return static_cast<const StringAttributeImpl *>(this)->getStringValue();
Bill Wendlingd509a662013-01-29 00:34:06 +0000534}
535
Tim Northoverb7141202019-05-30 18:48:23 +0000536Type *AttributeImpl::getValueAsType() const {
537 assert(isTypeAttribute());
538 return static_cast<const TypeAttributeImpl *>(this)->getTypeValue();
539}
540
Bill Wendlingd509a662013-01-29 00:34:06 +0000541bool AttributeImpl::operator<(const AttributeImpl &AI) const {
Bill Wendlingc79cdff2013-02-01 01:04:27 +0000542 // This sorts the attributes with Attribute::AttrKinds coming first (sorted
543 // relative to their enum value) and then strings.
Bill Wendling26b95752013-02-15 05:25:26 +0000544 if (isEnumAttribute()) {
545 if (AI.isEnumAttribute()) return getKindAsEnum() < AI.getKindAsEnum();
Hal Finkele15442c2014-07-18 06:51:55 +0000546 if (AI.isIntAttribute()) return true;
Bill Wendling26b95752013-02-15 05:25:26 +0000547 if (AI.isStringAttribute()) return true;
Tim Northoverb7141202019-05-30 18:48:23 +0000548 if (AI.isTypeAttribute()) return true;
549 }
550
551 if (isTypeAttribute()) {
552 if (AI.isEnumAttribute()) return false;
553 if (AI.isTypeAttribute()) {
554 assert(getKindAsEnum() != AI.getKindAsEnum() &&
555 "Comparison of types would be unstable");
556 return getKindAsEnum() < AI.getKindAsEnum();
557 }
558 if (AI.isIntAttribute()) return true;
559 if (AI.isStringAttribute()) return true;
Bill Wendling26b95752013-02-15 05:25:26 +0000560 }
Bill Wendlingc79cdff2013-02-01 01:04:27 +0000561
Hal Finkele15442c2014-07-18 06:51:55 +0000562 if (isIntAttribute()) {
Bill Wendling26b95752013-02-15 05:25:26 +0000563 if (AI.isEnumAttribute()) return false;
Tim Northoverb7141202019-05-30 18:48:23 +0000564 if (AI.isTypeAttribute()) return false;
Reid Kleckner7de67612016-04-04 23:06:05 +0000565 if (AI.isIntAttribute()) {
566 if (getKindAsEnum() == AI.getKindAsEnum())
567 return getValueAsInt() < AI.getValueAsInt();
568 return getKindAsEnum() < AI.getKindAsEnum();
569 }
Bill Wendling26b95752013-02-15 05:25:26 +0000570 if (AI.isStringAttribute()) return true;
Bill Wendling3f12ac22013-02-05 22:37:24 +0000571 }
Bill Wendlingd509a662013-01-29 00:34:06 +0000572
Tim Northoverb7141202019-05-30 18:48:23 +0000573 assert(isStringAttribute());
Bill Wendling26b95752013-02-15 05:25:26 +0000574 if (AI.isEnumAttribute()) return false;
Tim Northoverb7141202019-05-30 18:48:23 +0000575 if (AI.isTypeAttribute()) return false;
Hal Finkele15442c2014-07-18 06:51:55 +0000576 if (AI.isIntAttribute()) return false;
Bill Wendling26b95752013-02-15 05:25:26 +0000577 if (getKindAsString() == AI.getKindAsString())
578 return getValueAsString() < AI.getValueAsString();
579 return getKindAsString() < AI.getKindAsString();
Bill Wendlingd509a662013-01-29 00:34:06 +0000580}
581
Bill Wendlingd509a662013-01-29 00:34:06 +0000582//===----------------------------------------------------------------------===//
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000583// AttributeSet Definition
584//===----------------------------------------------------------------------===//
585
586AttributeSet AttributeSet::get(LLVMContext &C, const AttrBuilder &B) {
587 return AttributeSet(AttributeSetNode::get(C, B));
588}
589
590AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<Attribute> Attrs) {
591 return AttributeSet(AttributeSetNode::get(C, Attrs));
592}
593
Javed Absarf3d79042017-05-11 12:28:08 +0000594AttributeSet AttributeSet::addAttribute(LLVMContext &C,
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000595 Attribute::AttrKind Kind) const {
Javed Absarf3d79042017-05-11 12:28:08 +0000596 if (hasAttribute(Kind)) return *this;
597 AttrBuilder B;
598 B.addAttribute(Kind);
599 return addAttributes(C, AttributeSet::get(C, B));
600}
601
602AttributeSet AttributeSet::addAttribute(LLVMContext &C, StringRef Kind,
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000603 StringRef Value) const {
Javed Absarf3d79042017-05-11 12:28:08 +0000604 AttrBuilder B;
605 B.addAttribute(Kind, Value);
606 return addAttributes(C, AttributeSet::get(C, B));
607}
608
609AttributeSet AttributeSet::addAttributes(LLVMContext &C,
610 const AttributeSet AS) const {
611 if (!hasAttributes())
612 return AS;
613
614 if (!AS.hasAttributes())
615 return *this;
616
617 AttrBuilder B(AS);
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000618 for (const auto I : *this)
Javed Absarf3d79042017-05-11 12:28:08 +0000619 B.addAttribute(I);
620
621 return get(C, B);
622}
623
624AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
625 Attribute::AttrKind Kind) const {
626 if (!hasAttribute(Kind)) return *this;
Daniel Neilson88dddb82018-01-17 19:15:21 +0000627 AttrBuilder B(*this);
628 B.removeAttribute(Kind);
629 return get(C, B);
Javed Absarf3d79042017-05-11 12:28:08 +0000630}
631
632AttributeSet AttributeSet::removeAttribute(LLVMContext &C,
633 StringRef Kind) const {
634 if (!hasAttribute(Kind)) return *this;
Daniel Neilson88dddb82018-01-17 19:15:21 +0000635 AttrBuilder B(*this);
636 B.removeAttribute(Kind);
637 return get(C, B);
Javed Absarf3d79042017-05-11 12:28:08 +0000638}
639
640AttributeSet AttributeSet::removeAttributes(LLVMContext &C,
641 const AttrBuilder &Attrs) const {
Javed Absarf3d79042017-05-11 12:28:08 +0000642 AttrBuilder B(*this);
643 B.remove(Attrs);
644 return get(C, B);
645}
646
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000647unsigned AttributeSet::getNumAttributes() const {
648 return SetNode ? SetNode->getNumAttributes() : 0;
649}
650
651bool AttributeSet::hasAttribute(Attribute::AttrKind Kind) const {
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000652 return SetNode ? SetNode->hasAttribute(Kind) : false;
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000653}
654
655bool AttributeSet::hasAttribute(StringRef Kind) const {
Eugene Zelenkod761e2c2017-05-15 21:57:41 +0000656 return SetNode ? SetNode->hasAttribute(Kind) : false;
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000657}
658
659Attribute AttributeSet::getAttribute(Attribute::AttrKind Kind) const {
660 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
661}
662
663Attribute AttributeSet::getAttribute(StringRef Kind) const {
664 return SetNode ? SetNode->getAttribute(Kind) : Attribute();
665}
666
667unsigned AttributeSet::getAlignment() const {
668 return SetNode ? SetNode->getAlignment() : 0;
669}
670
671unsigned AttributeSet::getStackAlignment() const {
672 return SetNode ? SetNode->getStackAlignment() : 0;
673}
674
675uint64_t AttributeSet::getDereferenceableBytes() const {
676 return SetNode ? SetNode->getDereferenceableBytes() : 0;
677}
678
679uint64_t AttributeSet::getDereferenceableOrNullBytes() const {
680 return SetNode ? SetNode->getDereferenceableOrNullBytes() : 0;
681}
682
Tim Northoverb7141202019-05-30 18:48:23 +0000683Type *AttributeSet::getByValType() const {
684 return SetNode ? SetNode->getByValType() : nullptr;
685}
686
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000687std::pair<unsigned, Optional<unsigned>> AttributeSet::getAllocSizeArgs() const {
Konstantin Zhuravlyov6df95b72017-04-12 23:57:37 +0000688 return SetNode ? SetNode->getAllocSizeArgs()
689 : std::pair<unsigned, Optional<unsigned>>(0, 0);
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000690}
691
692std::string AttributeSet::getAsString(bool InAttrGrp) const {
693 return SetNode ? SetNode->getAsString(InAttrGrp) : "";
694}
695
696AttributeSet::iterator AttributeSet::begin() const {
697 return SetNode ? SetNode->begin() : nullptr;
698}
699
700AttributeSet::iterator AttributeSet::end() const {
701 return SetNode ? SetNode->end() : nullptr;
702}
703
Aaron Ballman615eb472017-10-15 14:32:27 +0000704#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Javed Absarf3d79042017-05-11 12:28:08 +0000705LLVM_DUMP_METHOD void AttributeSet::dump() const {
706 dbgs() << "AS =\n";
707 dbgs() << " { ";
708 dbgs() << getAsString(true) << " }\n";
709}
710#endif
711
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000712//===----------------------------------------------------------------------===//
Bill Wendlingd509a662013-01-29 00:34:06 +0000713// AttributeSetNode Definition
714//===----------------------------------------------------------------------===//
715
Reid Kleckner8ff77852017-04-10 23:46:08 +0000716AttributeSetNode::AttributeSetNode(ArrayRef<Attribute> Attrs)
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000717 : AvailableAttrs(0), NumAttrs(Attrs.size()) {
Reid Kleckner8ff77852017-04-10 23:46:08 +0000718 // There's memory after the node where we can store the entries in.
Fangrui Song75709322018-11-17 01:44:25 +0000719 llvm::copy(Attrs, getTrailingObjects<Attribute>());
Reid Kleckner8ff77852017-04-10 23:46:08 +0000720
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000721 for (const auto I : *this) {
Reid Kleckner8ff77852017-04-10 23:46:08 +0000722 if (!I.isStringAttribute()) {
723 AvailableAttrs |= ((uint64_t)1) << I.getKindAsEnum();
724 }
725 }
726}
727
Bill Wendlingd509a662013-01-29 00:34:06 +0000728AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
729 ArrayRef<Attribute> Attrs) {
730 if (Attrs.empty())
Craig Topperc6207612014-04-09 06:08:46 +0000731 return nullptr;
Bill Wendlingd509a662013-01-29 00:34:06 +0000732
733 // Otherwise, build a key to look up the existing attributes.
734 LLVMContextImpl *pImpl = C.pImpl;
735 FoldingSetNodeID ID;
736
737 SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
Fangrui Song0cac7262018-09-27 02:13:45 +0000738 llvm::sort(SortedAttrs);
Bill Wendlingd509a662013-01-29 00:34:06 +0000739
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000740 for (const auto Attr : SortedAttrs)
George Burgess IV500d3032015-12-16 05:21:02 +0000741 Attr.Profile(ID);
Bill Wendlingd509a662013-01-29 00:34:06 +0000742
743 void *InsertPoint;
744 AttributeSetNode *PA =
745 pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
746
747 // If we didn't find any existing attributes of the same shape then create a
748 // new one and insert it.
749 if (!PA) {
Benjamin Kramer741146b2013-07-11 12:13:16 +0000750 // Coallocate entries after the AttributeSetNode itself.
James Y Knightaa365b22015-08-05 22:57:34 +0000751 void *Mem = ::operator new(totalSizeToAlloc<Attribute>(SortedAttrs.size()));
Benjamin Kramer741146b2013-07-11 12:13:16 +0000752 PA = new (Mem) AttributeSetNode(SortedAttrs);
Bill Wendlingd509a662013-01-29 00:34:06 +0000753 pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
754 }
755
Reid Klecknerb5180542017-03-21 16:57:19 +0000756 // Return the AttributeSetNode that we found or created.
Bill Wendlingd509a662013-01-29 00:34:06 +0000757 return PA;
758}
759
Reid Klecknereb9dd5b2017-04-10 23:31:05 +0000760AttributeSetNode *AttributeSetNode::get(LLVMContext &C, const AttrBuilder &B) {
761 // Add target-independent attributes.
762 SmallVector<Attribute, 8> Attrs;
763 for (Attribute::AttrKind Kind = Attribute::None;
764 Kind != Attribute::EndAttrKinds; Kind = Attribute::AttrKind(Kind + 1)) {
765 if (!B.contains(Kind))
766 continue;
767
768 Attribute Attr;
769 switch (Kind) {
Tim Northoverb7141202019-05-30 18:48:23 +0000770 case Attribute::ByVal:
771 Attr = Attribute::getWithByValType(C, B.getByValType());
772 break;
Reid Klecknereb9dd5b2017-04-10 23:31:05 +0000773 case Attribute::Alignment:
774 Attr = Attribute::getWithAlignment(C, B.getAlignment());
775 break;
776 case Attribute::StackAlignment:
777 Attr = Attribute::getWithStackAlignment(C, B.getStackAlignment());
778 break;
779 case Attribute::Dereferenceable:
780 Attr = Attribute::getWithDereferenceableBytes(
781 C, B.getDereferenceableBytes());
782 break;
783 case Attribute::DereferenceableOrNull:
784 Attr = Attribute::getWithDereferenceableOrNullBytes(
785 C, B.getDereferenceableOrNullBytes());
786 break;
787 case Attribute::AllocSize: {
788 auto A = B.getAllocSizeArgs();
789 Attr = Attribute::getWithAllocSizeArgs(C, A.first, A.second);
790 break;
791 }
792 default:
793 Attr = Attribute::get(C, Kind);
794 }
795 Attrs.push_back(Attr);
796 }
797
798 // Add target-dependent (string) attributes.
799 for (const auto &TDA : B.td_attrs())
800 Attrs.emplace_back(Attribute::get(C, TDA.first, TDA.second));
801
802 return get(C, Attrs);
803}
804
Bill Wendlingbce7b972013-02-13 08:42:21 +0000805bool AttributeSetNode::hasAttribute(StringRef Kind) const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000806 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000807 if (I.hasAttribute(Kind))
Bill Wendlingbce7b972013-02-13 08:42:21 +0000808 return true;
809 return false;
810}
811
812Attribute AttributeSetNode::getAttribute(Attribute::AttrKind Kind) const {
Matthias Braun31eeb76f2016-01-29 22:25:13 +0000813 if (hasAttribute(Kind)) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000814 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000815 if (I.hasAttribute(Kind))
816 return I;
Matthias Braun31eeb76f2016-01-29 22:25:13 +0000817 }
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000818 return {};
Bill Wendlingbce7b972013-02-13 08:42:21 +0000819}
820
821Attribute AttributeSetNode::getAttribute(StringRef Kind) const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000822 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000823 if (I.hasAttribute(Kind))
824 return I;
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000825 return {};
Bill Wendlingbce7b972013-02-13 08:42:21 +0000826}
827
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000828unsigned AttributeSetNode::getAlignment() const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000829 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000830 if (I.hasAttribute(Attribute::Alignment))
831 return I.getAlignment();
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000832 return 0;
833}
834
835unsigned AttributeSetNode::getStackAlignment() const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000836 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000837 if (I.hasAttribute(Attribute::StackAlignment))
838 return I.getStackAlignment();
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000839 return 0;
840}
841
Tim Northoverb7141202019-05-30 18:48:23 +0000842Type *AttributeSetNode::getByValType() const {
843 for (const auto I : *this)
844 if (I.hasAttribute(Attribute::ByVal))
845 return I.getValueAsType();
846 return 0;
847}
848
Hal Finkelb0407ba2014-07-18 15:51:28 +0000849uint64_t AttributeSetNode::getDereferenceableBytes() const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000850 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000851 if (I.hasAttribute(Attribute::Dereferenceable))
852 return I.getDereferenceableBytes();
Hal Finkelb0407ba2014-07-18 15:51:28 +0000853 return 0;
854}
855
Sanjoy Das06cf33f2015-05-06 17:41:54 +0000856uint64_t AttributeSetNode::getDereferenceableOrNullBytes() const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000857 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000858 if (I.hasAttribute(Attribute::DereferenceableOrNull))
859 return I.getDereferenceableOrNullBytes();
Sanjoy Das06cf33f2015-05-06 17:41:54 +0000860 return 0;
861}
862
George Burgess IV278199f2016-04-12 01:05:35 +0000863std::pair<unsigned, Optional<unsigned>>
864AttributeSetNode::getAllocSizeArgs() const {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000865 for (const auto I : *this)
Benjamin Krameraf28e7d2016-06-26 14:10:56 +0000866 if (I.hasAttribute(Attribute::AllocSize))
867 return I.getAllocSizeArgs();
George Burgess IV278199f2016-04-12 01:05:35 +0000868 return std::make_pair(0, 0);
869}
870
Rafael Espindolacbf5a7a2013-05-01 13:07:03 +0000871std::string AttributeSetNode::getAsString(bool InAttrGrp) const {
Benjamin Kramer0baf8f42013-04-19 11:43:21 +0000872 std::string Str;
Benjamin Kramer741146b2013-07-11 12:13:16 +0000873 for (iterator I = begin(), E = end(); I != E; ++I) {
874 if (I != begin())
Rafael Espindolacbf5a7a2013-05-01 13:07:03 +0000875 Str += ' ';
876 Str += I->getAsString(InAttrGrp);
Bill Wendlingf2955aa2013-01-29 03:20:31 +0000877 }
878 return Str;
879}
880
Bill Wendlingd509a662013-01-29 00:34:06 +0000881//===----------------------------------------------------------------------===//
Reid Klecknerb5180542017-03-21 16:57:19 +0000882// AttributeListImpl Definition
Bill Wendlingd509a662013-01-29 00:34:06 +0000883//===----------------------------------------------------------------------===//
884
Reid Kleckner51b2cd82017-10-11 01:40:38 +0000885/// Map from AttributeList index to the internal array index. Adding one happens
886/// to work, but it relies on unsigned integer wrapping. MSVC warns about
887/// unsigned wrapping in constexpr functions, so write out the conditional. LLVM
888/// folds it to add anyway.
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000889static constexpr unsigned attrIdxToArrayIdx(unsigned Index) {
Reid Kleckner51b2cd82017-10-11 01:40:38 +0000890 return Index == AttributeList::FunctionIndex ? 0 : Index + 1;
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000891}
892
893AttributeListImpl::AttributeListImpl(LLVMContext &C,
894 ArrayRef<AttributeSet> Sets)
895 : AvailableFunctionAttrs(0), Context(C), NumAttrSets(Sets.size()) {
896 assert(!Sets.empty() && "pointless AttributeListImpl");
Reid Klecknera82be602017-04-11 00:16:00 +0000897
898 // There's memory after the node where we can store the entries in.
Fangrui Song75709322018-11-17 01:44:25 +0000899 llvm::copy(Sets, getTrailingObjects<AttributeSet>());
Reid Klecknera82be602017-04-11 00:16:00 +0000900
901 // Initialize AvailableFunctionAttrs summary bitset.
Reid Klecknerec0fc032017-04-12 22:22:01 +0000902 static_assert(Attribute::EndAttrKinds <=
903 sizeof(AvailableFunctionAttrs) * CHAR_BIT,
904 "Too many attributes");
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000905 static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
906 "function should be stored in slot 0");
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000907 for (const auto I : Sets[0]) {
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000908 if (!I.isStringAttribute())
909 AvailableFunctionAttrs |= 1ULL << I.getKindAsEnum();
Reid Klecknera82be602017-04-11 00:16:00 +0000910 }
911}
912
913void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000914 Profile(ID, makeArrayRef(begin(), end()));
Reid Klecknera82be602017-04-11 00:16:00 +0000915}
916
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000917void AttributeListImpl::Profile(FoldingSetNodeID &ID,
918 ArrayRef<AttributeSet> Sets) {
919 for (const auto &Set : Sets)
920 ID.AddPointer(Set.SetNode);
Reid Klecknera82be602017-04-11 00:16:00 +0000921}
922
Aaron Ballman615eb472017-10-15 14:32:27 +0000923#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Reid Klecknerb5180542017-03-21 16:57:19 +0000924LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
925 AttributeList(const_cast<AttributeListImpl *>(this)).dump();
Peter Collingbourneabca2ec2013-08-02 22:34:30 +0000926}
Matthias Braun8c209aa2017-01-28 02:02:38 +0000927#endif
Peter Collingbourneabca2ec2013-08-02 22:34:30 +0000928
Bill Wendlingd509a662013-01-29 00:34:06 +0000929//===----------------------------------------------------------------------===//
Reid Klecknerb5180542017-03-21 16:57:19 +0000930// AttributeList Construction and Mutation Methods
Bill Wendlingd509a662013-01-29 00:34:06 +0000931//===----------------------------------------------------------------------===//
932
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000933AttributeList AttributeList::getImpl(LLVMContext &C,
934 ArrayRef<AttributeSet> AttrSets) {
935 assert(!AttrSets.empty() && "pointless AttributeListImpl");
Reid Klecknereb9dd5b2017-04-10 23:31:05 +0000936
Bill Wendlingd509a662013-01-29 00:34:06 +0000937 LLVMContextImpl *pImpl = C.pImpl;
938 FoldingSetNodeID ID;
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000939 AttributeListImpl::Profile(ID, AttrSets);
Bill Wendlingd509a662013-01-29 00:34:06 +0000940
941 void *InsertPoint;
Reid Klecknerb5180542017-03-21 16:57:19 +0000942 AttributeListImpl *PA =
943 pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
Bill Wendlingd509a662013-01-29 00:34:06 +0000944
945 // If we didn't find any existing attributes of the same shape then
946 // create a new one and insert it.
947 if (!PA) {
Reid Klecknerb5180542017-03-21 16:57:19 +0000948 // Coallocate entries after the AttributeListImpl itself.
James Y Knightaa365b22015-08-05 22:57:34 +0000949 void *Mem = ::operator new(
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000950 AttributeListImpl::totalSizeToAlloc<AttributeSet>(AttrSets.size()));
951 PA = new (Mem) AttributeListImpl(C, AttrSets);
Bill Wendlingd509a662013-01-29 00:34:06 +0000952 pImpl->AttrsLists.InsertNode(PA, InsertPoint);
953 }
954
955 // Return the AttributesList that we found or created.
Reid Klecknerb5180542017-03-21 16:57:19 +0000956 return AttributeList(PA);
Bill Wendlingd509a662013-01-29 00:34:06 +0000957}
958
Reid Klecknerb5180542017-03-21 16:57:19 +0000959AttributeList
960AttributeList::get(LLVMContext &C,
961 ArrayRef<std::pair<unsigned, Attribute>> Attrs) {
Bill Wendlingd509a662013-01-29 00:34:06 +0000962 // If there are no attributes then return a null AttributesList pointer.
963 if (Attrs.empty())
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000964 return {};
Bill Wendlingd509a662013-01-29 00:34:06 +0000965
Craig Toppere30b8ca2016-01-03 19:43:40 +0000966 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
967 [](const std::pair<unsigned, Attribute> &LHS,
968 const std::pair<unsigned, Attribute> &RHS) {
969 return LHS.first < RHS.first;
970 }) && "Misordered Attributes list!");
Eugene Zelenko7fb5d412018-03-30 00:47:31 +0000971 assert(llvm::none_of(Attrs,
972 [](const std::pair<unsigned, Attribute> &Pair) {
973 return Pair.second.hasAttribute(Attribute::None);
974 }) &&
David Majnemer0a16c222016-08-11 21:15:00 +0000975 "Pointless attribute!");
Bill Wendlingd509a662013-01-29 00:34:06 +0000976
977 // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
978 // list.
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000979 SmallVector<std::pair<unsigned, AttributeSet>, 8> AttrPairVec;
Eugene Zelenkodeaf6952017-02-17 00:00:09 +0000980 for (ArrayRef<std::pair<unsigned, Attribute>>::iterator I = Attrs.begin(),
Bill Wendlingd509a662013-01-29 00:34:06 +0000981 E = Attrs.end(); I != E; ) {
982 unsigned Index = I->first;
983 SmallVector<Attribute, 4> AttrVec;
NAKAMURA Takumif05d2f22013-01-29 15:18:16 +0000984 while (I != E && I->first == Index) {
Bill Wendlingd509a662013-01-29 00:34:06 +0000985 AttrVec.push_back(I->second);
986 ++I;
987 }
988
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000989 AttrPairVec.emplace_back(Index, AttributeSet::get(C, AttrVec));
Bill Wendlingd509a662013-01-29 00:34:06 +0000990 }
991
Reid Kleckner8bf67fe2017-05-23 17:01:48 +0000992 return get(C, AttrPairVec);
Bill Wendlingd509a662013-01-29 00:34:06 +0000993}
994
Reid Klecknerb5180542017-03-21 16:57:19 +0000995AttributeList
996AttributeList::get(LLVMContext &C,
Reid Klecknerc2cb5602017-04-12 00:38:00 +0000997 ArrayRef<std::pair<unsigned, AttributeSet>> Attrs) {
Bill Wendlingd509a662013-01-29 00:34:06 +0000998 // If there are no attributes then return a null AttributesList pointer.
999 if (Attrs.empty())
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001000 return {};
Bill Wendlingd509a662013-01-29 00:34:06 +00001001
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001002 assert(std::is_sorted(Attrs.begin(), Attrs.end(),
1003 [](const std::pair<unsigned, AttributeSet> &LHS,
1004 const std::pair<unsigned, AttributeSet> &RHS) {
1005 return LHS.first < RHS.first;
1006 }) &&
1007 "Misordered Attributes list!");
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001008 assert(llvm::none_of(Attrs,
1009 [](const std::pair<unsigned, AttributeSet> &Pair) {
1010 return !Pair.second.hasAttributes();
1011 }) &&
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001012 "Pointless attribute!");
1013
1014 unsigned MaxIndex = Attrs.back().first;
Craig Topperf8642502018-04-16 17:05:01 +00001015 // If the MaxIndex is FunctionIndex and there are other indices in front
1016 // of it, we need to use the largest of those to get the right size.
1017 if (MaxIndex == FunctionIndex && Attrs.size() > 1)
1018 MaxIndex = Attrs[Attrs.size() - 2].first;
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001019
1020 SmallVector<AttributeSet, 4> AttrVec(attrIdxToArrayIdx(MaxIndex) + 1);
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001021 for (const auto Pair : Attrs)
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001022 AttrVec[attrIdxToArrayIdx(Pair.first)] = Pair.second;
1023
1024 return getImpl(C, AttrVec);
Bill Wendlingd509a662013-01-29 00:34:06 +00001025}
1026
Reid Kleckner7f720332017-04-13 00:58:09 +00001027AttributeList AttributeList::get(LLVMContext &C, AttributeSet FnAttrs,
1028 AttributeSet RetAttrs,
1029 ArrayRef<AttributeSet> ArgAttrs) {
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001030 // Scan from the end to find the last argument with attributes. Most
1031 // arguments don't have attributes, so it's nice if we can have fewer unique
1032 // AttributeListImpls by dropping empty attribute sets at the end of the list.
1033 unsigned NumSets = 0;
1034 for (size_t I = ArgAttrs.size(); I != 0; --I) {
1035 if (ArgAttrs[I - 1].hasAttributes()) {
1036 NumSets = I + 2;
1037 break;
1038 }
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001039 }
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001040 if (NumSets == 0) {
1041 // Check function and return attributes if we didn't have argument
1042 // attributes.
1043 if (RetAttrs.hasAttributes())
1044 NumSets = 2;
1045 else if (FnAttrs.hasAttributes())
1046 NumSets = 1;
1047 }
1048
1049 // If all attribute sets were empty, we can use the empty attribute list.
1050 if (NumSets == 0)
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001051 return {};
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001052
1053 SmallVector<AttributeSet, 8> AttrSets;
1054 AttrSets.reserve(NumSets);
1055 // If we have any attributes, we always have function attributes.
1056 AttrSets.push_back(FnAttrs);
1057 if (NumSets > 1)
1058 AttrSets.push_back(RetAttrs);
1059 if (NumSets > 2) {
1060 // Drop the empty argument attribute sets at the end.
1061 ArgAttrs = ArgAttrs.take_front(NumSets - 2);
1062 AttrSets.insert(AttrSets.end(), ArgAttrs.begin(), ArgAttrs.end());
1063 }
1064
1065 return getImpl(C, AttrSets);
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001066}
1067
Reid Klecknerb5180542017-03-21 16:57:19 +00001068AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1069 const AttrBuilder &B) {
Bill Wendlingd509a662013-01-29 00:34:06 +00001070 if (!B.hasAttributes())
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001071 return {};
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001072 Index = attrIdxToArrayIdx(Index);
1073 SmallVector<AttributeSet, 8> AttrSets(Index + 1);
1074 AttrSets[Index] = AttributeSet::get(C, B);
1075 return getImpl(C, AttrSets);
Bill Wendlingd509a662013-01-29 00:34:06 +00001076}
1077
Reid Klecknerb5180542017-03-21 16:57:19 +00001078AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1079 ArrayRef<Attribute::AttrKind> Kinds) {
Bill Wendlingd509a662013-01-29 00:34:06 +00001080 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001081 for (const auto K : Kinds)
David Majnemer0a16c222016-08-11 21:15:00 +00001082 Attrs.emplace_back(Index, Attribute::get(C, K));
Bill Wendlingd509a662013-01-29 00:34:06 +00001083 return get(C, Attrs);
1084}
1085
Reid Klecknerb5180542017-03-21 16:57:19 +00001086AttributeList AttributeList::get(LLVMContext &C, unsigned Index,
1087 ArrayRef<StringRef> Kinds) {
Amaury Sechet6100adf2016-06-15 17:50:39 +00001088 SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001089 for (const auto K : Kinds)
David Majnemer0a16c222016-08-11 21:15:00 +00001090 Attrs.emplace_back(Index, Attribute::get(C, K));
Amaury Sechet6100adf2016-06-15 17:50:39 +00001091 return get(C, Attrs);
1092}
1093
Reid Klecknerb5180542017-03-21 16:57:19 +00001094AttributeList AttributeList::get(LLVMContext &C,
1095 ArrayRef<AttributeList> Attrs) {
1096 if (Attrs.empty())
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001097 return {};
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001098 if (Attrs.size() == 1)
1099 return Attrs[0];
Bill Wendlingd509a662013-01-29 00:34:06 +00001100
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001101 unsigned MaxSize = 0;
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001102 for (const auto List : Attrs)
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001103 MaxSize = std::max(MaxSize, List.getNumAttrSets());
1104
Reid Kleckner1d7cbdf2017-05-31 14:24:06 +00001105 // If every list was empty, there is no point in merging the lists.
1106 if (MaxSize == 0)
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001107 return {};
Reid Kleckner1d7cbdf2017-05-31 14:24:06 +00001108
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001109 SmallVector<AttributeSet, 8> NewAttrSets(MaxSize);
1110 for (unsigned I = 0; I < MaxSize; ++I) {
1111 AttrBuilder CurBuilder;
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001112 for (const auto List : Attrs)
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001113 CurBuilder.merge(List.getAttributes(I - 1));
1114 NewAttrSets[I] = AttributeSet::get(C, CurBuilder);
Bill Wendlingd509a662013-01-29 00:34:06 +00001115 }
1116
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001117 return getImpl(C, NewAttrSets);
Bill Wendlingd509a662013-01-29 00:34:06 +00001118}
1119
Reid Klecknerb5180542017-03-21 16:57:19 +00001120AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1121 Attribute::AttrKind Kind) const {
Amaury Sechet392638d2016-06-14 20:27:35 +00001122 if (hasAttribute(Index, Kind)) return *this;
Reid Kleckneree4930b2017-05-02 22:07:37 +00001123 AttrBuilder B;
1124 B.addAttribute(Kind);
1125 return addAttributes(C, Index, B);
Reed Kotler795c7b42013-03-13 20:20:08 +00001126}
1127
Reid Klecknerb5180542017-03-21 16:57:19 +00001128AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
1129 StringRef Kind,
1130 StringRef Value) const {
Eugene Zelenkodeaf6952017-02-17 00:00:09 +00001131 AttrBuilder B;
Bill Wendling3b2f6102013-07-25 18:34:24 +00001132 B.addAttribute(Kind, Value);
Reid Kleckneree4930b2017-05-02 22:07:37 +00001133 return addAttributes(C, Index, B);
Bill Wendling3b2f6102013-07-25 18:34:24 +00001134}
1135
Reid Kleckner5fbdd172017-05-31 19:23:09 +00001136AttributeList AttributeList::addAttribute(LLVMContext &C, unsigned Index,
Reid Klecknerb5180542017-03-21 16:57:19 +00001137 Attribute A) const {
Reid Kleckner5fbdd172017-05-31 19:23:09 +00001138 AttrBuilder B;
1139 B.addAttribute(A);
1140 return addAttributes(C, Index, B);
Akira Hatanaka237916b2015-12-02 06:58:49 +00001141}
1142
Reid Klecknerb5180542017-03-21 16:57:19 +00001143AttributeList AttributeList::addAttributes(LLVMContext &C, unsigned Index,
Reid Kleckner61906252017-04-19 01:51:13 +00001144 const AttrBuilder &B) const {
1145 if (!B.hasAttributes())
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001146 return *this;
1147
Reid Klecknerfe64c012017-04-18 22:10:18 +00001148 if (!pImpl)
Reid Kleckner61906252017-04-19 01:51:13 +00001149 return AttributeList::get(C, {{Index, AttributeSet::get(C, B)}});
Reid Klecknerfe64c012017-04-18 22:10:18 +00001150
Bill Wendlingd509a662013-01-29 00:34:06 +00001151#ifndef NDEBUG
1152 // FIXME it is not obvious how this should work for alignment. For now, say
1153 // we can't change a known alignment.
Reid Klecknerbf6b3b152017-05-19 22:23:47 +00001154 unsigned OldAlign = getAttributes(Index).getAlignment();
Reid Kleckner61906252017-04-19 01:51:13 +00001155 unsigned NewAlign = B.getAlignment();
Bill Wendlingd509a662013-01-29 00:34:06 +00001156 assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
1157 "Attempt to change alignment!");
1158#endif
1159
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001160 Index = attrIdxToArrayIdx(Index);
1161 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1162 if (Index >= AttrSets.size())
1163 AttrSets.resize(Index + 1);
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001164
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001165 AttrBuilder Merged(AttrSets[Index]);
1166 Merged.merge(B);
1167 AttrSets[Index] = AttributeSet::get(C, Merged);
Bill Wendlingd509a662013-01-29 00:34:06 +00001168
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001169 return getImpl(C, AttrSets);
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001170}
1171
Reid Kleckner5fbdd172017-05-31 19:23:09 +00001172AttributeList AttributeList::addParamAttribute(LLVMContext &C,
1173 ArrayRef<unsigned> ArgNos,
1174 Attribute A) const {
1175 assert(std::is_sorted(ArgNos.begin(), ArgNos.end()));
1176
1177 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1178 unsigned MaxIndex = attrIdxToArrayIdx(ArgNos.back() + FirstArgIndex);
1179 if (MaxIndex >= AttrSets.size())
1180 AttrSets.resize(MaxIndex + 1);
1181
1182 for (unsigned ArgNo : ArgNos) {
1183 unsigned Index = attrIdxToArrayIdx(ArgNo + FirstArgIndex);
1184 AttrBuilder B(AttrSets[Index]);
1185 B.addAttribute(A);
1186 AttrSets[Index] = AttributeSet::get(C, B);
1187 }
1188
1189 return getImpl(C, AttrSets);
1190}
1191
Reid Klecknerb5180542017-03-21 16:57:19 +00001192AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1193 Attribute::AttrKind Kind) const {
Amaury Sechet392638d2016-06-14 20:27:35 +00001194 if (!hasAttribute(Index, Kind)) return *this;
Daniel Neilson88dddb82018-01-17 19:15:21 +00001195
1196 Index = attrIdxToArrayIdx(Index);
1197 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1198 assert(Index < AttrSets.size());
1199
1200 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1201
1202 return getImpl(C, AttrSets);
Bill Wendlingd509a662013-01-29 00:34:06 +00001203}
1204
Reid Klecknerb5180542017-03-21 16:57:19 +00001205AttributeList AttributeList::removeAttribute(LLVMContext &C, unsigned Index,
1206 StringRef Kind) const {
Amaury Sechet6100adf2016-06-15 17:50:39 +00001207 if (!hasAttribute(Index, Kind)) return *this;
Daniel Neilson88dddb82018-01-17 19:15:21 +00001208
1209 Index = attrIdxToArrayIdx(Index);
1210 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1211 assert(Index < AttrSets.size());
1212
1213 AttrSets[Index] = AttrSets[Index].removeAttribute(C, Kind);
1214
1215 return getImpl(C, AttrSets);
Bill Wendlingd509a662013-01-29 00:34:06 +00001216}
1217
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001218AttributeList
1219AttributeList::removeAttributes(LLVMContext &C, unsigned Index,
1220 const AttrBuilder &AttrsToRemove) const {
Reid Klecknerb5180542017-03-21 16:57:19 +00001221 if (!pImpl)
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001222 return {};
Pete Cooperd2a44612015-05-06 23:19:43 +00001223
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001224 Index = attrIdxToArrayIdx(Index);
1225 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1226 if (Index >= AttrSets.size())
1227 AttrSets.resize(Index + 1);
Pete Cooperd2a44612015-05-06 23:19:43 +00001228
Daniel Neilson88dddb82018-01-17 19:15:21 +00001229 AttrSets[Index] = AttrSets[Index].removeAttributes(C, AttrsToRemove);
Pete Cooperd2a44612015-05-06 23:19:43 +00001230
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001231 return getImpl(C, AttrSets);
Pete Cooperd2a44612015-05-06 23:19:43 +00001232}
1233
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001234AttributeList AttributeList::removeAttributes(LLVMContext &C,
1235 unsigned WithoutIndex) const {
1236 if (!pImpl)
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001237 return {};
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001238 WithoutIndex = attrIdxToArrayIdx(WithoutIndex);
1239 if (WithoutIndex >= getNumAttrSets())
1240 return *this;
1241 SmallVector<AttributeSet, 4> AttrSets(this->begin(), this->end());
1242 AttrSets[WithoutIndex] = AttributeSet();
1243 return getImpl(C, AttrSets);
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001244}
1245
Reid Klecknerb5180542017-03-21 16:57:19 +00001246AttributeList AttributeList::addDereferenceableAttr(LLVMContext &C,
1247 unsigned Index,
1248 uint64_t Bytes) const {
Eugene Zelenkodeaf6952017-02-17 00:00:09 +00001249 AttrBuilder B;
Ramkumar Ramachandra8fcb4982015-02-14 19:37:54 +00001250 B.addDereferenceableAttr(Bytes);
Reid Kleckneree4930b2017-05-02 22:07:37 +00001251 return addAttributes(C, Index, B);
Ramkumar Ramachandra8fcb4982015-02-14 19:37:54 +00001252}
1253
Reid Klecknerb5180542017-03-21 16:57:19 +00001254AttributeList
1255AttributeList::addDereferenceableOrNullAttr(LLVMContext &C, unsigned Index,
1256 uint64_t Bytes) const {
Eugene Zelenkodeaf6952017-02-17 00:00:09 +00001257 AttrBuilder B;
Sanjoy Das31ea6d12015-04-16 20:29:50 +00001258 B.addDereferenceableOrNullAttr(Bytes);
Reid Kleckneree4930b2017-05-02 22:07:37 +00001259 return addAttributes(C, Index, B);
Sanjoy Das31ea6d12015-04-16 20:29:50 +00001260}
1261
Reid Klecknerb5180542017-03-21 16:57:19 +00001262AttributeList
1263AttributeList::addAllocSizeAttr(LLVMContext &C, unsigned Index,
1264 unsigned ElemSizeArg,
1265 const Optional<unsigned> &NumElemsArg) {
Eugene Zelenkodeaf6952017-02-17 00:00:09 +00001266 AttrBuilder B;
George Burgess IV278199f2016-04-12 01:05:35 +00001267 B.addAllocSizeAttr(ElemSizeArg, NumElemsArg);
Reid Kleckneree4930b2017-05-02 22:07:37 +00001268 return addAttributes(C, Index, B);
George Burgess IV278199f2016-04-12 01:05:35 +00001269}
1270
Bill Wendlingd509a662013-01-29 00:34:06 +00001271//===----------------------------------------------------------------------===//
Reid Klecknerb5180542017-03-21 16:57:19 +00001272// AttributeList Accessor Methods
Bill Wendlingd509a662013-01-29 00:34:06 +00001273//===----------------------------------------------------------------------===//
1274
Reid Klecknerb5180542017-03-21 16:57:19 +00001275LLVMContext &AttributeList::getContext() const { return pImpl->getContext(); }
1276
Reid Klecknerf021fab2017-04-13 23:12:13 +00001277AttributeSet AttributeList::getParamAttributes(unsigned ArgNo) const {
Reid Klecknera0b45f42017-05-03 18:17:31 +00001278 return getAttributes(ArgNo + FirstArgIndex);
Bill Wendling5d020a32013-02-10 05:00:40 +00001279}
1280
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001281AttributeSet AttributeList::getRetAttributes() const {
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001282 return getAttributes(ReturnIndex);
Bill Wendlingd509a662013-01-29 00:34:06 +00001283}
1284
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001285AttributeSet AttributeList::getFnAttributes() const {
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001286 return getAttributes(FunctionIndex);
Bill Wendlingd509a662013-01-29 00:34:06 +00001287}
1288
Reid Klecknerb5180542017-03-21 16:57:19 +00001289bool AttributeList::hasAttribute(unsigned Index,
1290 Attribute::AttrKind Kind) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001291 return getAttributes(Index).hasAttribute(Kind);
Bill Wendlingd509a662013-01-29 00:34:06 +00001292}
1293
Reid Klecknerb5180542017-03-21 16:57:19 +00001294bool AttributeList::hasAttribute(unsigned Index, StringRef Kind) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001295 return getAttributes(Index).hasAttribute(Kind);
Bill Wendlingbce7b972013-02-13 08:42:21 +00001296}
1297
Reid Klecknerb5180542017-03-21 16:57:19 +00001298bool AttributeList::hasAttributes(unsigned Index) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001299 return getAttributes(Index).hasAttributes();
Bill Wendlingd509a662013-01-29 00:34:06 +00001300}
1301
Reid Klecknerb5180542017-03-21 16:57:19 +00001302bool AttributeList::hasFnAttribute(Attribute::AttrKind Kind) const {
Matthias Braun33282812016-01-29 22:25:19 +00001303 return pImpl && pImpl->hasFnAttribute(Kind);
1304}
1305
Reid Klecknerb5180542017-03-21 16:57:19 +00001306bool AttributeList::hasFnAttribute(StringRef Kind) const {
1307 return hasAttribute(AttributeList::FunctionIndex, Kind);
Amaury Sechet5f04d812016-09-09 04:50:38 +00001308}
1309
Reid Klecknerf021fab2017-04-13 23:12:13 +00001310bool AttributeList::hasParamAttribute(unsigned ArgNo,
1311 Attribute::AttrKind Kind) const {
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001312 return hasAttribute(ArgNo + FirstArgIndex, Kind);
Reid Klecknerf021fab2017-04-13 23:12:13 +00001313}
1314
Reid Klecknerb5180542017-03-21 16:57:19 +00001315bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
1316 unsigned *Index) const {
Craig Topperc6207612014-04-09 06:08:46 +00001317 if (!pImpl) return false;
Bill Wendlingd509a662013-01-29 00:34:06 +00001318
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001319 for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
1320 if (hasAttribute(I, Attr)) {
1321 if (Index)
1322 *Index = I;
1323 return true;
1324 }
1325 }
Bill Wendlingd509a662013-01-29 00:34:06 +00001326
1327 return false;
1328}
1329
Reid Klecknerb5180542017-03-21 16:57:19 +00001330Attribute AttributeList::getAttribute(unsigned Index,
1331 Attribute::AttrKind Kind) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001332 return getAttributes(Index).getAttribute(Kind);
Bill Wendlingbce7b972013-02-13 08:42:21 +00001333}
1334
Reid Klecknerb5180542017-03-21 16:57:19 +00001335Attribute AttributeList::getAttribute(unsigned Index, StringRef Kind) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001336 return getAttributes(Index).getAttribute(Kind);
Bill Wendlingbce7b972013-02-13 08:42:21 +00001337}
1338
Reid Kleckner859f8b52017-04-28 20:34:27 +00001339unsigned AttributeList::getRetAlignment() const {
1340 return getAttributes(ReturnIndex).getAlignment();
1341}
1342
1343unsigned AttributeList::getParamAlignment(unsigned ArgNo) const {
Reid Klecknera0b45f42017-05-03 18:17:31 +00001344 return getAttributes(ArgNo + FirstArgIndex).getAlignment();
Bill Wendlingd509a662013-01-29 00:34:06 +00001345}
1346
Tim Northoverb7141202019-05-30 18:48:23 +00001347Type *AttributeList::getParamByValType(unsigned Index) const {
1348 return getAttributes(Index+FirstArgIndex).getByValType();
1349}
1350
1351
Reid Klecknerb5180542017-03-21 16:57:19 +00001352unsigned AttributeList::getStackAlignment(unsigned Index) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001353 return getAttributes(Index).getStackAlignment();
Bill Wendlingd509a662013-01-29 00:34:06 +00001354}
1355
Reid Klecknerb5180542017-03-21 16:57:19 +00001356uint64_t AttributeList::getDereferenceableBytes(unsigned Index) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001357 return getAttributes(Index).getDereferenceableBytes();
Hal Finkelb0407ba2014-07-18 15:51:28 +00001358}
1359
Reid Klecknerb5180542017-03-21 16:57:19 +00001360uint64_t AttributeList::getDereferenceableOrNullBytes(unsigned Index) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001361 return getAttributes(Index).getDereferenceableOrNullBytes();
Sanjoy Das06cf33f2015-05-06 17:41:54 +00001362}
1363
George Burgess IV278199f2016-04-12 01:05:35 +00001364std::pair<unsigned, Optional<unsigned>>
Reid Klecknerb5180542017-03-21 16:57:19 +00001365AttributeList::getAllocSizeArgs(unsigned Index) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001366 return getAttributes(Index).getAllocSizeArgs();
George Burgess IV278199f2016-04-12 01:05:35 +00001367}
1368
Reid Klecknerb5180542017-03-21 16:57:19 +00001369std::string AttributeList::getAsString(unsigned Index, bool InAttrGrp) const {
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001370 return getAttributes(Index).getAsString(InAttrGrp);
Bill Wendlingd509a662013-01-29 00:34:06 +00001371}
1372
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001373AttributeSet AttributeList::getAttributes(unsigned Index) const {
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001374 Index = attrIdxToArrayIdx(Index);
1375 if (!pImpl || Index >= getNumAttrSets())
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001376 return {};
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001377 return pImpl->begin()[Index];
Bill Wendlingd509a662013-01-29 00:34:06 +00001378}
1379
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001380AttributeList::iterator AttributeList::begin() const {
1381 return pImpl ? pImpl->begin() : nullptr;
Bill Wendlinga9174862013-01-31 23:53:05 +00001382}
1383
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001384AttributeList::iterator AttributeList::end() const {
1385 return pImpl ? pImpl->end() : nullptr;
Bill Wendlinga9174862013-01-31 23:53:05 +00001386}
1387
Bill Wendlingd509a662013-01-29 00:34:06 +00001388//===----------------------------------------------------------------------===//
Reid Klecknerb5180542017-03-21 16:57:19 +00001389// AttributeList Introspection Methods
Bill Wendlingd509a662013-01-29 00:34:06 +00001390//===----------------------------------------------------------------------===//
1391
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001392unsigned AttributeList::getNumAttrSets() const {
1393 return pImpl ? pImpl->NumAttrSets : 0;
Bill Wendlingd509a662013-01-29 00:34:06 +00001394}
1395
Aaron Ballman615eb472017-10-15 14:32:27 +00001396#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
Reid Klecknerb5180542017-03-21 16:57:19 +00001397LLVM_DUMP_METHOD void AttributeList::dump() const {
Bill Wendlingd509a662013-01-29 00:34:06 +00001398 dbgs() << "PAL[\n";
1399
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001400 for (unsigned i = index_begin(), e = index_end(); i != e; ++i) {
1401 if (getAttributes(i).hasAttributes())
1402 dbgs() << " { " << i << " => " << getAsString(i) << " }\n";
Bill Wendlingd509a662013-01-29 00:34:06 +00001403 }
1404
1405 dbgs() << "]\n";
1406}
Matthias Braun8c209aa2017-01-28 02:02:38 +00001407#endif
Bill Wendlingd509a662013-01-29 00:34:06 +00001408
Bill Wendlingabf3feb2012-10-05 06:44:41 +00001409//===----------------------------------------------------------------------===//
Bill Wendlingcd330342013-01-04 23:27:34 +00001410// AttrBuilder Method Implementations
Bill Wendlingabf3feb2012-10-05 06:44:41 +00001411//===----------------------------------------------------------------------===//
1412
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001413// FIXME: Remove this ctor, use AttributeSet.
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001414AttrBuilder::AttrBuilder(AttributeList AL, unsigned Index) {
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001415 AttributeSet AS = AL.getAttributes(Index);
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001416 for (const auto &A : AS)
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001417 addAttribute(A);
Bill Wendling096f5442013-01-07 08:24:35 +00001418}
1419
Reid Klecknerc2cb5602017-04-12 00:38:00 +00001420AttrBuilder::AttrBuilder(AttributeSet AS) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001421 for (const auto &A : AS)
Reid Kleckner8bf67fe2017-05-23 17:01:48 +00001422 addAttribute(A);
Reid Klecknereb9dd5b2017-04-10 23:31:05 +00001423}
1424
Bill Wendlingcd330342013-01-04 23:27:34 +00001425void AttrBuilder::clear() {
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001426 Attrs.reset();
Sanjoy Das88d0fde2015-09-03 22:27:42 +00001427 TargetDepAttrs.clear();
Sanjoy Das31ea6d12015-04-16 20:29:50 +00001428 Alignment = StackAlignment = DerefBytes = DerefOrNullBytes = 0;
George Burgess IV278199f2016-04-12 01:05:35 +00001429 AllocSizeArgs = 0;
Tim Northoverb7141202019-05-30 18:48:23 +00001430 ByValType = nullptr;
Bill Wendlingcd330342013-01-04 23:27:34 +00001431}
1432
1433AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001434 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
Bill Wendling1c7cc8a2013-01-31 23:16:25 +00001435 assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment &&
George Burgess IV278199f2016-04-12 01:05:35 +00001436 Val != Attribute::Dereferenceable && Val != Attribute::AllocSize &&
Hal Finkelb0407ba2014-07-18 15:51:28 +00001437 "Adding integer attribute without adding a value!");
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001438 Attrs[Val] = true;
Bill Wendling7c04e042012-10-09 19:01:18 +00001439 return *this;
Bill Wendlingabf3feb2012-10-05 06:44:41 +00001440}
1441
Bill Wendling23804da2013-01-31 23:38:01 +00001442AttrBuilder &AttrBuilder::addAttribute(Attribute Attr) {
Bill Wendling0a437302013-02-10 10:13:23 +00001443 if (Attr.isStringAttribute()) {
1444 addAttribute(Attr.getKindAsString(), Attr.getValueAsString());
1445 return *this;
1446 }
1447
Bill Wendling3f12ac22013-02-05 22:37:24 +00001448 Attribute::AttrKind Kind = Attr.getKindAsEnum();
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001449 Attrs[Kind] = true;
Bill Wendling1aa9d9e2013-01-28 05:23:28 +00001450
Bill Wendling3f12ac22013-02-05 22:37:24 +00001451 if (Kind == Attribute::Alignment)
Bill Wendling1aa9d9e2013-01-28 05:23:28 +00001452 Alignment = Attr.getAlignment();
Bill Wendling3f12ac22013-02-05 22:37:24 +00001453 else if (Kind == Attribute::StackAlignment)
Bill Wendling1aa9d9e2013-01-28 05:23:28 +00001454 StackAlignment = Attr.getStackAlignment();
Tim Northoverb7141202019-05-30 18:48:23 +00001455 else if (Kind == Attribute::ByVal)
1456 ByValType = Attr.getValueAsType();
Hal Finkelb0407ba2014-07-18 15:51:28 +00001457 else if (Kind == Attribute::Dereferenceable)
1458 DerefBytes = Attr.getDereferenceableBytes();
Sanjoy Das31ea6d12015-04-16 20:29:50 +00001459 else if (Kind == Attribute::DereferenceableOrNull)
1460 DerefOrNullBytes = Attr.getDereferenceableOrNullBytes();
George Burgess IV278199f2016-04-12 01:05:35 +00001461 else if (Kind == Attribute::AllocSize)
1462 AllocSizeArgs = Attr.getValueAsInt();
Bill Wendling1aa9d9e2013-01-28 05:23:28 +00001463 return *this;
1464}
1465
Bill Wendlingb9c5b1a2013-02-05 08:09:32 +00001466AttrBuilder &AttrBuilder::addAttribute(StringRef A, StringRef V) {
1467 TargetDepAttrs[A] = V;
1468 return *this;
1469}
1470
Bill Wendling23804da2013-01-31 23:38:01 +00001471AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001472 assert((unsigned)Val < Attribute::EndAttrKinds && "Attribute out of range!");
1473 Attrs[Val] = false;
Bill Wendling23804da2013-01-31 23:38:01 +00001474
1475 if (Val == Attribute::Alignment)
1476 Alignment = 0;
1477 else if (Val == Attribute::StackAlignment)
1478 StackAlignment = 0;
Tim Northoverb7141202019-05-30 18:48:23 +00001479 else if (Val == Attribute::ByVal)
1480 ByValType = nullptr;
Hal Finkelb0407ba2014-07-18 15:51:28 +00001481 else if (Val == Attribute::Dereferenceable)
1482 DerefBytes = 0;
Sanjoy Das31ea6d12015-04-16 20:29:50 +00001483 else if (Val == Attribute::DereferenceableOrNull)
1484 DerefOrNullBytes = 0;
George Burgess IV278199f2016-04-12 01:05:35 +00001485 else if (Val == Attribute::AllocSize)
1486 AllocSizeArgs = 0;
Bill Wendling23804da2013-01-31 23:38:01 +00001487
1488 return *this;
1489}
1490
Reid Klecknerb5180542017-03-21 16:57:19 +00001491AttrBuilder &AttrBuilder::removeAttributes(AttributeList A, uint64_t Index) {
Reid Kleckner6652a522017-04-28 18:37:16 +00001492 remove(A.getAttributes(Index));
Bill Wendling1aa9d9e2013-01-28 05:23:28 +00001493 return *this;
1494}
1495
Bill Wendlingb9c5b1a2013-02-05 08:09:32 +00001496AttrBuilder &AttrBuilder::removeAttribute(StringRef A) {
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001497 auto I = TargetDepAttrs.find(A);
Bill Wendlingb9c5b1a2013-02-05 08:09:32 +00001498 if (I != TargetDepAttrs.end())
1499 TargetDepAttrs.erase(I);
1500 return *this;
1501}
1502
George Burgess IV278199f2016-04-12 01:05:35 +00001503std::pair<unsigned, Optional<unsigned>> AttrBuilder::getAllocSizeArgs() const {
1504 return unpackAllocSizeArgs(AllocSizeArgs);
1505}
1506
Bill Wendling50d27842012-10-15 20:35:56 +00001507AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
Bill Wendlingabd5ba22012-10-14 03:58:29 +00001508 if (Align == 0) return *this;
Bill Wendlingcd330342013-01-04 23:27:34 +00001509
Bill Wendlingabf3feb2012-10-05 06:44:41 +00001510 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1511 assert(Align <= 0x40000000 && "Alignment too large.");
Bill Wendlingcd330342013-01-04 23:27:34 +00001512
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001513 Attrs[Attribute::Alignment] = true;
Bill Wendlingcd330342013-01-04 23:27:34 +00001514 Alignment = Align;
Bill Wendlingabd5ba22012-10-14 03:58:29 +00001515 return *this;
Chris Lattner3e13b8c2008-01-02 23:42:30 +00001516}
1517
Bill Wendlingcd330342013-01-04 23:27:34 +00001518AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
1519 // Default alignment, allow the target to define how to align it.
1520 if (Align == 0) return *this;
1521
1522 assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
1523 assert(Align <= 0x100 && "Alignment too large.");
1524
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001525 Attrs[Attribute::StackAlignment] = true;
Bill Wendlingcd330342013-01-04 23:27:34 +00001526 StackAlignment = Align;
1527 return *this;
1528}
1529
Hal Finkelb0407ba2014-07-18 15:51:28 +00001530AttrBuilder &AttrBuilder::addDereferenceableAttr(uint64_t Bytes) {
1531 if (Bytes == 0) return *this;
1532
1533 Attrs[Attribute::Dereferenceable] = true;
1534 DerefBytes = Bytes;
1535 return *this;
1536}
1537
Sanjoy Das31ea6d12015-04-16 20:29:50 +00001538AttrBuilder &AttrBuilder::addDereferenceableOrNullAttr(uint64_t Bytes) {
1539 if (Bytes == 0)
1540 return *this;
1541
1542 Attrs[Attribute::DereferenceableOrNull] = true;
1543 DerefOrNullBytes = Bytes;
1544 return *this;
1545}
1546
George Burgess IV278199f2016-04-12 01:05:35 +00001547AttrBuilder &AttrBuilder::addAllocSizeAttr(unsigned ElemSize,
1548 const Optional<unsigned> &NumElems) {
1549 return addAllocSizeAttrFromRawRepr(packAllocSizeArgs(ElemSize, NumElems));
1550}
1551
1552AttrBuilder &AttrBuilder::addAllocSizeAttrFromRawRepr(uint64_t RawArgs) {
1553 // (0, 0) is our "not present" value, so we need to check for it here.
1554 assert(RawArgs && "Invalid allocsize arguments -- given allocsize(0, 0)");
1555
1556 Attrs[Attribute::AllocSize] = true;
1557 // Reuse existing machinery to store this as a single 64-bit integer so we can
1558 // save a few bytes over using a pair<unsigned, Optional<unsigned>>.
1559 AllocSizeArgs = RawArgs;
1560 return *this;
1561}
1562
Tim Northoverb7141202019-05-30 18:48:23 +00001563AttrBuilder &AttrBuilder::addByValAttr(Type *Ty) {
1564 Attrs[Attribute::ByVal] = true;
1565 ByValType = Ty;
1566 return *this;
1567}
1568
Bill Wendlinge2614922013-02-06 01:16:00 +00001569AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
1570 // FIXME: What if both have alignments, but they don't match?!
1571 if (!Alignment)
1572 Alignment = B.Alignment;
1573
1574 if (!StackAlignment)
1575 StackAlignment = B.StackAlignment;
1576
Hal Finkelb0407ba2014-07-18 15:51:28 +00001577 if (!DerefBytes)
1578 DerefBytes = B.DerefBytes;
1579
Pete Cooperd2a44612015-05-06 23:19:43 +00001580 if (!DerefOrNullBytes)
1581 DerefOrNullBytes = B.DerefOrNullBytes;
1582
George Burgess IV278199f2016-04-12 01:05:35 +00001583 if (!AllocSizeArgs)
1584 AllocSizeArgs = B.AllocSizeArgs;
1585
Tim Northoverb7141202019-05-30 18:48:23 +00001586 if (!ByValType)
1587 ByValType = B.ByValType;
1588
Benjamin Kramer45e7d532013-02-16 19:13:18 +00001589 Attrs |= B.Attrs;
Bill Wendlinge2614922013-02-06 01:16:00 +00001590
Pete Cooperd2a44612015-05-06 23:19:43 +00001591 for (auto I : B.td_attrs())
1592 TargetDepAttrs[I.first] = I.second;
Bill Wendlinge2614922013-02-06 01:16:00 +00001593
1594 return *this;
1595}
1596
Pete Cooperd2a44612015-05-06 23:19:43 +00001597AttrBuilder &AttrBuilder::remove(const AttrBuilder &B) {
1598 // FIXME: What if both have alignments, but they don't match?!
1599 if (B.Alignment)
1600 Alignment = 0;
1601
1602 if (B.StackAlignment)
1603 StackAlignment = 0;
1604
1605 if (B.DerefBytes)
1606 DerefBytes = 0;
1607
1608 if (B.DerefOrNullBytes)
1609 DerefOrNullBytes = 0;
1610
George Burgess IV278199f2016-04-12 01:05:35 +00001611 if (B.AllocSizeArgs)
1612 AllocSizeArgs = 0;
1613
Tim Northoverb7141202019-05-30 18:48:23 +00001614 if (B.ByValType)
1615 ByValType = nullptr;
1616
Pete Cooperd2a44612015-05-06 23:19:43 +00001617 Attrs &= ~B.Attrs;
1618
1619 for (auto I : B.td_attrs())
1620 TargetDepAttrs.erase(I.first);
1621
1622 return *this;
1623}
1624
1625bool AttrBuilder::overlaps(const AttrBuilder &B) const {
1626 // First check if any of the target independent attributes overlap.
1627 if ((Attrs & B.Attrs).any())
1628 return true;
1629
1630 // Then check if any target dependent ones do.
Sean Silva9011aca2017-02-22 06:34:04 +00001631 for (const auto &I : td_attrs())
Pete Cooperd2a44612015-05-06 23:19:43 +00001632 if (B.contains(I.first))
1633 return true;
1634
1635 return false;
1636}
1637
Bill Wendling4b001442013-02-06 01:33:42 +00001638bool AttrBuilder::contains(StringRef A) const {
1639 return TargetDepAttrs.find(A) != TargetDepAttrs.end();
1640}
1641
Bill Wendling50d27842012-10-15 20:35:56 +00001642bool AttrBuilder::hasAttributes() const {
Benjamin Kramereaf706b2013-02-18 12:09:51 +00001643 return !Attrs.none() || !TargetDepAttrs.empty();
Bill Wendlingc6daefa2012-10-08 23:27:46 +00001644}
Bill Wendling9ac69f92013-01-04 20:54:35 +00001645
Reid Kleckner6652a522017-04-28 18:37:16 +00001646bool AttrBuilder::hasAttributes(AttributeList AL, uint64_t Index) const {
1647 AttributeSet AS = AL.getAttributes(Index);
Bill Wendling9ca01da2013-02-02 00:42:06 +00001648
Eugene Zelenko7fb5d412018-03-30 00:47:31 +00001649 for (const auto Attr : AS) {
Hal Finkele15442c2014-07-18 06:51:55 +00001650 if (Attr.isEnumAttribute() || Attr.isIntAttribute()) {
Reid Kleckner6652a522017-04-28 18:37:16 +00001651 if (contains(Attr.getKindAsEnum()))
Bill Wendling7cde51d2013-02-12 07:56:49 +00001652 return true;
1653 } else {
1654 assert(Attr.isStringAttribute() && "Invalid attribute kind!");
Reid Kleckner6652a522017-04-28 18:37:16 +00001655 return contains(Attr.getKindAsString());
Bill Wendling7cde51d2013-02-12 07:56:49 +00001656 }
1657 }
Bill Wendling9ca01da2013-02-02 00:42:06 +00001658
1659 return false;
Bill Wendling70f39172012-10-09 00:01:21 +00001660}
Bill Wendling9ac69f92013-01-04 20:54:35 +00001661
Bill Wendling50d27842012-10-15 20:35:56 +00001662bool AttrBuilder::hasAlignmentAttr() const {
Bill Wendlingcd330342013-01-04 23:27:34 +00001663 return Alignment != 0;
Bill Wendlingc6daefa2012-10-08 23:27:46 +00001664}
1665
Bill Wendlingd509a662013-01-29 00:34:06 +00001666bool AttrBuilder::operator==(const AttrBuilder &B) {
Benjamin Kramer45e7d532013-02-16 19:13:18 +00001667 if (Attrs != B.Attrs)
1668 return false;
Bill Wendling4b001442013-02-06 01:33:42 +00001669
1670 for (td_const_iterator I = TargetDepAttrs.begin(),
1671 E = TargetDepAttrs.end(); I != E; ++I)
1672 if (B.TargetDepAttrs.find(I->first) == B.TargetDepAttrs.end())
1673 return false;
1674
Hal Finkelb0407ba2014-07-18 15:51:28 +00001675 return Alignment == B.Alignment && StackAlignment == B.StackAlignment &&
Tim Northoverb7141202019-05-30 18:48:23 +00001676 DerefBytes == B.DerefBytes && ByValType == B.ByValType;
Bill Wendlingd509a662013-01-29 00:34:06 +00001677}
1678
Bill Wendling57625a42013-01-25 23:09:36 +00001679//===----------------------------------------------------------------------===//
1680// AttributeFuncs Function Defintions
1681//===----------------------------------------------------------------------===//
1682
Adrian Prantl5f8f34e42018-05-01 15:54:18 +00001683/// Which attributes cannot be applied to a type.
Craig Toppere3dcce92015-08-01 22:20:21 +00001684AttrBuilder AttributeFuncs::typeIncompatible(Type *Ty) {
Bill Wendling57625a42013-01-25 23:09:36 +00001685 AttrBuilder Incompatible;
1686
1687 if (!Ty->isIntegerTy())
1688 // Attribute that only apply to integers.
1689 Incompatible.addAttribute(Attribute::SExt)
1690 .addAttribute(Attribute::ZExt);
1691
1692 if (!Ty->isPointerTy())
1693 // Attribute that only apply to pointers.
1694 Incompatible.addAttribute(Attribute::ByVal)
1695 .addAttribute(Attribute::Nest)
1696 .addAttribute(Attribute::NoAlias)
1697 .addAttribute(Attribute::NoCapture)
Nick Lewyckyd52b1522014-05-20 01:23:40 +00001698 .addAttribute(Attribute::NonNull)
Hal Finkelb0407ba2014-07-18 15:51:28 +00001699 .addDereferenceableAttr(1) // the int here is ignored
Sanjoy Das31ea6d12015-04-16 20:29:50 +00001700 .addDereferenceableOrNullAttr(1) // the int here is ignored
Nick Lewyckyc2ec0722013-07-06 00:29:58 +00001701 .addAttribute(Attribute::ReadNone)
1702 .addAttribute(Attribute::ReadOnly)
Reid Klecknera534a382013-12-19 02:14:12 +00001703 .addAttribute(Attribute::StructRet)
1704 .addAttribute(Attribute::InAlloca);
Bill Wendling57625a42013-01-25 23:09:36 +00001705
Pete Cooper2777d8872015-05-06 23:19:56 +00001706 return Incompatible;
Bill Wendling57625a42013-01-25 23:09:36 +00001707}
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001708
1709template<typename AttrClass>
1710static bool isEqual(const Function &Caller, const Function &Callee) {
1711 return Caller.getFnAttribute(AttrClass::getKind()) ==
1712 Callee.getFnAttribute(AttrClass::getKind());
1713}
1714
Adrian Prantl5f8f34e42018-05-01 15:54:18 +00001715/// Compute the logical AND of the attributes of the caller and the
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001716/// callee.
1717///
1718/// This function sets the caller's attribute to false if the callee's attribute
1719/// is false.
1720template<typename AttrClass>
1721static void setAND(Function &Caller, const Function &Callee) {
1722 if (AttrClass::isSet(Caller, AttrClass::getKind()) &&
1723 !AttrClass::isSet(Callee, AttrClass::getKind()))
1724 AttrClass::set(Caller, AttrClass::getKind(), false);
1725}
1726
Adrian Prantl5f8f34e42018-05-01 15:54:18 +00001727/// Compute the logical OR of the attributes of the caller and the
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001728/// callee.
1729///
1730/// This function sets the caller's attribute to true if the callee's attribute
1731/// is true.
1732template<typename AttrClass>
1733static void setOR(Function &Caller, const Function &Callee) {
1734 if (!AttrClass::isSet(Caller, AttrClass::getKind()) &&
1735 AttrClass::isSet(Callee, AttrClass::getKind()))
1736 AttrClass::set(Caller, AttrClass::getKind(), true);
1737}
1738
Adrian Prantl5f8f34e42018-05-01 15:54:18 +00001739/// If the inlined function had a higher stack protection level than the
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001740/// calling function, then bump up the caller's stack protection level.
1741static void adjustCallerSSPLevel(Function &Caller, const Function &Callee) {
1742 // If upgrading the SSP attribute, clear out the old SSP Attributes first.
1743 // Having multiple SSP attributes doesn't actually hurt, but it adds useless
1744 // clutter to the IR.
Reid Kleckneree4930b2017-05-02 22:07:37 +00001745 AttrBuilder OldSSPAttr;
1746 OldSSPAttr.addAttribute(Attribute::StackProtect)
1747 .addAttribute(Attribute::StackProtectStrong)
1748 .addAttribute(Attribute::StackProtectReq);
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001749
Evgeniy Stepanovf17120a2016-04-11 22:27:48 +00001750 if (Callee.hasFnAttribute(Attribute::StackProtectReq)) {
Reid Klecknerb5180542017-03-21 16:57:19 +00001751 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001752 Caller.addFnAttr(Attribute::StackProtectReq);
1753 } else if (Callee.hasFnAttribute(Attribute::StackProtectStrong) &&
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001754 !Caller.hasFnAttribute(Attribute::StackProtectReq)) {
Reid Klecknerb5180542017-03-21 16:57:19 +00001755 Caller.removeAttributes(AttributeList::FunctionIndex, OldSSPAttr);
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001756 Caller.addFnAttr(Attribute::StackProtectStrong);
1757 } else if (Callee.hasFnAttribute(Attribute::StackProtect) &&
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001758 !Caller.hasFnAttribute(Attribute::StackProtectReq) &&
1759 !Caller.hasFnAttribute(Attribute::StackProtectStrong))
1760 Caller.addFnAttr(Attribute::StackProtect);
1761}
1762
Adrian Prantl5f8f34e42018-05-01 15:54:18 +00001763/// If the inlined function required stack probes, then ensure that
whitequarked54b4a2017-06-21 18:46:50 +00001764/// the calling function has those too.
1765static void adjustCallerStackProbes(Function &Caller, const Function &Callee) {
whitequark08b20352017-06-22 23:22:36 +00001766 if (!Caller.hasFnAttribute("probe-stack") &&
1767 Callee.hasFnAttribute("probe-stack")) {
1768 Caller.addFnAttr(Callee.getFnAttribute("probe-stack"));
1769 }
1770}
1771
Adrian Prantl5f8f34e42018-05-01 15:54:18 +00001772/// If the inlined function defines the size of guard region
whitequark08b20352017-06-22 23:22:36 +00001773/// on the stack, then ensure that the calling function defines a guard region
1774/// that is no larger.
1775static void
1776adjustCallerStackProbeSize(Function &Caller, const Function &Callee) {
1777 if (Callee.hasFnAttribute("stack-probe-size")) {
1778 uint64_t CalleeStackProbeSize;
1779 Callee.getFnAttribute("stack-probe-size")
1780 .getValueAsString()
1781 .getAsInteger(0, CalleeStackProbeSize);
1782 if (Caller.hasFnAttribute("stack-probe-size")) {
1783 uint64_t CallerStackProbeSize;
1784 Caller.getFnAttribute("stack-probe-size")
1785 .getValueAsString()
1786 .getAsInteger(0, CallerStackProbeSize);
1787 if (CallerStackProbeSize > CalleeStackProbeSize) {
1788 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1789 }
1790 } else {
1791 Caller.addFnAttr(Callee.getFnAttribute("stack-probe-size"));
1792 }
1793 }
whitequarked54b4a2017-06-21 18:46:50 +00001794}
1795
Craig Topper1d504f72018-07-24 18:49:00 +00001796/// If the inlined function defines a min legal vector width, then ensure
Craig Topper961b9562018-11-29 07:27:38 +00001797/// the calling function has the same or larger min legal vector width. If the
1798/// caller has the attribute, but the callee doesn't, we need to remove the
1799/// attribute from the caller since we can't make any guarantees about the
1800/// caller's requirements.
1801/// This function is called after the inlining decision has been made so we have
1802/// to merge the attribute this way. Heuristics that would use
Craig Topper1d504f72018-07-24 18:49:00 +00001803/// min-legal-vector-width to determine inline compatibility would need to be
1804/// handled as part of inline cost analysis.
1805static void
1806adjustMinLegalVectorWidth(Function &Caller, const Function &Callee) {
Craig Topper961b9562018-11-29 07:27:38 +00001807 if (Caller.hasFnAttribute("min-legal-vector-width")) {
1808 if (Callee.hasFnAttribute("min-legal-vector-width")) {
Craig Topper1d504f72018-07-24 18:49:00 +00001809 uint64_t CallerVectorWidth;
1810 Caller.getFnAttribute("min-legal-vector-width")
1811 .getValueAsString()
1812 .getAsInteger(0, CallerVectorWidth);
Craig Topper961b9562018-11-29 07:27:38 +00001813 uint64_t CalleeVectorWidth;
1814 Callee.getFnAttribute("min-legal-vector-width")
1815 .getValueAsString()
1816 .getAsInteger(0, CalleeVectorWidth);
1817 if (CallerVectorWidth < CalleeVectorWidth)
Craig Topper1d504f72018-07-24 18:49:00 +00001818 Caller.addFnAttr(Callee.getFnAttribute("min-legal-vector-width"));
Craig Topper1d504f72018-07-24 18:49:00 +00001819 } else {
Craig Topper961b9562018-11-29 07:27:38 +00001820 // If the callee doesn't have the attribute then we don't know anything
1821 // and must drop the attribute from the caller.
1822 Caller.removeFnAttr("min-legal-vector-width");
Craig Topper1d504f72018-07-24 18:49:00 +00001823 }
1824 }
1825}
1826
Manoj Gupta9d83ce92018-07-30 19:33:53 +00001827/// If the inlined function has "null-pointer-is-valid=true" attribute,
1828/// set this attribute in the caller post inlining.
1829static void
1830adjustNullPointerValidAttr(Function &Caller, const Function &Callee) {
1831 if (Callee.nullPointerIsDefined() && !Caller.nullPointerIsDefined()) {
1832 Caller.addFnAttr(Callee.getFnAttribute("null-pointer-is-valid"));
1833 }
1834}
1835
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001836#define GET_ATTR_COMPAT_FUNC
1837#include "AttributesCompatFunc.inc"
1838
1839bool AttributeFuncs::areInlineCompatible(const Function &Caller,
1840 const Function &Callee) {
1841 return hasCompatibleFnAttrs(Caller, Callee);
1842}
1843
Akira Hatanaka1cb242e2015-12-22 23:57:37 +00001844void AttributeFuncs::mergeAttributesForInlining(Function &Caller,
1845 const Function &Callee) {
1846 mergeFnAttrs(Caller, Callee);
1847}