diff options
-rw-r--r-- | include/llvm/IR/Attributes.h | 2 | ||||
-rw-r--r-- | lib/IR/AttributeImpl.h | 14 | ||||
-rw-r--r-- | lib/IR/Attributes.cpp | 155 | ||||
-rw-r--r-- | test/Transforms/FunctionAttrs/atomic.ll | 4 | ||||
-rw-r--r-- | test/Transforms/Inline/inline_ssp.ll | 20 |
5 files changed, 120 insertions, 75 deletions
diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 1aa733efbf..1578789df6 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -180,7 +180,7 @@ private: /// \brief The attributes for the specified index are returned. Attributes /// for the result are denoted with Idx = 0. - Attribute getAttributes(unsigned Idx) const; + AttributeSetNode *getAttributes(unsigned Idx) const; /// \brief Create an AttributeSet with the specified parameters in it. static AttributeSet get(LLVMContext &C, diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index 34754e8e54..91f5005639 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -18,6 +18,7 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/IR/Attributes.h" +#include <string> namespace llvm { @@ -92,6 +93,13 @@ class AttributeSetNode : public FoldingSetNode { public: static AttributeSetNode *get(LLVMContext &C, ArrayRef<Attribute> Attrs); + bool hasAttribute(Attribute::AttrKind Kind) const; + bool hasAttributes() const { return !AttrList.empty(); } + + unsigned getAlignment() const; + unsigned getStackAlignment() const; + std::string getAsString() const; + typedef SmallVectorImpl<Attribute>::iterator iterator; typedef SmallVectorImpl<Attribute>::const_iterator const_iterator; @@ -152,6 +160,12 @@ public: return AttributeSet::get(Context, AttrNodes[Slot]); } + /// \brief Retrieve the attribute set node for the given "slot" in the + /// AttrNode list. + AttributeSetNode *getSlotNode(unsigned Slot) const { + return AttrNodes[Slot].second; + } + typedef AttributeSetNode::iterator iterator; typedef AttributeSetNode::const_iterator const_iterator; diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 8250330871..ab29766e9f 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -99,77 +99,78 @@ unsigned Attribute::getStackAlignment() const { } std::string Attribute::getAsString() const { - std::string Result; if (hasAttribute(Attribute::ZExt)) - Result += "zeroext "; + return "zeroext"; if (hasAttribute(Attribute::SExt)) - Result += "signext "; + return "signext"; if (hasAttribute(Attribute::NoReturn)) - Result += "noreturn "; + return "noreturn"; if (hasAttribute(Attribute::NoUnwind)) - Result += "nounwind "; + return "nounwind"; if (hasAttribute(Attribute::UWTable)) - Result += "uwtable "; + return "uwtable"; if (hasAttribute(Attribute::ReturnsTwice)) - Result += "returns_twice "; + return "returns_twice"; if (hasAttribute(Attribute::InReg)) - Result += "inreg "; + return "inreg"; if (hasAttribute(Attribute::NoAlias)) - Result += "noalias "; + return "noalias"; if (hasAttribute(Attribute::NoCapture)) - Result += "nocapture "; + return "nocapture"; if (hasAttribute(Attribute::StructRet)) - Result += "sret "; + return "sret"; if (hasAttribute(Attribute::ByVal)) - Result += "byval "; + return "byval"; if (hasAttribute(Attribute::Nest)) - Result += "nest "; + return "nest"; if (hasAttribute(Attribute::ReadNone)) - Result += "readnone "; + return "readnone"; if (hasAttribute(Attribute::ReadOnly)) - Result += "readonly "; + return "readonly"; if (hasAttribute(Attribute::OptimizeForSize)) - Result += "optsize "; + return "optsize"; if (hasAttribute(Attribute::NoInline)) - Result += "noinline "; + return "noinline"; if (hasAttribute(Attribute::InlineHint)) - Result += "inlinehint "; + return "inlinehint"; if (hasAttribute(Attribute::AlwaysInline)) - Result += "alwaysinline "; + return "alwaysinline"; if (hasAttribute(Attribute::StackProtect)) - Result += "ssp "; + return "ssp"; if (hasAttribute(Attribute::StackProtectReq)) - Result += "sspreq "; + return "sspreq"; if (hasAttribute(Attribute::StackProtectStrong)) - Result += "sspstrong "; + return "sspstrong"; if (hasAttribute(Attribute::NoRedZone)) - Result += "noredzone "; + return "noredzone"; if (hasAttribute(Attribute::NoImplicitFloat)) - Result += "noimplicitfloat "; + return "noimplicitfloat"; if (hasAttribute(Attribute::Naked)) - Result += "naked "; + return "naked"; if (hasAttribute(Attribute::NonLazyBind)) - Result += "nonlazybind "; + return "nonlazybind"; if (hasAttribute(Attribute::AddressSafety)) - Result += "address_safety "; + return "address_safety"; if (hasAttribute(Attribute::MinSize)) - Result += "minsize "; + return "minsize"; if (hasAttribute(Attribute::StackAlignment)) { + std::string Result; Result += "alignstack("; Result += utostr(getStackAlignment()); - Result += ") "; + Result += ")"; + return Result; } if (hasAttribute(Attribute::Alignment)) { + std::string Result; Result += "align "; Result += utostr(getAlignment()); - Result += " "; + Result += ""; + return Result; } if (hasAttribute(Attribute::NoDuplicate)) - Result += "noduplicate "; - // Trim the trailing space. - assert(!Result.empty() && "Unknown attribute!"); - Result.erase(Result.end()-1); - return Result; + return "noduplicate"; + + llvm_unreachable("Unknown attribute"); } bool Attribute::operator==(AttrKind K) const { @@ -354,6 +355,40 @@ AttributeSetNode *AttributeSetNode::get(LLVMContext &C, return PA; } +bool AttributeSetNode::hasAttribute(Attribute::AttrKind Kind) const { + for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), + E = AttrList.end(); I != E; ++I) + if (I->hasAttribute(Kind)) + return true; + return false; +} + +unsigned AttributeSetNode::getAlignment() const { + for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), + E = AttrList.end(); I != E; ++I) + if (I->hasAttribute(Attribute::Alignment)) + return I->getAlignment(); + return 0; +} + +unsigned AttributeSetNode::getStackAlignment() const { + for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), + E = AttrList.end(); I != E; ++I) + if (I->hasAttribute(Attribute::StackAlignment)) + return I->getStackAlignment(); + return 0; +} + +std::string AttributeSetNode::getAsString() const { + std::string Str = ""; + for (SmallVectorImpl<Attribute>::const_iterator I = AttrList.begin(), + E = AttrList.end(); I != E; ++I) { + if (I != AttrList.begin()) Str += " "; + Str += I->getAsString(); + } + return Str; +} + //===----------------------------------------------------------------------===// // AttributeSetImpl Definition //===----------------------------------------------------------------------===// @@ -597,7 +632,7 @@ AttributeSet AttributeSet::removeAttributes(LLVMContext &C, unsigned Idx, AttributeSet AttributeSet::getParamAttributes(unsigned Idx) const { return pImpl && hasAttributes(Idx) ? AttributeSet::get(pImpl->getContext(), - ArrayRef<std::pair<unsigned, Attribute> >( + ArrayRef<std::pair<unsigned, AttributeSetNode*> >( std::make_pair(Idx, getAttributes(Idx)))) : AttributeSet(); } @@ -605,7 +640,7 @@ AttributeSet AttributeSet::getParamAttributes(unsigned Idx) const { AttributeSet AttributeSet::getRetAttributes() const { return pImpl && hasAttributes(ReturnIndex) ? AttributeSet::get(pImpl->getContext(), - ArrayRef<std::pair<unsigned, Attribute> >( + ArrayRef<std::pair<unsigned, AttributeSetNode*> >( std::make_pair(ReturnIndex, getAttributes(ReturnIndex)))) : AttributeSet(); @@ -614,18 +649,20 @@ AttributeSet AttributeSet::getRetAttributes() const { AttributeSet AttributeSet::getFnAttributes() const { return pImpl && hasAttributes(FunctionIndex) ? AttributeSet::get(pImpl->getContext(), - ArrayRef<std::pair<unsigned, Attribute> >( + ArrayRef<std::pair<unsigned, AttributeSetNode*> >( std::make_pair(FunctionIndex, getAttributes(FunctionIndex)))) : AttributeSet(); } bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{ - return getAttributes(Index).hasAttribute(Kind); + AttributeSetNode *ASN = getAttributes(Index); + return ASN ? ASN->hasAttribute(Kind) : false; } bool AttributeSet::hasAttributes(unsigned Index) const { - return getAttributes(Index).hasAttributes(); + AttributeSetNode *ASN = getAttributes(Index); + return ASN ? ASN->hasAttributes() : false; } /// \brief Return true if the specified attribute is set for at least one @@ -642,36 +679,31 @@ bool AttributeSet::hasAttrSomewhere(Attribute::AttrKind Attr) const { return false; } -unsigned AttributeSet::getParamAlignment(unsigned Idx) const { - return getAttributes(Idx).getAlignment(); +unsigned AttributeSet::getParamAlignment(unsigned Index) const { + AttributeSetNode *ASN = getAttributes(Index); + return ASN ? ASN->getAlignment() : 0; } unsigned AttributeSet::getStackAlignment(unsigned Index) const { - return getAttributes(Index).getStackAlignment(); + AttributeSetNode *ASN = getAttributes(Index); + return ASN ? ASN->getStackAlignment() : 0; } std::string AttributeSet::getAsString(unsigned Index) const { - return getAttributes(Index).getAsString(); + AttributeSetNode *ASN = getAttributes(Index); + return ASN ? ASN->getAsString() : std::string(""); } /// \brief The attributes for the specified index are returned. -/// -/// FIXME: This shouldn't return 'Attribute'. -Attribute AttributeSet::getAttributes(unsigned Idx) const { - if (pImpl == 0) return Attribute(); - - // Loop through to find the attribute we want. - for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) { - if (pImpl->getSlotIndex(I) != Idx) continue; +AttributeSetNode *AttributeSet::getAttributes(unsigned Idx) const { + if (!pImpl) return 0; - AttrBuilder B; - for (AttributeSetImpl::const_iterator II = pImpl->begin(I), - IE = pImpl->end(I); II != IE; ++II) - B.addAttributes(*II); - return Attribute::get(pImpl->getContext(), B); - } + // Loop through to find the attribute node we want. + for (unsigned I = 0, E = pImpl->getNumAttributes(); I != E; ++I) + if (pImpl->getSlotIndex(I) == Idx) + return pImpl->getSlotNode(I); - return Attribute(); + return 0; } //===----------------------------------------------------------------------===// @@ -948,9 +980,8 @@ void AttributeFuncs::decodeLLVMAttributesForBitcode(LLVMContext &C, assert((!Alignment || isPowerOf2_32(Alignment)) && "Alignment must be a power of two."); - B.addRawValue(EncodedAttrs & 0xffff); if (Alignment) B.addAlignmentAttr(Alignment); - B.addRawValue((EncodedAttrs & (0xffffULL << 32)) >> 11); + B.addRawValue(((EncodedAttrs & (0xffffULL << 32)) >> 11) | + (EncodedAttrs & 0xffff)); } - diff --git a/test/Transforms/FunctionAttrs/atomic.ll b/test/Transforms/FunctionAttrs/atomic.ll index 7c2bff7a05..df916e265c 100644 --- a/test/Transforms/FunctionAttrs/atomic.ll +++ b/test/Transforms/FunctionAttrs/atomic.ll @@ -3,7 +3,7 @@ ; Atomic load/store to local doesn't affect whether a function is ; readnone/readonly. define i32 @test1(i32 %x) uwtable ssp { -; CHECK: define i32 @test1(i32 %x) uwtable readnone ssp { +; CHECK: define i32 @test1(i32 %x) readnone ssp uwtable { entry: %x.addr = alloca i32, align 4 store atomic i32 %x, i32* %x.addr seq_cst, align 4 @@ -13,7 +13,7 @@ entry: ; A function with an Acquire load is not readonly. define i32 @test2(i32* %x) uwtable ssp { -; CHECK: define i32 @test2(i32* nocapture %x) uwtable ssp { +; CHECK: define i32 @test2(i32* nocapture %x) ssp uwtable { entry: %r = load atomic i32* %x seq_cst, align 4 ret i32 %r diff --git a/test/Transforms/Inline/inline_ssp.ll b/test/Transforms/Inline/inline_ssp.ll index d9996b30aa..ff0d5ce891 100644 --- a/test/Transforms/Inline/inline_ssp.ll +++ b/test/Transforms/Inline/inline_ssp.ll @@ -39,35 +39,35 @@ entry: define void @inline_req_req() nounwind uwtable sspreq { entry: -; CHECK: @inline_req_req() nounwind uwtable sspreq +; CHECK: @inline_req_req() nounwind sspreq uwtable call void @fun_sspreq() ret void } define void @inline_req_strong() nounwind uwtable sspstrong { entry: -; CHECK: @inline_req_strong() nounwind uwtable sspreq +; CHECK: @inline_req_strong() nounwind sspreq uwtable call void @fun_sspreq() ret void } define void @inline_req_ssp() nounwind uwtable ssp { entry: -; CHECK: @inline_req_ssp() nounwind uwtable sspreq +; CHECK: @inline_req_ssp() nounwind sspreq uwtable call void @fun_sspreq() ret void } define void @inline_req_nossp() nounwind uwtable { entry: -; CHECK: @inline_req_nossp() nounwind uwtable sspreq +; CHECK: @inline_req_nossp() nounwind sspreq uwtable call void @fun_sspreq() ret void } define void @inline_strong_req() nounwind uwtable sspreq { entry: -; CHECK: @inline_strong_req() nounwind uwtable sspreq +; CHECK: @inline_strong_req() nounwind sspreq uwtable call void @fun_sspstrong() ret void } @@ -96,7 +96,7 @@ entry: define void @inline_ssp_req() nounwind uwtable sspreq { entry: -; CHECK: @inline_ssp_req() nounwind uwtable sspreq +; CHECK: @inline_ssp_req() nounwind sspreq uwtable call void @fun_ssp() ret void } @@ -111,21 +111,21 @@ entry: define void @inline_ssp_ssp() nounwind uwtable ssp { entry: -; CHECK: @inline_ssp_ssp() nounwind uwtable ssp +; CHECK: @inline_ssp_ssp() nounwind ssp uwtable call void @fun_ssp() ret void } define void @inline_ssp_nossp() nounwind uwtable { entry: -; CHECK: @inline_ssp_nossp() nounwind uwtable ssp +; CHECK: @inline_ssp_nossp() nounwind ssp uwtable call void @fun_ssp() ret void } define void @inline_nossp_req() nounwind uwtable sspreq { entry: -; CHECK: @inline_nossp_req() nounwind uwtable sspreq +; CHECK: @inline_nossp_req() nounwind sspreq uwtable call void @fun_nossp() ret void } @@ -140,7 +140,7 @@ entry: define void @inline_nossp_ssp() nounwind uwtable ssp { entry: -; CHECK: @inline_nossp_ssp() nounwind uwtable ssp +; CHECK: @inline_nossp_ssp() nounwind ssp uwtable call void @fun_nossp() ret void } |