From 169d5270751597aed4095ead00401a3374906147 Mon Sep 17 00:00:00 2001 From: Bill Wendling Date: Thu, 31 Jan 2013 23:16:25 +0000 Subject: [PATCH] Remove the AttrBuilder form of the Attribute::get creators. The AttrBuilder is for building a collection of attributes. The Attribute object holds only one attribute. So it's not really useful for the Attribute object to have a creator which takes an AttrBuilder. This has two fallouts: 1. The AttrBuilder no longer holds its internal attributes in a bit-mask form. 2. The attributes are now ordered alphabetically (hence why the tests have changed). git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@174110 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/IR/Attributes.h | 5 +- lib/IR/AttributeImpl.h | 2 + lib/IR/Attributes.cpp | 70 ++++++++++++++-------------- test/Transforms/Inline/inline_ssp.ll | 38 +++++++-------- test/Transforms/MemCpyOpt/memcpy.ll | 20 ++++---- 5 files changed, 69 insertions(+), 66 deletions(-) diff --git a/include/llvm/IR/Attributes.h b/include/llvm/IR/Attributes.h index 3950d932201..d5da1c0a2e9 100644 --- a/include/llvm/IR/Attributes.h +++ b/include/llvm/IR/Attributes.h @@ -105,8 +105,6 @@ public: private: AttributeImpl *pImpl; Attribute(AttributeImpl *A) : pImpl(A) {} - - static Attribute get(LLVMContext &Context, AttrBuilder &B); public: Attribute() : pImpl(0) {} @@ -115,7 +113,8 @@ public: //===--------------------------------------------------------------------===// /// \brief Return a uniquified Attribute object. - static Attribute get(LLVMContext &Context, AttrKind Kind); + static Attribute get(LLVMContext &Context, AttrKind Kind, Constant *Val = 0); + static Attribute get(LLVMContext &Context, Constant *Kind, Constant *Val = 0); /// \brief Return a uniquified Attribute object that has the specific /// alignment set. diff --git a/lib/IR/AttributeImpl.h b/lib/IR/AttributeImpl.h index 442860d31b2..e9525785a20 100644 --- a/lib/IR/AttributeImpl.h +++ b/lib/IR/AttributeImpl.h @@ -40,6 +40,8 @@ class AttributeImpl : public FoldingSetNode { public: AttributeImpl(LLVMContext &C, Constant *Kind) : Context(C), Kind(Kind) {} + AttributeImpl(LLVMContext &C, Constant *Kind, ArrayRef Vals) + : Context(C), Kind(Kind), Vals(Vals.begin(), Vals.end()) {} explicit AttributeImpl(LLVMContext &C, Attribute::AttrKind data); AttributeImpl(LLVMContext &C, Attribute::AttrKind data, ArrayRef values); diff --git a/lib/IR/Attributes.cpp b/lib/IR/Attributes.cpp index 5608cbd47fa..c2ea2b29eb6 100644 --- a/lib/IR/Attributes.cpp +++ b/lib/IR/Attributes.cpp @@ -30,24 +30,11 @@ using namespace llvm; // Attribute Construction Methods //===----------------------------------------------------------------------===// -Attribute Attribute::get(LLVMContext &Context, AttrKind Kind) { - AttrBuilder B; - return Attribute::get(Context, B.addAttribute(Kind)); -} - -Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { - // If there are no attributes, return an empty Attribute class. - if (!B.hasAttributes()) - return Attribute(); - - assert(std::distance(B.begin(), B.end()) == 1 && - "The Attribute object should represent one attribute only!"); - - // Otherwise, build a key to look up the existing attributes. +Attribute Attribute::get(LLVMContext &Context, Constant *Kind, Constant *Val) { LLVMContextImpl *pImpl = Context.pImpl; FoldingSetNodeID ID; - ConstantInt *CI = ConstantInt::get(Type::getInt64Ty(Context), B.Raw()); - ID.AddPointer(CI); + ID.AddPointer(Kind); + if (Val) ID.AddPointer(Val); void *InsertPoint; AttributeImpl *PA = pImpl->AttrsSet.FindNodeOrInsertPos(ID, InsertPoint); @@ -55,7 +42,9 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { if (!PA) { // If we didn't find any existing attributes of the same shape then create a // new one and insert it. - PA = new AttributeImpl(Context, CI); + PA = (!Val) ? + new AttributeImpl(Context, Kind) : + new AttributeImpl(Context, Kind, Val); pImpl->AttrsSet.InsertNode(PA, InsertPoint); } @@ -63,15 +52,24 @@ Attribute Attribute::get(LLVMContext &Context, AttrBuilder &B) { return Attribute(PA); } +Attribute Attribute::get(LLVMContext &Context, AttrKind Kind, Constant *Val) { + ConstantInt *KindVal = ConstantInt::get(Type::getInt64Ty(Context), Kind); + return get(Context, KindVal, Val); +} + Attribute Attribute::getWithAlignment(LLVMContext &Context, uint64_t Align) { - AttrBuilder B; - return get(Context, B.addAlignmentAttr(Align)); + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); + assert(Align <= 0x40000000 && "Alignment too large."); + return get(Context, Alignment, + ConstantInt::get(Type::getInt64Ty(Context), Align)); } Attribute Attribute::getWithStackAlignment(LLVMContext &Context, uint64_t Align) { - AttrBuilder B; - return get(Context, B.addStackAlignmentAttr(Align)); + assert(isPowerOf2_32(Align) && "Alignment must be a power of two."); + assert(Align <= 0x100 && "Alignment too large."); + return get(Context, StackAlignment, + ConstantInt::get(Type::getInt64Ty(Context), Align)); } //===----------------------------------------------------------------------===// @@ -250,17 +248,21 @@ AttributeImpl::AttributeImpl(LLVMContext &C, StringRef kind) } bool AttributeImpl::hasAttribute(Attribute::AttrKind A) const { - return (Raw() & getAttrMask(A)) != 0; + if (ConstantInt *CI = dyn_cast(Kind)) + return CI->getZExtValue() == A; + return false; } uint64_t AttributeImpl::getAlignment() const { - uint64_t Mask = Raw() & getAttrMask(Attribute::Alignment); - return 1ULL << ((Mask >> 16) - 1); + assert(hasAttribute(Attribute::Alignment) && + "Trying to retrieve the alignment from a non-alignment attr!"); + return cast(Vals[0])->getZExtValue(); } uint64_t AttributeImpl::getStackAlignment() const { - uint64_t Mask = Raw() & getAttrMask(Attribute::StackAlignment); - return 1ULL << ((Mask >> 26) - 1); + assert(hasAttribute(Attribute::StackAlignment) && + "Trying to retrieve the stack alignment from a non-alignment attr!"); + return cast(Vals[0])->getZExtValue(); } bool AttributeImpl::operator==(Attribute::AttrKind kind) const { @@ -808,12 +810,15 @@ void AttrBuilder::clear() { } AttrBuilder &AttrBuilder::addAttribute(Attribute::AttrKind Val) { + assert(Val != Attribute::Alignment && Val != Attribute::StackAlignment && + "Adding alignment attribute without adding alignment value!"); Attrs.insert(Val); return *this; } AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { Attrs.erase(Val); + if (Val == Attribute::Alignment) Alignment = 0; else if (Val == Attribute::StackAlignment) @@ -823,16 +828,13 @@ AttrBuilder &AttrBuilder::removeAttribute(Attribute::AttrKind Val) { } AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) { - uint64_t Mask = Attr.Raw(); - - for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds; - I = Attribute::AttrKind(I + 1)) - if ((Mask & AttributeImpl::getAttrMask(I)) != 0) - Attrs.insert(I); + ConstantInt *Kind = cast(Attr.getAttributeKind()); + Attribute::AttrKind KindVal = Attribute::AttrKind(Kind->getZExtValue()); + Attrs.insert(KindVal); - if (Attr.getAlignment()) + if (KindVal == Attribute::Alignment) Alignment = Attr.getAlignment(); - if (Attr.getStackAlignment()) + else if (KindVal == Attribute::StackAlignment) StackAlignment = Attr.getStackAlignment(); return *this; } diff --git a/test/Transforms/Inline/inline_ssp.ll b/test/Transforms/Inline/inline_ssp.ll index ff0d5ce8917..e3835e0d945 100644 --- a/test/Transforms/Inline/inline_ssp.ll +++ b/test/Transforms/Inline/inline_ssp.ll @@ -11,19 +11,19 @@ ; propagated correctly. The caller should have its SSP attribute set as: ; strictest(caller-ssp-attr, callee-ssp-attr), where strictness is ordered as: ; sspreq > sspstrong > ssp > [no ssp] -define internal void @fun_sspreq() nounwind uwtable sspreq { +define internal void @fun_sspreq() nounwind sspreq uwtable { entry: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([12 x i8]* @.str3, i32 0, i32 0)) ret void } -define internal void @fun_sspstrong() nounwind uwtable sspstrong { +define internal void @fun_sspstrong() nounwind sspstrong uwtable { entry: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([15 x i8]* @.str2, i32 0, i32 0)) ret void } -define internal void @fun_ssp() nounwind uwtable ssp { +define internal void @fun_ssp() nounwind ssp uwtable { entry: %call = call i32 (i8*, ...)* @printf(i8* getelementptr inbounds ([9 x i8]* @.str1, i32 0, i32 0)) ret void @@ -37,21 +37,21 @@ entry: ; Tests start below -define void @inline_req_req() nounwind uwtable sspreq { +define void @inline_req_req() nounwind sspreq uwtable { entry: ; CHECK: @inline_req_req() nounwind sspreq uwtable call void @fun_sspreq() ret void } -define void @inline_req_strong() nounwind uwtable sspstrong { +define void @inline_req_strong() nounwind sspstrong uwtable { entry: ; CHECK: @inline_req_strong() nounwind sspreq uwtable call void @fun_sspreq() ret void } -define void @inline_req_ssp() nounwind uwtable ssp { +define void @inline_req_ssp() nounwind ssp uwtable { entry: ; CHECK: @inline_req_ssp() nounwind sspreq uwtable call void @fun_sspreq() @@ -65,7 +65,7 @@ entry: ret void } -define void @inline_strong_req() nounwind uwtable sspreq { +define void @inline_strong_req() nounwind sspreq uwtable { entry: ; CHECK: @inline_strong_req() nounwind sspreq uwtable call void @fun_sspstrong() @@ -73,28 +73,28 @@ entry: } -define void @inline_strong_strong() nounwind uwtable sspstrong { +define void @inline_strong_strong() nounwind sspstrong uwtable { entry: -; CHECK: @inline_strong_strong() nounwind uwtable sspstrong +; CHECK: @inline_strong_strong() nounwind sspstrong uwtable call void @fun_sspstrong() ret void } -define void @inline_strong_ssp() nounwind uwtable ssp { +define void @inline_strong_ssp() nounwind ssp uwtable { entry: -; CHECK: @inline_strong_ssp() nounwind uwtable sspstrong +; CHECK: @inline_strong_ssp() nounwind sspstrong uwtable call void @fun_sspstrong() ret void } define void @inline_strong_nossp() nounwind uwtable { entry: -; CHECK: @inline_strong_nossp() nounwind uwtable sspstrong +; CHECK: @inline_strong_nossp() nounwind sspstrong uwtable call void @fun_sspstrong() ret void } -define void @inline_ssp_req() nounwind uwtable sspreq { +define void @inline_ssp_req() nounwind sspreq uwtable { entry: ; CHECK: @inline_ssp_req() nounwind sspreq uwtable call void @fun_ssp() @@ -102,14 +102,14 @@ entry: } -define void @inline_ssp_strong() nounwind uwtable sspstrong { +define void @inline_ssp_strong() nounwind sspstrong uwtable { entry: -; CHECK: @inline_ssp_strong() nounwind uwtable sspstrong +; CHECK: @inline_ssp_strong() nounwind sspstrong uwtable call void @fun_ssp() ret void } -define void @inline_ssp_ssp() nounwind uwtable ssp { +define void @inline_ssp_ssp() nounwind ssp uwtable { entry: ; CHECK: @inline_ssp_ssp() nounwind ssp uwtable call void @fun_ssp() @@ -131,14 +131,14 @@ entry: } -define void @inline_nossp_strong() nounwind uwtable sspstrong { +define void @inline_nossp_strong() nounwind sspstrong uwtable { entry: -; CHECK: @inline_nossp_strong() nounwind uwtable sspstrong +; CHECK: @inline_nossp_strong() nounwind sspstrong uwtable call void @fun_nossp() ret void } -define void @inline_nossp_ssp() nounwind uwtable ssp { +define void @inline_nossp_ssp() nounwind ssp uwtable { entry: ; CHECK: @inline_nossp_ssp() nounwind ssp uwtable call void @fun_nossp() diff --git a/test/Transforms/MemCpyOpt/memcpy.ll b/test/Transforms/MemCpyOpt/memcpy.ll index 3fa16288c21..c19a93a776c 100644 --- a/test/Transforms/MemCpyOpt/memcpy.ll +++ b/test/Transforms/MemCpyOpt/memcpy.ll @@ -70,20 +70,20 @@ define void @test4(i8 *%P) { %A = alloca %1 %a = bitcast %1* %A to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* %a, i8* %P, i64 8, i32 4, i1 false) - call void @test4a(i8* byval align 1 %a) + call void @test4a(i8* align 1 byval %a) ret void ; CHECK: @test4 ; CHECK-NEXT: call void @test4a( } -declare void @test4a(i8* byval align 1) +declare void @test4a(i8* align 1 byval) declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind %struct.S = type { i128, [4 x i8]} @sS = external global %struct.S, align 16 -declare void @test5a(%struct.S* byval align 16) nounwind ssp +declare void @test5a(%struct.S* align 16 byval) nounwind ssp ; rdar://8713376 - This memcpy can't be eliminated. @@ -94,11 +94,11 @@ entry: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* bitcast (%struct.S* @sS to i8*), i64 32, i32 16, i1 false) %a = getelementptr %struct.S* %y, i64 0, i32 1, i64 0 store i8 4, i8* %a - call void @test5a(%struct.S* byval align 16 %y) + call void @test5a(%struct.S* align 16 byval %y) ret i32 0 ; CHECK: @test5( ; CHECK: store i8 4 - ; CHECK: call void @test5a(%struct.S* byval align 16 %y) + ; CHECK: call void @test5a(%struct.S* align 16 byval %y) } ;; Noop memcpy should be zapped. @@ -114,19 +114,19 @@ define void @test6(i8 *%P) { ; isn't itself 8 byte aligned. %struct.p = type { i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32 } -define i32 @test7(%struct.p* nocapture byval align 8 %q) nounwind ssp { +define i32 @test7(%struct.p* nocapture align 8 byval %q) nounwind ssp { entry: %agg.tmp = alloca %struct.p, align 4 %tmp = bitcast %struct.p* %agg.tmp to i8* %tmp1 = bitcast %struct.p* %q to i8* call void @llvm.memcpy.p0i8.p0i8.i64(i8* %tmp, i8* %tmp1, i64 48, i32 4, i1 false) - %call = call i32 @g(%struct.p* byval align 8 %agg.tmp) nounwind + %call = call i32 @g(%struct.p* align 8 byval %agg.tmp) nounwind ret i32 %call ; CHECK: @test7 -; CHECK: call i32 @g(%struct.p* byval align 8 %q) nounwind +; CHECK: call i32 @g(%struct.p* align 8 byval %q) nounwind } -declare i32 @g(%struct.p* byval align 8) +declare i32 @g(%struct.p* align 8 byval) declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i32, i1) nounwind @@ -152,7 +152,7 @@ declare noalias i8* @malloc(i32) ; rdar://11341081 %struct.big = type { [50 x i32] } -define void @test9() nounwind uwtable ssp { +define void @test9() nounwind ssp uwtable { entry: ; CHECK: test9 ; CHECK: f1 -- 2.34.1