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