Make the AttrListPtr object a part of the LLVMContext.

When code deletes the context, the AttributeImpls that the AttrListPtr points to
are now invalid. Therefore, instead of keeping a separate managed static for the
AttrListPtrs that's reference counted, move it into the LLVMContext and delete
it when deleting the AttributeImpls.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168354 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Bill Wendling
2012-11-20 05:09:20 +00:00
parent 9eecb35d6b
commit 0976e00fd1
12 changed files with 103 additions and 125 deletions

View File

@ -312,21 +312,26 @@ public:
FunctionIndex = ~0U FunctionIndex = ~0U
}; };
private: private:
/// AttrList - The attributes that we are managing. This can be null to /// @brief The attributes that we are managing. This can be null to represent
/// represent the empty attributes list. /// the empty attributes list.
AttributeListImpl *AttrList; AttributeListImpl *AttrList;
/// @brief The attributes for the specified index are returned. Attributes
/// for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
explicit AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {}
public: public:
AttrListPtr() : AttrList(0) {} AttrListPtr() : AttrList(0) {}
AttrListPtr(const AttrListPtr &P); AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {}
const AttrListPtr &operator=(const AttrListPtr &RHS); const AttrListPtr &operator=(const AttrListPtr &RHS);
~AttrListPtr();
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Attribute List Construction and Mutation // Attribute List Construction and Mutation
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
/// get - Return a Attributes list with the specified parameters in it. /// get - Return a Attributes list with the specified parameters in it.
static AttrListPtr get(ArrayRef<AttributeWithIndex> Attrs); static AttrListPtr get(LLVMContext &C, ArrayRef<AttributeWithIndex> Attrs);
/// addAttr - Add the specified attribute at the specified index to this /// addAttr - Add the specified attribute at the specified index to this
/// attribute list. Since attribute lists are immutable, this /// attribute list. Since attribute lists are immutable, this
@ -413,13 +418,6 @@ public:
const AttributeWithIndex &getSlot(unsigned Slot) const; const AttributeWithIndex &getSlot(unsigned Slot) const;
void dump() const; void dump() const;
private:
explicit AttrListPtr(AttributeListImpl *L);
/// getAttributes - The attributes for the specified index are
/// returned. Attributes for the result are denoted with Idx = 0.
Attributes getAttributes(unsigned Idx) const;
}; };
} // End llvm namespace } // End llvm namespace

View File

@ -2793,7 +2793,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) {
Attributes::get(RetType->getContext(), Attributes::get(RetType->getContext(),
FuncAttrs))); FuncAttrs)));
AttrListPtr PAL = AttrListPtr::get(Attrs); AttrListPtr PAL = AttrListPtr::get(Context, Attrs);
if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) && if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) &&
!RetType->isVoidTy()) !RetType->isVoidTy())
@ -3350,7 +3350,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) {
FnAttrs))); FnAttrs)));
// Finish off the Attributes and check them // Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs); AttrListPtr PAL = AttrListPtr::get(Context, Attrs);
InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args);
II->setCallingConv(CC); II->setCallingConv(CC);
@ -3752,7 +3752,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS,
FnAttrs))); FnAttrs)));
// Finish off the Attributes and check them // Finish off the Attributes and check them
AttrListPtr PAL = AttrListPtr::get(Attrs); AttrListPtr PAL = AttrListPtr::get(Context, Attrs);
CallInst *CI = CallInst::Create(Callee, Args); CallInst *CI = CallInst::Create(Callee, Args);
CI->setTailCall(isTail); CI->setTailCall(isTail);

View File

@ -487,7 +487,7 @@ bool BitcodeReader::ParseAttributeBlock() {
Attributes::get(Context, B))); Attributes::get(Context, B)));
} }
MAttributes.push_back(AttrListPtr::get(Attrs)); MAttributes.push_back(AttrListPtr::get(Context, Attrs));
Attrs.clear(); Attrs.clear();
break; break;
} }

View File

