Attributes.cpp revision 9f175f88190fae22df9c6e68af618d0493477ff9
1//===-- Attributes.cpp - Implement AttributesList -------------------------===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// \file
11// \brief This file implements the Attribute, AttributeImpl, AttrBuilder,
12// AttributeSetImpl, and AttributeSet classes.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/IR/Attributes.h"
17#include "AttributeImpl.h"
18#include "LLVMContextImpl.h"
19#include "llvm/ADT/StringExtras.h"
20#include "llvm/IR/Type.h"
21#include "llvm/Support/Atomic.h"
22#include "llvm/Support/Debug.h"
23#include "llvm/Support/ManagedStatic.h"
24#include "llvm/Support/Mutex.h"
25#include "llvm/Support/raw_ostream.h"
26#include <algorithm>
27using namespace llvm;
28
29//===----------------------------------------------------------------------===//
30// Attribute Construction Methods
31//===----------------------------------------------------------------------===//
32
33Attribute Attribute::get(LLVMContext &Context, AttrKind Kind) {
34  AttrBuilder B;
35  return Attribute::get(Context, B.addAttribute(Kind));
36}
37
38Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) {
39  // If there are no attributes, return an empty Attribute class.
40  if (!B.hasAttributes())
41    return Attribute();
42
43  // Otherwise, build a key to look up the existing attributes.
44  LLVMContextImpl *pImpl = Context.pImpl;
45  FoldingSetNodeID ID;
46  ConstantInt *CI = ConstantInt::get(Type::getInt64Ty(Context), B.Raw());
47  ID.AddPointer(CI);
48
49  void *InsertPoint;
50  AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint);
51
52  if (!PA) {
53    // If we didn't find any existing attributes of the same shape then create a
54    // new one and insert it.
55    PA = new AttributeImpl(Context, CI);
56    pImpl->AttrsSet.InsertNode(PA, InsertPoint);
57  }
58
59  // Return the AttributesList that we found or created.
60  return Attribute(PA);
61}
62
63Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) {
64  AttrBuilder B;
65  return get(Context, B.addAlignmentAttr(Align));
66}
67
68Attribute Attribute::getWithStackAlignment(LLVMContext &Context,
69                                           uint64_t Align) {
70  AttrBuilder B;
71  return get(Context, B.addStackAlignmentAttr(Align));
72}
73
74//===----------------------------------------------------------------------===//
75// Attribute Accessor Methods
76//===----------------------------------------------------------------------===//
77
78bool Attribute::hasAttribute(AttrKind Val) const {
79  return pImpl && pImpl->hasAttribute(Val);
80}
81
82bool Attribute::hasAttributes() const {
83  return pImpl && pImpl->hasAttributes();
84}
85
86/// This returns the alignment field of an attribute as a byte alignment value.
87unsigned Attribute::getAlignment() const {
88  if (!hasAttribute(Attribute::Alignment))
89    return 0;
90  return pImpl->getAlignment();
91}
92
93/// This returns the stack alignment field of an attribute as a byte alignment
94/// value.
95unsigned Attribute::getStackAlignment() const {
96  if (!hasAttribute(Attribute::StackAlignment))
97    return 0;
98  return pImpl->getStackAlignment();
99}
100
101std::string Attribute::getAsString() const {
102  if (hasAttribute(Attribute::ZExt))
103    return "zeroext";
104  if (hasAttribute(Attribute::SExt))
105    return "signext";
106  if (hasAttribute(Attribute::NoReturn))
107    return "noreturn";
108  if (hasAttribute(Attribute::NoUnwind))
109    return "nounwind";
110  if (hasAttribute(Attribute::UWTable))
111    return "uwtable";
112  if (hasAttribute(Attribute::ReturnsTwice))
113    return "returns_twice";
114  if (hasAttribute(Attribute::InReg))
115    return "inreg";
116  if (hasAttribute(Attribute::NoAlias))
117    return "noalias";
118  if (hasAttribute(Attribute::NoCapture))
119    return "nocapture";
120  if (hasAttribute(Attribute::StructRet))
121    return "sret";
122  if (hasAttribute(Attribute::ByVal))
123    return "byval";
124  if (hasAttribute(Attribute::Nest))
125    return "nest";
126  if (hasAttribute(Attribute::ReadNone))
127    return "readnone";
128  if (hasAttribute(Attribute::ReadOnly))
129    return "readonly";
130  if (hasAttribute(Attribute::OptimizeForSize))
131    return "optsize";
132  if (hasAttribute(Attribute::NoInline))
133    return "noinline";
134  if (hasAttribute(Attribute::InlineHint))
135    return "inlinehint";
136  if (hasAttribute(Attribute::AlwaysInline))
137    return "alwaysinline";
138  if (hasAttribute(Attribute::StackProtect))
139    return "ssp";
140  if (hasAttribute(Attribute::StackProtectReq))
141    return "sspreq";
142  if (hasAttribute(Attribute::StackProtectStrong))
143    return "sspstrong";
144  if (hasAttribute(Attribute::NoRedZone))
145    return "noredzone";
146  if (hasAttribute(Attribute::NoImplicitFloat))
147    return "noimplicitfloat";
148  if (hasAttribute(Attribute::Naked))
149    return "naked";
150  if (hasAttribute(Attribute::NonLazyBind))
151    return "nonlazybind";
152  if (hasAttribute(Attribute::AddressSafety))
153    return "address_safety";
154  if (hasAttribute(Attribute::MinSize))
155    return "minsize";
156  if (hasAttribute(Attribute::StackAlignment)) {
157    std::string Result;
158    Result += "alignstack(";
159    Result += utostr(getStackAlignment());
160    Result += ")";
161    return Result;
162  }
163  if (hasAttribute(Attribute::Alignment)) {
164    std::string Result;
165    Result += "align ";
166    Result += utostr(getAlignment());
167    Result += "";
168    return Result;
169  }
170  if (hasAttribute(Attribute::NoDuplicate))
171    return "noduplicate";
172
173  llvm_unreachable("Unknown attribute");
174}
175
176bool Attribute::operator==(AttrKind K) const {
177  return pImpl && *pImpl == K;
178}
179bool Attribute::operator!=(AttrKind K) const {
180  return !(*this == K);
181}
182
183bool Attribute::operator<(Attribute A) const {
184  if (!pImpl && !A.pImpl) return false;
185  if (!pImpl) return true;
186  if (!A.pImpl) return false;
187  return *pImpl < *A.pImpl;
188}
189
190uint64_t Attribute::Raw() const {
191  return pImpl ? pImpl->Raw() : 0;
192}
193
194//===----------------------------------------------------------------------===//
195// AttributeImpl Definition
196//===----------------------------------------------------------------------===//
197
198AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind kind)
199  : Context(C) {
200  Kind = ConstantInt::get(Type::getInt64Ty(C), kind);
201}
202AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind kind,
203                             ArrayRef<Constant*> values)
204  : Context(C) {
205  Kind = ConstantInt::get(Type::getInt64Ty(C), kind);
206  Vals.reserve(values.size());
207  Vals.append(values.begin(), values.end());
208}
209AttributeImpl::AttributeImpl(LLVMContext &C, StringRef kind)
210  : Context(C) {
211  Kind = ConstantDataArray::getString(C, kind);
212}
213
214bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const {
215  return (Raw() & getAttrMask(A)) != 0;
216}
217
218bool AttributeImpl::hasAttributes() const {
219  return Raw() != 0;
220}
221
222uint64_t AttributeImpl::getAlignment() const {
223  uint64_t Mask = Raw() & getAttrMask(Attribute::Alignment);
224  return 1ULL << ((Mask >> 16) - 1);
225}
226
227uint64_t AttributeImpl::getStackAlignment() const {
228  uint64_t Mask = Raw() & getAttrMask(Attribute::StackAlignment);
229  return 1ULL << ((Mask >> 26) - 1);
230}
231
232bool AttributeImpl::operator==(Attribute::AttrKind kind) const {
233  if (ConstantInt *CI = dyn_cast<ConstantInt>(Kind))
234    return CI->getZExtValue() == kind;
235  return false;
236}
237bool AttributeImpl::operator!=(Attribute::AttrKind kind) const {
238  return !(*this == kind);
239}
240
241bool AttributeImpl::operator==(StringRef kind) const {
242  if (ConstantDataArray *CDA = dyn_cast<ConstantDataArray>(Kind))
243    if (CDA->isString())
244      return CDA->getAsString() == kind;
245  return false;
246}
247
248bool AttributeImpl::operator!=(StringRef kind) const {
249  return !(*this == kind);
250}
251
252bool AttributeImpl::operator<(const AttributeImpl &AI) const {
253  if (!Kind && !AI.Kind) return false;
254  if (!Kind && AI.Kind) return true;
255  if (Kind && !AI.Kind) return false;
256
257  ConstantInt *ThisCI = dyn_cast<ConstantInt>(Kind);
258  ConstantInt *ThatCI = dyn_cast<ConstantInt>(AI.Kind);
259
260  ConstantDataArray *ThisCDA = dyn_cast<ConstantDataArray>(Kind);
261  ConstantDataArray *ThatCDA = dyn_cast<ConstantDataArray>(AI.Kind);
262
263  if (ThisCI && ThatCI)
264    return ThisCI->getZExtValue() < ThatCI->getZExtValue();
265
266  if (ThisCI && ThatCDA)
267    return true;
268
269  if (ThisCDA && ThatCI)
270    return false;
271
272  return ThisCDA->getAsString() < ThatCDA->getAsString();
273}
274
275uint64_t AttributeImpl::Raw() const {
276  // FIXME: Remove this.
277  return cast<ConstantInt>(Kind)->getZExtValue();
278}
279
280uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) {
281  // FIXME: Remove this.
282  switch (Val) {
283  case Attribute::EndAttrKinds:
284  case Attribute::AttrKindEmptyKey:
285  case Attribute::AttrKindTombstoneKey:
286    llvm_unreachable("Synthetic enumerators which should never get here");
287
288  case Attribute::None:            return 0;
289  case Attribute::ZExt:            return 1 << 0;
290  case Attribute::SExt:            return 1 << 1;
291  case Attribute::NoReturn:        return 1 << 2;
292  case Attribute::InReg:           return 1 << 3;
293  case Attribute::StructRet:       return 1 << 4;
294  case Attribute::NoUnwind:        return 1 << 5;
295  case Attribute::NoAlias:         return 1 << 6;
296  case Attribute::ByVal:           return 1 << 7;
297  case Attribute::Nest:            return 1 << 8;
298  case Attribute::ReadNone:        return 1 << 9;
299  case Attribute::ReadOnly:        return 1 << 10;
300  case Attribute::NoInline:        return 1 << 11;
301  case Attribute::AlwaysInline:    return 1 << 12;
302  case Attribute::OptimizeForSize: return 1 << 13;
303  case Attribute::StackProtect:    return 1 << 14;
304  case Attribute::StackProtectReq: return 1 << 15;
305  case Attribute::Alignment:       return 31 << 16;
306  case Attribute::NoCapture:       return 1 << 21;
307  case Attribute::NoRedZone:       return 1 << 22;
308  case Attribute::NoImplicitFloat: return 1 << 23;
309  case Attribute::Naked:           return 1 << 24;
310  case Attribute::InlineHint:      return 1 << 25;
311  case Attribute::StackAlignment:  return 7 << 26;
312  case Attribute::ReturnsTwice:    return 1 << 29;
313  case Attribute::UWTable:         return 1 << 30;
314  case Attribute::NonLazyBind:     return 1U << 31;
315  case Attribute::AddressSafety:   return 1ULL << 32;
316  case Attribute::MinSize:         return 1ULL << 33;
317  case Attribute::NoDuplicate:     return 1ULL << 34;
318  case Attribute::StackProtectStrong: return 1ULL << 35;
319  }
320  llvm_unreachable("Unsupported attribute type");
321}
322
323//===----------------------------------------------------------------------===//
324// AttributeSetNode Definition
325//===----------------------------------------------------------------------===//
326
327AttributeSetNode *AttributeSetNode::get(LLVMContext &C,
328                                        ArrayRef<Attribute> Attrs) {
329  if (Attrs.empty())
330    return 0;
331
332  // Otherwise, build a key to look up the existing attributes.
333  LLVMContextImpl *pImpl = C.pImpl;
334  FoldingSetNodeID ID;
335
336  SmallVector<Attribute, 8> SortedAttrs(Attrs.begin(), Attrs.end());
337  std::sort(SortedAttrs.begin(), SortedAttrs.end());
338
339  for (SmallVectorImpl<Attribute>::iterator I = SortedAttrs.begin(),
340         E = SortedAttrs.end(); I != E; ++I)
341    I->Profile(ID);
342
343  void *InsertPoint;
344  AttributeSetNode *PA =
345    pImpl->AttrsSetNodes.FindNodeOrInsertPos(ID, InsertPoint);
346
347  // If we didn't find any existing attributes of the same shape then create a
348  // new one and insert it.
349  if (!PA) {
350    PA = new AttributeSetNode(SortedAttrs);
351    pImpl->AttrsSetNodes.InsertNode(PA, InsertPoint);
352  }
353
354  // Return the AttributesListNode that we found or created.
355  return PA;
356}
357
358bool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const {
359  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
360         E = AttrList.end(); I != E; ++I)
361    if (I->hasAttribute(Kind))
362      return true;
363  return false;
364}
365
366unsigned AttributeSetNode::getAlignment() const {
367  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
368         E = AttrList.end(); I != E; ++I)
369    if (I->hasAttribute(Attribute::Alignment))
370      return I->getAlignment();
371  return 0;
372}
373
374unsigned AttributeSetNode::getStackAlignment() const {
375  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
376         E = AttrList.end(); I != E; ++I)
377    if (I->hasAttribute(Attribute::StackAlignment))
378      return I->getStackAlignment();
379  return 0;
380}
381
382std::string AttributeSetNode::getAsString() const {
383  std::string Str = "";
384  for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(),
385         E = AttrList.end(); I != E; ++I) {
386    if (I != AttrList.begin()) Str += " ";
387    Str += I->getAsString();
388  }
389  return Str;
390}
391
392//===----------------------------------------------------------------------===//
393// AttributeSetImpl Definition
394//===----------------------------------------------------------------------===//
395
396uint64_t AttributeSetImpl::Raw(uint64_t Index) const {
397  for (unsigned I = 0, E = getNumAttributes(); I != E; ++I) {
398    if (getSlotIndex(I) != Index) continue;
399    const AttributeSetNode *ASN = AttrNodes[I].second;
400    AttrBuilder B;
401
402    for (AttributeSetNode::const_iterator II = ASN->begin(),
403           IE = ASN->end(); II != IE; ++II)
404      B.addAttributes(*II);
405    return B.Raw();
406  }
407
408  return 0;
409}
410
411//===----------------------------------------------------------------------===//
412// AttributeSet Construction and Mutation Methods
413//===----------------------------------------------------------------------===//
414
415AttributeSet
416AttributeSet::getImpl(LLVMContext &C,
417                      ArrayRef<std::pair<unsigned, AttributeSetNode*> > Attrs) {
418  LLVMContextImpl *pImpl = C.pImpl;
419  FoldingSetNodeID ID;
420  AttributeSetImpl::Profile(ID, Attrs);
421
422  void *InsertPoint;
423  AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint);
424
425  // If we didn't find any existing attributes of the same shape then
426  // create a new one and insert it.
427  if (!PA) {
428    PA = new AttributeSetImpl(C, Attrs);
429    pImpl->AttrsLists.InsertNode(PA, InsertPoint);
430  }
431
432  // Return the AttributesList that we found or created.
433  return AttributeSet(PA);
434}
435
436AttributeSet AttributeSet::get(LLVMContext &C,
437                               ArrayRef<std::pair<unsigned, Attribute> > Attrs){
438  // If there are no attributes then return a null AttributesList pointer.
439  if (Attrs.empty())
440    return AttributeSet();
441
442#ifndef NDEBUG
443  for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
444    assert((!i || Attrs[i-1].first <= Attrs[i].first) &&
445           "Misordered Attributes list!");
446    assert(Attrs[i].second.hasAttributes() &&
447           "Pointless attribute!");
448  }
449#endif
450
451  // Create a vector if (unsigned, AttributeSetNode*) pairs from the attributes
452  // list.
453  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrPairVec;
454  for (ArrayRef<std::pair<unsigned, Attribute> >::iterator I = Attrs.begin(),
455         E = Attrs.end(); I != E; ) {
456    unsigned Index = I->first;
457    SmallVector<Attribute, 4> AttrVec;
458    while (I != E && I->first == Index) {
459      AttrVec.push_back(I->second);
460      ++I;
461    }
462
463    AttrPairVec.push_back(std::make_pair(Index,
464                                         AttributeSetNode::get(C, AttrVec)));
465  }
466
467  return getImpl(C, AttrPairVec);
468}
469
470AttributeSet AttributeSet::get(LLVMContext &C,
471                               ArrayRef<std::pair<unsigned,
472                                                  AttributeSetNode*> > Attrs) {
473  // If there are no attributes then return a null AttributesList pointer.
474  if (Attrs.empty())
475    return AttributeSet();
476
477  return getImpl(C, Attrs);
478}
479
480AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) {
481  if (!B.hasAttributes())
482    return AttributeSet();
483
484  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
485  for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) {
486    Attribute::AttrKind Kind = *I;
487    if (Kind == Attribute::Alignment)
488      Attrs.push_back(std::make_pair(Idx, Attribute::
489                                     getWithAlignment(C, B.getAlignment())));
490    else if (Kind == Attribute::StackAlignment)
491      Attrs.push_back(std::make_pair(Idx, Attribute::
492                              getWithStackAlignment(C, B.getStackAlignment())));
493    else
494      Attrs.push_back(std::make_pair(Idx, Attribute::get(C, Kind)));
495  }
496
497  return get(C, Attrs);
498}
499
500AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx,
501                               ArrayRef<Attribute::AttrKind> Kind) {
502  SmallVector<std::pair<unsigned, Attribute>, 8> Attrs;
503  for (ArrayRef<Attribute::AttrKind>::iterator I = Kind.begin(),
504         E = Kind.end(); I != E; ++I)
505    Attrs.push_back(std::make_pair(Idx, Attribute::get(C, *I)));
506  return get(C, Attrs);
507}
508
509AttributeSet AttributeSet::get(LLVMContext &C, ArrayRef<AttributeSet> Attrs) {
510  if (Attrs.empty()) return AttributeSet();
511
512  SmallVector<std::pair<unsigned, AttributeSetNode*>, 8> AttrNodeVec;
513  for (unsigned I = 0, E = Attrs.size(); I != E; ++I) {
514    AttributeSet AS = Attrs[I];
515    if (!AS.pImpl) continue;
516    AttrNodeVec.append(AS.pImpl->AttrNodes.begin(), AS.pImpl->AttrNodes.end());
517  }
518
519  return getImpl(C, AttrNodeVec);
520}
521
522AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Idx,
523                                        Attribute::AttrKind Attr) const {
524  return addAttributes(C, Idx, AttributeSet::get(C, Idx, Attr));
525}
526
527AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx,
528                                         AttributeSet Attrs) const {
529  if (!pImpl) return Attrs;
530  if (!Attrs.pImpl) return *this;
531
532#ifndef NDEBUG
533  // FIXME it is not obvious how this should work for alignment. For now, say
534  // we can't change a known alignment.
535  unsigned OldAlign = getParamAlignment(Idx);
536  unsigned NewAlign = Attrs.getParamAlignment(Idx);
537  assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
538         "Attempt to change alignment!");
539#endif
540
541  // Add the attribute slots before the one we're trying to add.
542  SmallVector<AttributeSet, 4> AttrSet;
543  uint64_t NumAttrs = pImpl->getNumAttributes();
544  AttributeSet AS;
545  uint64_t LastIndex = 0;
546  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
547    if (getSlotIndex(I) >= Idx) {
548      if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++);
549      break;
550    }
551    LastIndex = I + 1;
552    AttrSet.push_back(getSlotAttributes(I));
553  }
554
555  // Now add the attribute into the correct slot. There may already be an
556  // AttributeSet there.
557  AttrBuilder B(AS, Idx);
558
559  for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I)
560    if (Attrs.getSlotIndex(I) == Idx) {
561      for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I),
562             IE = Attrs.pImpl->end(I); II != IE; ++II)
563        B.addAttributes(*II);
564      break;
565    }
566
567  AttrSet.push_back(AttributeSet::get(C, Idx, B));
568
569  // Add the remaining attribute slots.
570  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
571    AttrSet.push_back(getSlotAttributes(I));
572
573  return get(C, AttrSet);
574}
575
576AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Idx,
577                                           Attribute::AttrKind Attr) const {
578  return removeAttributes(C, Idx, AttributeSet::get(C, Idx, Attr));
579}
580
581AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx,
582                                            AttributeSet Attrs) const {
583  if (!pImpl) return AttributeSet();
584  if (!Attrs.pImpl) return *this;
585
586#ifndef NDEBUG
587  // FIXME it is not obvious how this should work for alignment.
588  // For now, say we can't pass in alignment, which no current use does.
589  assert(!Attrs.hasAttribute(Idx, Attribute::Alignment) &&
590         "Attempt to change alignment!");
591#endif
592
593  // Add the attribute slots before the one we're trying to add.
594  SmallVector<AttributeSet, 4> AttrSet;
595  uint64_t NumAttrs = pImpl->getNumAttributes();
596  AttributeSet AS;
597  uint64_t LastIndex = 0;
598  for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
599    if (getSlotIndex(I) >= Idx) {
600      if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++);
601      break;
602    }
603    LastIndex = I + 1;
604    AttrSet.push_back(getSlotAttributes(I));
605  }
606
607  // Now add the attribute into the correct slot. There may already be an
608  // AttributeSet there.
609  AttrBuilder B(AS, Idx);
610
611  for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I)
612    if (Attrs.getSlotIndex(I) == Idx) {
613      for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I),
614             IE = Attrs.pImpl->end(I); II != IE; ++II)
615        B.removeAttributes(*II);
616      break;
617    }
618
619  AttrSet.push_back(AttributeSet::get(C, Idx, B));
620
621  // Add the remaining attribute slots.
622  for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
623    AttrSet.push_back(getSlotAttributes(I));
624
625  return get(C, AttrSet);
626}
627
628//===----------------------------------------------------------------------===//
629// AttributeSet Accessor Methods
630//===----------------------------------------------------------------------===//
631
632AttributeSet AttributeSet::getParamAttributes(unsigned Idx) const {
633  return pImpl && hasAttributes(Idx) ?
634    AttributeSet::get(pImpl->getContext(),
635                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
636                        std::make_pair(Idx, getAttributes(Idx)))) :
637    AttributeSet();
638}
639
640AttributeSet AttributeSet::getRetAttributes() const {
641  return pImpl && hasAttributes(ReturnIndex) ?
642    AttributeSet::get(pImpl->getContext(),
643                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
644                        std::make_pair(ReturnIndex,
645                                       getAttributes(ReturnIndex)))) :
646    AttributeSet();
647}
648
649AttributeSet AttributeSet::getFnAttributes() const {
650  return pImpl && hasAttributes(FunctionIndex) ?
651    AttributeSet::get(pImpl->getContext(),
652                      ArrayRef<std::pair<unsigned, AttributeSetNode*> >(
653                        std::make_pair(FunctionIndex,
654                                       getAttributes(FunctionIndex)))) :
655    AttributeSet();
656}
657
658bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{
659  AttributeSetNode *ASN = getAttributes(Index);
660  return ASN ? ASN->hasAttribute(Kind) : false;
661}
662
663bool AttributeSet::hasAttributes(unsigned Index) const {
664  AttributeSetNode *ASN = getAttributes(Index);
665  return ASN ? ASN->hasAttributes() : false;
666}
667
668/// \brief Return true if the specified attribute is set for at least one
669/// parameter or for the return value.
670bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const {
671  if (pImpl == 0) return false;
672
673  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I)
674    for (AttributeSetImpl::const_iterator II = pImpl->begin(I),
675           IE = pImpl->end(I); II != IE; ++II)
676      if (II->hasAttribute(Attr))
677        return true;
678
679  return false;
680}
681
682unsigned AttributeSet::getParamAlignment(unsigned Index) const {
683  AttributeSetNode *ASN = getAttributes(Index);
684  return ASN ? ASN->getAlignment() : 0;
685}
686
687unsigned AttributeSet::getStackAlignment(unsigned Index) const {
688  AttributeSetNode *ASN = getAttributes(Index);
689  return ASN ? ASN->getStackAlignment() : 0;
690}
691
692std::string AttributeSet::getAsString(unsigned Index) const {
693  AttributeSetNode *ASN = getAttributes(Index);
694  return ASN ? ASN->getAsString() : std::string("");
695}
696
697/// \brief The attributes for the specified index are returned.
698AttributeSetNode *AttributeSet::getAttributes(unsigned Idx) const {
699  if (!pImpl) return 0;
700
701  // Loop through to find the attribute node we want.
702  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I)
703    if (pImpl->getSlotIndex(I) == Idx)
704      return pImpl->getSlotNode(I);
705
706  return 0;
707}
708
709//===----------------------------------------------------------------------===//
710// AttributeSet Introspection Methods
711//===----------------------------------------------------------------------===//
712
713/// \brief Return the number of slots used in this attribute list.  This is the
714/// number of arguments that have an attribute set on them (including the
715/// function itself).
716unsigned AttributeSet::getNumSlots() const {
717  return pImpl ? pImpl->getNumAttributes() : 0;
718}
719
720uint64_t AttributeSet::getSlotIndex(unsigned Slot) const {
721  assert(pImpl && Slot < pImpl->getNumAttributes() &&
722         "Slot # out of range!");
723  return pImpl->getSlotIndex(Slot);
724}
725
726AttributeSet AttributeSet::getSlotAttributes(unsigned Slot) const {
727  assert(pImpl && Slot < pImpl->getNumAttributes() &&
728         "Slot # out of range!");
729  return pImpl->getSlotAttributes(Slot);
730}
731
732uint64_t AttributeSet::Raw(unsigned Index) const {
733  // FIXME: Remove this.
734  return pImpl ? pImpl->Raw(Index) : 0;
735}
736
737void AttributeSet::dump() const {
738  dbgs() << "PAL[\n";
739
740  for (unsigned i = 0, e = getNumSlots(); i < e; ++i) {
741    uint64_t Index = getSlotIndex(i);
742    dbgs() << "  { ";
743    if (Index == ~0U)
744      dbgs() << "~0U";
745    else
746      dbgs() << Index;
747    dbgs() << " => " << getAsString(Index) << " }\n";
748  }
749
750  dbgs() << "]\n";
751}
752
753//===----------------------------------------------------------------------===//
754// AttrBuilder Method Implementations
755//===----------------------------------------------------------------------===//
756
757AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx)
758  : Alignment(0), StackAlignment(0) {
759  AttributeSetImpl *pImpl = AS.pImpl;
760  if (!pImpl) return;
761
762  AttrBuilder B;
763
764  for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) {
765    if (pImpl->getSlotIndex(I) != Idx) continue;
766
767    for (AttributeSetNode::const_iterator II = pImpl->begin(I),
768           IE = pImpl->end(I); II != IE; ++II)
769      B.addAttributes(*II);
770
771    break;
772  }
773
774  if (!B.hasAttributes()) return;
775
776  uint64_t Mask = B.Raw();
777
778  for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
779       I = Attribute::AttrKind(I + 1)) {
780    if (uint64_t A = (Mask & AttributeImpl::getAttrMask(I))) {
781      Attrs.insert(I);
782
783      if (I == Attribute::Alignment)
784        Alignment = 1ULL << ((A >> 16) - 1);
785      else if (I == Attribute::StackAlignment)
786        StackAlignment = 1ULL << ((A >> 26)-1);
787    }
788  }
789}
790
791void AttrBuilder::clear() {
792  Attrs.clear();
793  Alignment = StackAlignment = 0;
794}
795
796AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) {
797  Attrs.insert(Val);
798  return *this;
799}
800
801AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) {
802  Attrs.erase(Val);
803  if (Val == Attribute::Alignment)
804    Alignment = 0;
805  else if (Val == Attribute::StackAlignment)
806    StackAlignment = 0;
807
808  return *this;
809}
810
811AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) {
812  uint64_t Mask = Attr.Raw();
813
814  for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
815       I = Attribute::AttrKind(I + 1))
816    if ((Mask & AttributeImpl::getAttrMask(I)) != 0)
817      Attrs.insert(I);
818
819  if (Attr.getAlignment())
820    Alignment = Attr.getAlignment();
821  if (Attr.getStackAlignment())
822    StackAlignment = Attr.getStackAlignment();
823  return *this;
824}
825
826AttrBuilder &AttrBuilder::removeAttributes(Attribute A) {
827  uint64_t Mask = A.Raw();
828
829  for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
830       I = Attribute::AttrKind(I + 1)) {
831    if (Mask & AttributeImpl::getAttrMask(I)) {
832      Attrs.erase(I);
833
834      if (I == Attribute::Alignment)
835        Alignment = 0;
836      else if (I == Attribute::StackAlignment)
837        StackAlignment = 0;
838    }
839  }
840
841  return *this;
842}
843
844AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
845  if (Align == 0) return *this;
846
847  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
848  assert(Align <= 0x40000000 && "Alignment too large.");
849
850  Attrs.insert(Attribute::Alignment);
851  Alignment = Align;
852  return *this;
853}
854
855AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
856  // Default alignment, allow the target to define how to align it.
857  if (Align == 0) return *this;
858
859  assert(isPowerOf2_32(Align) && "Alignment must be a power of two.");
860  assert(Align <= 0x100 && "Alignment too large.");
861
862  Attrs.insert(Attribute::StackAlignment);
863  StackAlignment = Align;
864  return *this;
865}
866
867bool AttrBuilder::contains(Attribute::AttrKind A) const {
868  return Attrs.count(A);
869}
870
871bool AttrBuilder::hasAttributes() const {
872  return !Attrs.empty();
873}
874
875bool AttrBuilder::hasAttributes(const Attribute &A) const {
876  return Raw() & A.Raw();
877}
878
879bool AttrBuilder::hasAlignmentAttr() const {
880  return Alignment != 0;
881}
882
883bool AttrBuilder::operator==(const AttrBuilder &B) {
884  SmallVector<Attribute::AttrKind, 8> This(Attrs.begin(), Attrs.end());
885  SmallVector<Attribute::AttrKind, 8> That(B.Attrs.begin(), B.Attrs.end());
886  return This == That;
887}
888
889AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) {
890  if (!Val) return *this;
891
892  for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
893       I = Attribute::AttrKind(I + 1)) {
894    if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) {
895      Attrs.insert(I);
896
897      if (I == Attribute::Alignment)
898        Alignment = 1ULL << ((A >> 16) - 1);
899      else if (I == Attribute::StackAlignment)
900        StackAlignment = 1ULL << ((A >> 26)-1);
901    }
902  }
903
904  return *this;
905}
906
907uint64_t AttrBuilder::Raw() const {
908  uint64_t Mask = 0;
909
910  for (DenseSet<Attribute::AttrKind>::const_iterator I = Attrs.begin(),
911         E = Attrs.end(); I != E; ++I) {
912    Attribute::AttrKind Kind = *I;
913
914    if (Kind == Attribute::Alignment)
915      Mask |= (Log2_32(Alignment) + 1) << 16;
916    else if (Kind == Attribute::StackAlignment)
917      Mask |= (Log2_32(StackAlignment) + 1) << 26;
918    else
919      Mask |= AttributeImpl::getAttrMask(Kind);
920  }
921
922  return Mask;
923}
924
925//===----------------------------------------------------------------------===//
926// AttributeFuncs Function Defintions
927//===----------------------------------------------------------------------===//
928
929Attribute AttributeFuncs::typeIncompatible(Type *Ty) {
930  AttrBuilder Incompatible;
931
932  if (!Ty->isIntegerTy())
933    // Attribute that only apply to integers.
934    Incompatible.addAttribute(Attribute::SExt)
935      .addAttribute(Attribute::ZExt);
936
937  if (!Ty->isPointerTy())
938    // Attribute that only apply to pointers.
939    Incompatible.addAttribute(Attribute::ByVal)
940      .addAttribute(Attribute::Nest)
941      .addAttribute(Attribute::NoAlias)
942      .addAttribute(Attribute::NoCapture)
943      .addAttribute(Attribute::StructRet);
944
945  return Attribute::get(Ty->getContext(), Incompatible);
946}
947
948/// \brief This returns an integer containing an encoding of all the LLVM
949/// attributes found in the given attribute bitset.  Any change to this encoding
950/// is a breaking change to bitcode compatibility.
951/// N.B. This should be used only by the bitcode reader!
952uint64_t AttributeFuncs::encodeLLVMAttributesForBitcode(AttributeSet Attrs,
953                                                        unsigned Index) {
954  // FIXME: It doesn't make sense to store the alignment information as an
955  // expanded out value, we should store it as a log2 value.  However, we can't
956  // just change that here without breaking bitcode compatibility.  If this ever
957  // becomes a problem in practice, we should introduce new tag numbers in the
958  // bitcode file and have those tags use a more efficiently encoded alignment
959  // field.
960
961  // Store the alignment in the bitcode as a 16-bit raw value instead of a 5-bit
962  // log2 encoded value. Shift the bits above the alignment up by 11 bits.
963  uint64_t EncodedAttrs = Attrs.Raw(Index) & 0xffff;
964  if (Attrs.hasAttribute(Index, Attribute::Alignment))
965    EncodedAttrs |= Attrs.getParamAlignment(Index) << 16;
966  EncodedAttrs |= (Attrs.Raw(Index) & (0xffffULL << 21)) << 11;
967  return EncodedAttrs;
968}
969
970/// \brief This fills an AttrBuilder object with the LLVM attributes that have
971/// been decoded from the given integer. This function must stay in sync with
972/// 'encodeLLVMAttributesForBitcode'.
973/// N.B. This should be used only by the bitcode reader!
974void AttributeFuncs::decodeLLVMAttributesForBitcode(LLVMContext &C,
975                                                    AttrBuilder &B,
976                                                    uint64_t EncodedAttrs) {
977  // The alignment is stored as a 16-bit raw value from bits 31--16.  We shift
978  // the bits above 31 down by 11 bits.
979  unsigned Alignment = (EncodedAttrs & (0xffffULL << 16)) >> 16;
980  assert((!Alignment || isPowerOf2_32(Alignment)) &&
981         "Alignment must be a power of two.");
982
983  if (Alignment)
984    B.addAlignmentAttr(Alignment);
985  B.addRawValue(((EncodedAttrs & (0xffffULL << 32)) >> 11) |
986                (EncodedAttrs & 0xffff));
987}
988