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