@ -611,7 +611,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
// Recompute the parameter attributes list based on the new arguments for // Recompute the parameter attributes list based on the new arguments for
// the function. // the function.
NF->setAttributes(AttrListPtr::get(AttributesVec)); NF->setAttributes(AttrListPtr::get(F->getContext(), AttributesVec));
AttributesVec.clear(); AttributesVec.clear();
F->getParent()->getFunctionList().insert(F, NF); F->getParent()->getFunctionList().insert(F, NF);
@ -731,11 +731,13 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F,
New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(),
Args, "", Call); Args, "", Call);
cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv()); cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
cast<InvokeInst>(New)->setAttributes(AttrListPtr::get(AttributesVec)); cast<InvokeInst>(New)->setAttributes(AttrListPtr::get(II->getContext(),
AttributesVec));
} else { } else {
New = CallInst::Create(NF, Args, "", Call); New = CallInst::Create(NF, Args, "", Call);
cast<CallInst>(New)->setCallingConv(CS.getCallingConv()); cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
cast<CallInst>(New)->setAttributes(AttrListPtr::get(AttributesVec)); cast<CallInst>(New)->setAttributes(AttrListPtr::get(New->getContext(),
AttributesVec));
if (cast<CallInst>(Call)->isTailCall()) if (cast<CallInst>(Call)->isTailCall())
cast<CallInst>(New)->setTailCall(); cast<CallInst>(New)->setTailCall();
} }

View File

