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