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