@ -280,7 +280,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) {
if (FnAttrs.hasAttributes()) if (FnAttrs.hasAttributes())
AttributesVec.push_back(AttributeWithIndex::get(AttrListPtr::FunctionIndex, AttributesVec.push_back(AttributeWithIndex::get(AttrListPtr::FunctionIndex,
FnAttrs)); FnAttrs));
PAL = AttrListPtr::get(AttributesVec); PAL = AttrListPtr::get(Fn.getContext(), AttributesVec);
} }
Instruction *New; Instruction *New;
@ -806,7 +806,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
FnAttrs)); FnAttrs));
// Reconstruct the AttributesList based on the vector we constructed. // Reconstruct the AttributesList based on the vector we constructed.
AttrListPtr NewPAL = AttrListPtr::get(AttributesVec); AttrListPtr NewPAL = AttrListPtr::get(F->getContext(), AttributesVec);
// Create the new function type based on the recomputed parameters. // Create the new function type based on the recomputed parameters.
FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg()); FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg());
@ -874,7 +874,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) {
FnAttrs)); FnAttrs));
// Reconstruct the AttributesList based on the vector we constructed. // Reconstruct the AttributesList based on the vector we constructed.
AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec); AttrListPtr NewCallPAL = AttrListPtr::get(F->getContext(), AttributesVec);
Instruction *New; Instruction *New;
if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) { if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {

View File

@ -1177,7 +1177,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
if (NewRetTy->isVoidTy()) if (NewRetTy->isVoidTy())
Caller->setName(""); // Void type should not have a name. Caller->setName(""); // Void type should not have a name.
const AttrListPtr &NewCallerPAL = AttrListPtr::get(attrVec); const AttrListPtr &NewCallerPAL = AttrListPtr::get(Callee->getContext(),
attrVec);
Instruction *NC; Instruction *NC;
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) { if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {
@ -1355,7 +1356,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS,
NestF->getType() == PointerType::getUnqual(NewFTy) ? NestF->getType() == PointerType::getUnqual(NewFTy) ?
NestF : ConstantExpr::getBitCast(NestF, NestF : ConstantExpr::getBitCast(NestF,
PointerType::getUnqual(NewFTy)); PointerType::getUnqual(NewFTy));
const AttrListPtr &NewPAL = AttrListPtr::get(NewAttrs); const AttrListPtr &NewPAL = AttrListPtr::get(FTy->getContext(), NewAttrs);
Instruction *NewCaller; Instruction *NewCaller;
if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) { if (InvokeInst *II = dyn_cast<InvokeInst>(Caller)) {

View File

@ -47,7 +47,9 @@ Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD,
ArrayRef<Attributes::AttrVal>(AVs, 2)); ArrayRef<Attributes::AttrVal>(AVs, 2));
LLVMContext &Context = B.GetInsertBlock()->getContext(); LLVMContext &Context = B.GetInsertBlock()->getContext();
Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI), Constant *StrLen = M->getOrInsertFunction("strlen",
AttrListPtr::get(M->getContext(),
AWI),
TD->getIntPtrType(Context), TD->getIntPtrType(Context),
B.getInt8PtrTy(), B.getInt8PtrTy(),
NULL); NULL);
@ -74,7 +76,9 @@ Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B,
ArrayRef<Attributes::AttrVal>(AVs, 2)); ArrayRef<Attributes::AttrVal>(AVs, 2));
LLVMContext &Context = B.GetInsertBlock()->getContext(); LLVMContext &Context = B.GetInsertBlock()->getContext();
Constant *StrNLen = M->getOrInsertFunction("strnlen", AttrListPtr::get(AWI), Constant *StrNLen = M->getOrInsertFunction("strnlen",
AttrListPtr::get(M->getContext(),
AWI),
TD->getIntPtrType(Context), TD->getIntPtrType(Context),
B.getInt8PtrTy(), B.getInt8PtrTy(),
TD->getIntPtrType(Context), TD->getIntPtrType(Context),
@ -102,7 +106,9 @@ Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B,
Type *I8Ptr = B.getInt8PtrTy(); Type *I8Ptr = B.getInt8PtrTy();
Type *I32Ty = B.getInt32Ty(); Type *I32Ty = B.getInt32Ty();
Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(AWI), Constant *StrChr = M->getOrInsertFunction("strchr",
AttrListPtr::get(M->getContext(),
AWI),
I8Ptr, I8Ptr, I32Ty, NULL); I8Ptr, I8Ptr, I32Ty, NULL);
CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B),
ConstantInt::get(I32Ty, C), "strchr"); ConstantInt::get(I32Ty, C), "strchr");
@ -127,7 +133,9 @@ Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len,
ArrayRef<Attributes::AttrVal>(AVs, 2)); ArrayRef<Attributes::AttrVal>(AVs, 2));
LLVMContext &Context = B.GetInsertBlock()->getContext(); LLVMContext &Context = B.GetInsertBlock()->getContext();
Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI), Value *StrNCmp = M->getOrInsertFunction("strncmp",
AttrListPtr::get(M->getContext(),
AWI),
B.getInt32Ty(), B.getInt32Ty(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
@ -155,7 +163,8 @@ Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B,
AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
Attributes::NoUnwind); Attributes::NoUnwind);
Type *I8Ptr = B.getInt8PtrTy(); Type *I8Ptr = B.getInt8PtrTy();
Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI), Value *StrCpy = M->getOrInsertFunction(Name,
AttrListPtr::get(M->getContext(), AWI),
I8Ptr, I8Ptr, I8Ptr, NULL); I8Ptr, I8Ptr, I8Ptr, NULL);
CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
Name); Name);
@ -178,7 +187,9 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len,
AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
Attributes::NoUnwind); Attributes::NoUnwind);
Type *I8Ptr = B.getInt8PtrTy(); Type *I8Ptr = B.getInt8PtrTy();
Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI), Value *StrNCpy = M->getOrInsertFunction(Name,
AttrListPtr::get(M->getContext(),
AWI),
I8Ptr, I8Ptr, I8Ptr, I8Ptr, I8Ptr, I8Ptr,
Len->getType(), NULL); Len->getType(), NULL);
CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B), CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B),
@ -203,7 +214,7 @@ Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize,
Attributes::NoUnwind); Attributes::NoUnwind);
LLVMContext &Context = B.GetInsertBlock()->getContext(); LLVMContext &Context = B.GetInsertBlock()->getContext();
Value *MemCpy = M->getOrInsertFunction("__memcpy_chk", Value *MemCpy = M->getOrInsertFunction("__memcpy_chk",
AttrListPtr::get(AWI), AttrListPtr::get(M->getContext(), AWI),
B.getInt8PtrTy(), B.getInt8PtrTy(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
@ -231,7 +242,8 @@ Value *llvm::EmitMemChr(Value *Ptr, Value *Val,
AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
ArrayRef<Attributes::AttrVal>(AVs, 2)); ArrayRef<Attributes::AttrVal>(AVs, 2));
LLVMContext &Context = B.GetInsertBlock()->getContext(); LLVMContext &Context = B.GetInsertBlock()->getContext();
Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI), Value *MemChr = M->getOrInsertFunction("memchr",
AttrListPtr::get(M->getContext(), AWI),
B.getInt8PtrTy(), B.getInt8PtrTy(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
B.getInt32Ty(), B.getInt32Ty(),
@ -261,7 +273,8 @@ Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2,
ArrayRef<Attributes::AttrVal>(AVs, 2)); ArrayRef<Attributes::AttrVal>(AVs, 2));
LLVMContext &Context = B.GetInsertBlock()->getContext(); LLVMContext &Context = B.GetInsertBlock()->getContext();
Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI), Value *MemCmp = M->getOrInsertFunction("memcmp",
AttrListPtr::get(M->getContext(), AWI),
B.getInt32Ty(), B.getInt32Ty(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
@ -338,7 +351,8 @@ Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD,
AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex,
Attributes::NoUnwind); Attributes::NoUnwind);
Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI), Value *PutS = M->getOrInsertFunction("puts",
AttrListPtr::get(M->getContext(), AWI),
B.getInt32Ty(), B.getInt32Ty(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
NULL); NULL);
@ -362,7 +376,8 @@ Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B,
Attributes::NoUnwind); Attributes::NoUnwind);
Constant *F; Constant *F;
if (File->getType()->isPointerTy()) if (File->getType()->isPointerTy())
F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI), F = M->getOrInsertFunction("fputc",
AttrListPtr::get(M->getContext(), AWI),
B.getInt32Ty(), B.getInt32Ty(),
B.getInt32Ty(), File->getType(), B.getInt32Ty(), File->getType(),
NULL); NULL);
@ -396,7 +411,8 @@ Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B,
StringRef FPutsName = TLI->getName(LibFunc::fputs); StringRef FPutsName = TLI->getName(LibFunc::fputs);
Constant *F; Constant *F;
if (File->getType()->isPointerTy()) if (File->getType()->isPointerTy())
F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI), F = M->getOrInsertFunction(FPutsName,
AttrListPtr::get(M->getContext(), AWI),
B.getInt32Ty(), B.getInt32Ty(),
B.getInt8PtrTy(), B.getInt8PtrTy(),
File->getType(), NULL); File->getType(), NULL);
@ -429,7 +445,8 @@ Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File,
StringRef FWriteName = TLI->getName(LibFunc::fwrite); StringRef FWriteName = TLI->getName(LibFunc::fwrite);
Constant *F; Constant *F;
if (File->getType()->isPointerTy()) if (File->getType()->isPointerTy())
F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI), F = M->getOrInsertFunction(FWriteName,
AttrListPtr::get(M->getContext(), AWI),
TD->getIntPtrType(Context), TD->getIntPtrType(Context),
B.getInt8PtrTy(), B.getInt8PtrTy(),
TD->getIntPtrType(Context), TD->getIntPtrType(Context),

View File

@ -355,62 +355,8 @@ uint64_t AttributesImpl::getStackAlignment() const {
// AttributeListImpl Definition // AttributeListImpl Definition
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
namespace llvm { AttrListPtr AttrListPtr::get(LLVMContext &C,
class AttributeListImpl; ArrayRef<AttributeWithIndex> Attrs) {
}
static ManagedStatic<FoldingSet<AttributeListImpl> > AttributesLists;
namespace llvm {
static ManagedStatic<sys::SmartMutex<true> > ALMutex;
class AttributeListImpl : public FoldingSetNode {
sys::cas_flag RefCount;
// AttributesList is uniqued, these should not be publicly available.
void operator=(const AttributeListImpl &) LLVM_DELETED_FUNCTION;
AttributeListImpl(const AttributeListImpl &) LLVM_DELETED_FUNCTION;
~AttributeListImpl(); // Private implementation
public:
SmallVector<AttributeWithIndex, 4> Attrs;
AttributeListImpl(ArrayRef<AttributeWithIndex> attrs)
: Attrs(attrs.begin(), attrs.end()) {
RefCount = 0;
}
void AddRef() {
sys::SmartScopedLock<true> Lock(*ALMutex);
++RefCount;
}
void DropRef() {
sys::SmartScopedLock<true> Lock(*ALMutex);
if (!AttributesLists.isConstructed())
return;
sys::cas_flag new_val = --RefCount;
if (new_val == 0)
delete this;
}
void Profile(FoldingSetNodeID &ID) const {
Profile(ID, Attrs);
}
static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeWithIndex> Attrs){
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
ID.AddInteger(Attrs[i].Attrs.Raw());
ID.AddInteger(Attrs[i].Index);
}
}
};
} // end llvm namespace
AttributeListImpl::~AttributeListImpl() {
// NOTE: Lock must be acquired by caller.
AttributesLists->RemoveNode(this);
}
AttrListPtr AttrListPtr::get(ArrayRef<AttributeWithIndex> Attrs) {
// If there are no attributes then return a null AttributesList pointer. // If there are no attributes then return a null AttributesList pointer.
if (Attrs.empty()) if (Attrs.empty())
return AttrListPtr(); return AttrListPtr();
@ -425,49 +371,34 @@ AttrListPtr AttrListPtr::get(ArrayRef<AttributeWithIndex> Attrs) {
#endif #endif
// Otherwise, build a key to look up the existing attributes. // Otherwise, build a key to look up the existing attributes.
LLVMContextImpl *pImpl = C.pImpl;
FoldingSetNodeID ID; FoldingSetNodeID ID;
AttributeListImpl::Profile(ID, Attrs); AttributeListImpl::Profile(ID, Attrs);
void *InsertPos;
sys::SmartScopedLock<true> Lock(*ALMutex); void *InsertPoint;
AttributeListImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID,
AttributeListImpl *PAL = InsertPoint);
AttributesLists->FindNodeOrInsertPos(ID, InsertPos);
// If we didn't find any existing attributes of the same shape then // If we didn't find any existing attributes of the same shape then
// create a new one and insert it. // create a new one and insert it.
if (!PAL) { if (!PA) {
PAL = new AttributeListImpl(Attrs); PA = new AttributeListImpl(Attrs);
AttributesLists->InsertNode(PAL, InsertPos); pImpl->AttrsLists.InsertNode(PA, InsertPoint);
} }
// Return the AttributesList that we found or created. // Return the AttributesList that we found or created.
return AttrListPtr(PAL); return AttrListPtr(PA);
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// AttrListPtr Method Implementations // AttrListPtr Method Implementations
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
AttrListPtr::AttrListPtr(AttributeListImpl *LI) : AttrList(LI) {
if (LI) LI->AddRef();
}
AttrListPtr::AttrListPtr(const AttrListPtr &P) : AttrList(P.AttrList) {
if (AttrList) AttrList->AddRef();
}
const AttrListPtr &AttrListPtr::operator=(const AttrListPtr &RHS) { const AttrListPtr &AttrListPtr::operator=(const AttrListPtr &RHS) {
sys::SmartScopedLock<true> Lock(*ALMutex);
if (AttrList == RHS.AttrList) return *this; if (AttrList == RHS.AttrList) return *this;
if (AttrList) AttrList->DropRef();
AttrList = RHS.AttrList;
if (AttrList) AttrList->AddRef();
return *this;
}
AttrListPtr::~AttrListPtr() { AttrList = RHS.AttrList;
if (AttrList) AttrList->DropRef(); return *this;
} }
/// getNumSlots - Return the number of slots used in this attribute list. /// getNumSlots - Return the number of slots used in this attribute list.
@ -507,6 +438,7 @@ bool AttrListPtr::hasAttrSomewhere(Attributes::AttrVal Attr) const {
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) for (unsigned i = 0, e = Attrs.size(); i != e; ++i)
if (Attrs[i].Attrs.hasAttribute(Attr)) if (Attrs[i].Attrs.hasAttribute(Attr))
return true; return true;
return false; return false;
} }
@ -562,7 +494,7 @@ AttrListPtr AttrListPtr::addAttr(LLVMContext &C, unsigned Idx,
OldAttrList.begin()+i, OldAttrList.end()); OldAttrList.begin()+i, OldAttrList.end());
} }
return get(NewAttrList); return get(C, NewAttrList);
} }
AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx, AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx,
@ -601,7 +533,7 @@ AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx,
NewAttrList.insert(NewAttrList.end(), NewAttrList.insert(NewAttrList.end(),
OldAttrList.begin()+i, OldAttrList.end()); OldAttrList.begin()+i, OldAttrList.end());
return get(NewAttrList); return get(C, NewAttrList);
} }
void AttrListPtr::dump() const { void AttrListPtr::dump() const {

View File

@ -15,12 +15,11 @@
#ifndef LLVM_ATTRIBUTESIMPL_H #ifndef LLVM_ATTRIBUTESIMPL_H
#define LLVM_ATTRIBUTESIMPL_H #define LLVM_ATTRIBUTESIMPL_H
#include "llvm/Attributes.h"
#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/FoldingSet.h"
namespace llvm { namespace llvm {
class Attributes;
class AttributesImpl : public FoldingSetNode { class AttributesImpl : public FoldingSetNode {
uint64_t Bits; // FIXME: We will be expanding this. uint64_t Bits; // FIXME: We will be expanding this.
public: public:
@ -46,6 +45,27 @@ public:
} }
}; };
class AttributeListImpl : public FoldingSetNode {
// AttributesList is uniqued, these should not be publicly available.
void operator=(const AttributeListImpl &) LLVM_DELETED_FUNCTION;
AttributeListImpl(const AttributeListImpl &) LLVM_DELETED_FUNCTION;
public:
SmallVector<AttributeWithIndex, 4> Attrs;
AttributeListImpl(ArrayRef<AttributeWithIndex> attrs)
: Attrs(attrs.begin(), attrs.end()) {}
void Profile(FoldingSetNodeID &ID) const {
Profile(ID, Attrs);
}
static void Profile(FoldingSetNodeID &ID, ArrayRef<AttributeWithIndex> Attrs){
for (unsigned i = 0, e = Attrs.size(); i != e; ++i) {
ID.AddInteger(Attrs[i].Attrs.Raw());
ID.AddInteger(Attrs[i].Index);
}
}
};
} // end llvm namespace } // end llvm namespace
#endif #endif

View File

@ -97,11 +97,18 @@ LLVMContextImpl::~LLVMContextImpl() {
// Destroy attributes. // Destroy attributes.
for (FoldingSetIterator<AttributesImpl> I = AttrsSet.begin(), for (FoldingSetIterator<AttributesImpl> I = AttrsSet.begin(),
E = AttrsSet.end(); I != E;) { E = AttrsSet.end(); I != E; ) {
FoldingSetIterator<AttributesImpl> Elem = I++; FoldingSetIterator<AttributesImpl> Elem = I++;
delete &*Elem; delete &*Elem;
} }
// Destroy attribute lists.
for (FoldingSetIterator<AttributeListImpl> I = AttrsLists.begin(),
E = AttrsLists.end(); I != E; ) {
FoldingSetIterator<AttributeListImpl> Elem = I++;
delete &*Elem;
}
// Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet
// and the NonUniquedMDNodes sets, so copy the values out first. // and the NonUniquedMDNodes sets, so copy the values out first.
SmallVector<MDNode*, 8> MDNodes; SmallVector<MDNode*, 8> MDNodes;

View File

@ -256,7 +256,8 @@ public:
FPMapTy FPConstants; FPMapTy FPConstants;
FoldingSet<AttributesImpl> AttrsSet; FoldingSet<AttributesImpl> AttrsSet;
FoldingSet<AttributeListImpl> AttrsLists;
StringMap<Value*> MDStringCache; StringMap<Value*> MDStringCache;
FoldingSet<MDNode> MDNodeSet; FoldingSet<MDNode> MDNodeSet;

View File

@ -621,7 +621,7 @@ EmitAttributes(const std::vector<CodeGenIntrinsic> &Ints, raw_ostream &OS) {
OS << " }\n"; OS << " }\n";
OS << " }\n"; OS << " }\n";
OS << " return AttrListPtr::get(ArrayRef<AttributeWithIndex>(AWI, " OS << " return AttrListPtr::get(C, ArrayRef<AttributeWithIndex>(AWI, "
"NumAttrs));\n"; "NumAttrs));\n";
OS << "}\n"; OS << "}\n";
OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n"; OS << "#endif // GET_INTRINSIC_ATTRIBUTES\n\n";