X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FIR%2FAttributes.cpp;h=bef7a6c1749cba846822a5dd4e03deaeae16b365;hb=0fecdfb7c44aee85e78e0ba6e9547b702bc64c4a;hp=5057f783bb5a727ba8c64255c84e3281c7d4f422;hpb=60507d53e7e8e6b0c537675f68204a93c3033de7;p=oota-llvm.git diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 5057f783bb5..bef7a6c1749 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -45,7 +45,8 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { // Otherwise, build a key to look up the existing attributes. LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; - ID.AddInteger(B.getBitMask()); + // FIXME: Don't look up ConstantInts here. + ID.AddPointer(ConstantInt::get(Type::getInt64Ty(Context), B.getBitMask())); void *InsertPoint; AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); @@ -76,6 +77,12 @@ unsigned Attribute::getAlignment() const { return 1U << ((pImpl->getAlignment() >> 16) - 1); } +void Attribute::setAlignment(unsigned Align) { + assert(hasAttribute(Attribute::Alignment) && + "Trying to set the alignment on a non-alignment attribute!"); + pImpl->setAlignment(Align); +} + /// This returns the stack alignment field of an attribute as a byte alignment /// value. unsigned Attribute::getStackAlignment() const { @@ -84,6 +91,12 @@ unsigned Attribute::getStackAlignment() const { return 1U << ((pImpl->getStackAlignment() >> 26) - 1); } +void Attribute::setStackAlignment(unsigned Align) { + assert(hasAttribute(Attribute::StackAlignment) && + "Trying to set the stack alignment on a non-alignment attribute!"); + pImpl->setStackAlignment(Align); +} + bool Attribute::operator==(AttrKind K) const { return pImpl && *pImpl == K; } @@ -225,97 +238,185 @@ std::string Attribute::getAsString() const { } //===----------------------------------------------------------------------===// -// AttrBuilder Implementation +// AttrBuilder Method Implementations //===----------------------------------------------------------------------===// -AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val){ - Bits |= AttributeImpl::getAttrMask(Val); +AttrBuilder::AttrBuilder(AttributeSet AS, unsigned Idx) + : Alignment(0), StackAlignment(0) { + AttributeSetImpl *pImpl = AS.AttrList; + if (!pImpl) return; + + ArrayRef AttrList = pImpl->getAttributes(); + const AttributeWithIndex *AWI = 0; + for (unsigned I = 0, E = AttrList.size(); I != E; ++I) + if (AttrList[I].Index == Idx) { + AWI = &AttrList[I]; + break; + } + + assert(AWI && "Cannot find index in attribute set!"); + + /// FIXME: This will be modified in the future. Basically, the + /// AttributeWithIndex class will contain the + +} + +void AttrBuilder::clear() { + Attrs.clear(); + Alignment = StackAlignment = 0; +} + +AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { + Attrs.insert(Val); return *this; } -AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { - Bits |= Val; +AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { + Attrs.erase(Val); + if (Val == Attribute::Alignment) + Alignment = 0; + else if (Val == Attribute::StackAlignment) + StackAlignment = 0; + return *this; } AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) { if (Align == 0) return *this; + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); assert(Align <= 0x40000000 && "Alignment too large."); - Bits |= (Log2_32(Align) + 1) << 16; + + Attrs.insert(Attribute::Alignment); + Alignment = Align; return *this; } -AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align){ + +AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) { // Default alignment, allow the target to define how to align it. if (Align == 0) return *this; + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); assert(Align <= 0x100 && "Alignment too large."); - Bits |= (Log2_32(Align) + 1) << 26; + + Attrs.insert(Attribute::StackAlignment); + StackAlignment = Align; return *this; } -AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { - Bits &= ~AttributeImpl::getAttrMask(Val); +AttrBuilder &AttrBuilder::addRawValue(uint64_t Val) { + for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; + I = Attribute::AttrKind(I + 1)) { + if (uint64_t A = (Val & AttributeImpl::getAttrMask(I))) { + Attrs.insert(I); + + if (I == Attribute::Alignment) + Alignment = 1ULL << ((A >> 16) - 1); + else if (I == Attribute::StackAlignment) + StackAlignment = 1ULL << ((A >> 26)-1); + } + } + return *this; } AttrBuilder &AttrBuilder::addAttributes(const Attribute &A) { - Bits |= A.getBitMask(); + uint64_t Mask = A.getBitMask(); + + for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; + I = Attribute::AttrKind(I + 1)) { + if (uint64_t A = (Mask & AttributeImpl::getAttrMask(I))) { + Attrs.insert(I); + + if (I == Attribute::Alignment) + Alignment = 1ULL << ((A >> 16) - 1); + else if (I == Attribute::StackAlignment) + StackAlignment = 1ULL << ((A >> 26)-1); + } + } + return *this; } AttrBuilder &AttrBuilder::removeAttributes(const Attribute &A){ - Bits &= ~A.getBitMask(); + uint64_t Mask = A.getBitMask(); + + for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; + I = Attribute::AttrKind(I + 1)) { + if (Mask & AttributeImpl::getAttrMask(I)) { + Attrs.erase(I); + + if (I == Attribute::Alignment) + Alignment = 0; + else if (I == Attribute::StackAlignment) + StackAlignment = 0; + } + } + return *this; } bool AttrBuilder::contains(Attribute::AttrKind A) const { - return Bits & AttributeImpl::getAttrMask(A); + return Attrs.count(A); } bool AttrBuilder::hasAttributes() const { - return Bits != 0; + return !Attrs.empty(); } bool AttrBuilder::hasAttributes(const Attribute &A) const { - return Bits & A.getBitMask(); + return getBitMask() & A.getBitMask(); } bool AttrBuilder::hasAlignmentAttr() const { - return Bits & AttributeImpl::getAttrMask(Attribute::Alignment); + return Alignment != 0; } -uint64_t AttrBuilder::getAlignment() const { - if (!hasAlignmentAttr()) - return 0; - return 1ULL << - (((Bits & AttributeImpl::getAttrMask(Attribute::Alignment)) >> 16) - 1); +uint64_t AttrBuilder::getBitMask() const { + uint64_t Mask = 0; + + for (DenseSet::const_iterator I = Attrs.begin(), + E = Attrs.end(); I != E; ++I) { + Attribute::AttrKind Kind = *I; + + if (Kind == Attribute::Alignment) + Mask |= (Log2_32(Alignment) + 1) << 16; + else if (Kind == Attribute::StackAlignment) + Mask |= (Log2_32(StackAlignment) + 1) << 26; + else + Mask |= AttributeImpl::getAttrMask(Kind); + } + + return Mask; } -uint64_t AttrBuilder::getStackAlignment() const { - if (!hasAlignmentAttr()) - return 0; - return 1ULL << - (((Bits & AttributeImpl::getAttrMask(Attribute::StackAlignment))>>26)-1); +bool AttrBuilder::operator==(const AttrBuilder &B) { + SmallVector This(Attrs.begin(), Attrs.end()); + SmallVector That(B.Attrs.begin(), B.Attrs.end()); + return This == That; } //===----------------------------------------------------------------------===// // AttributeImpl Definition //===----------------------------------------------------------------------===// -AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data) { +AttributeImpl::AttributeImpl(LLVMContext &C, uint64_t data) + : Context(C) { Data = ConstantInt::get(Type::getInt64Ty(C), data); } -AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) { +AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data) + : Context(C) { Data = ConstantInt::get(Type::getInt64Ty(C), data); } AttributeImpl::AttributeImpl(LLVMContext &C, Attribute::AttrKind data, - ArrayRef values) { + ArrayRef values) + : Context(C) { Data = ConstantInt::get(Type::getInt64Ty(C), data); Vals.reserve(values.size()); Vals.append(values.begin(), values.end()); } -AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) { +AttributeImpl::AttributeImpl(LLVMContext &C, StringRef data) + : Context(C) { Data = ConstantDataArray::getString(C, data); } @@ -345,6 +446,11 @@ uint64_t AttributeImpl::getBitMask() const { uint64_t AttributeImpl::getAttrMask(Attribute::AttrKind Val) { switch (Val) { + case Attribute::EndAttrKinds: + case Attribute::AttrKindEmptyKey: + case Attribute::AttrKindTombstoneKey: + llvm_unreachable("Synthetic enumerators which should never get here"); + case Attribute::None: return 0; case Attribute::ZExt: return 1 << 0; case Attribute::SExt: return 1 << 1; @@ -391,10 +497,18 @@ uint64_t AttributeImpl::getAlignment() const { return getBitMask() & getAttrMask(Attribute::Alignment); } +void AttributeImpl::setAlignment(unsigned Align) { + Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align)); +} + uint64_t AttributeImpl::getStackAlignment() const { return getBitMask() & getAttrMask(Attribute::StackAlignment); } +void AttributeImpl::setStackAlignment(unsigned Align) { + Vals.push_back(ConstantInt::get(Type::getInt64Ty(Context), Align)); +} + //===----------------------------------------------------------------------===// // AttributeSetImpl Definition //===----------------------------------------------------------------------===// @@ -420,8 +534,7 @@ AttributeSet AttributeSet::get(LLVMContext &C, AttributeSetImpl::Profile(ID, Attrs); void *InsertPoint; - AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, - InsertPoint); + AttributeSetImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, InsertPoint); // If we didn't find any existing attributes of the same shape then // create a new one and insert it. @@ -434,6 +547,23 @@ AttributeSet AttributeSet::get(LLVMContext &C, return AttributeSet(PA); } +AttributeSet AttributeSet::get(LLVMContext &C, unsigned Idx, AttrBuilder &B) { + SmallVector Attrs; + for (AttrBuilder::iterator I = B.begin(), E = B.end(); I != E; ++I) { + Attribute::AttrKind Kind = *I; + Attribute A = Attribute::get(C, Kind); + + if (Kind == Attribute::Alignment) + A.setAlignment(B.getAlignment()); + else if (Kind == Attribute::StackAlignment) + A.setStackAlignment(B.getStackAlignment()); + + Attrs.push_back(AttributeWithIndex::get(Idx, A)); + } + + return get(C, Attrs); +} + //===----------------------------------------------------------------------===// // AttributeSet Method Implementations //===----------------------------------------------------------------------===//