From 00dace859e62c85379021f727c9aeade734f5154 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 16:40:23 +0000 Subject: Merging r168197: into 3.2 release branch Preserve address space of forward-referenced global variables in the LL parser Before, the parser would assert on the following code: @a2 = global i8 addrspace(1)* @a @a = addrspace(1) global i8 0 because the type of @a was "i8*" instead of "i8 addrspace(1)*" when parsing the initializer for @a2. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168435 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AsmParser/LLParser.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index ac803c5783..e8e6e27725 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -779,7 +779,9 @@ GlobalValue *LLParser::GetGlobalVal(const std::string &Name, Type *Ty, FwdVal = Function::Create(FT, GlobalValue::ExternalWeakLinkage, Name, M); else FwdVal = new GlobalVariable(*M, PTy->getElementType(), false, - GlobalValue::ExternalWeakLinkage, 0, Name); + GlobalValue::ExternalWeakLinkage, 0, Name, + 0, GlobalVariable::NotThreadLocal, + PTy->getAddressSpace()); ForwardRefVals[Name] = std::make_pair(FwdVal, Loc); return FwdVal; -- cgit v1.2.3 From 36915224aa459ce855d7ce56b36307d468ab44a8 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 18:28:32 +0000 Subject: Merging r168361, r168346 and r168227 into 3.2 branch release Merging r168361: Fix PR14132 and handle OOB loads speculated throuh PHI nodes. The issue is that we may end up with newly OOB loads when speculating a load into the predecessors of a PHI node, and this confuses the new integer splitting logic in some cases, triggering an assertion failure. In fact, the branch in question must be dead code as it loads from a too-narrow alloca. Add code to handle this gracefully and leave the requisite FIXMEs for both optimizing more aggressively and doing more to aid sanitizing invalid code which triggers these patterns. Merging r168346: ------------------------------------------------------------------------ Rework the rewriting of loads and stores for vector and integer allocas to properly handle the combinations of these with split integer loads and stores. This essentially replaces Evan's r168227 by refactoring the code in a different way, and trynig to mirror that refactoring in both the load and store sides of the rewriting. Generally speaking there was some really problematic duplicated code here that led to poorly founded assumptions and then subtle bugs. Now much of the code actually flows through and follows a more consistent style and logical path. There is still a tiny bit of duplication on the store side of things, but it is much less bad. This also changes the logic to never re-use a load or store instruction as that was simply too error prone in practice. I've added a few tests (one a reduction of the one in Evan's original patch, which happened to be the same as the report in PR14349). I'm going to look at adding a few more tests for things I found and fixed in passing (such as the volatile tests in the vectorizable predicate). This patch has survived bootstrap, and modulo one bugfix survived Duncan's test suite, but let me know if anything else explodes. Merging r168227: Teach SROA rewriteVectorizedStoreInst to handle cases when the loaded value is narrower than the stored value. rdar://12713675 git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168443 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/SROA.cpp | 282 +++++++++++++++++++---------------------- 1 file changed, 131 insertions(+), 151 deletions(-) (limited to 'lib') diff --git a/lib/Transforms/Scalar/SROA.cpp b/lib/Transforms/Scalar/SROA.cpp index d95c855ce7..ccc2f7a77b 100644 --- a/lib/Transforms/Scalar/SROA.cpp +++ b/lib/Transforms/Scalar/SROA.cpp @@ -568,6 +568,10 @@ private: // Clamp the end offset to the end of the allocation. Note that this is // formulated to handle even the case where "BeginOffset + Size" overflows. + // NOTE! This may appear superficially to be something we could ignore + // entirely, but that is not so! There may be PHI-node uses where some + // instructions are dead but not others. We can't completely ignore the + // PHI node, and so have to record at least the information here. assert(AllocSize >= BeginOffset); // Established above. if (Size > AllocSize - BeginOffset) { DEBUG(dbgs() << "WARNING: Clamping a " << Size << " byte use @" << Offset @@ -1382,11 +1386,7 @@ class SROA : public FunctionPass { /// \brief A collection of instructions to delete. /// We try to batch deletions to simplify code and make things a bit more /// efficient. - SmallVector DeadInsts; - - /// \brief A set to prevent repeatedly marking an instruction split into many - /// uses as dead. Only used to guard insertion into DeadInsts. - SmallPtrSet DeadSplitInsts; + SetVector > DeadInsts; /// \brief Post-promotion worklist. /// @@ -1573,7 +1573,7 @@ private: do { LoadInst *LI = Loads.pop_back_val(); LI->replaceAllUsesWith(NewPN); - Pass.DeadInsts.push_back(LI); + Pass.DeadInsts.insert(LI); } while (!Loads.empty()); // Inject loads into all of the pred blocks. @@ -1717,7 +1717,7 @@ private: DEBUG(dbgs() << " speculated to: " << *V << "\n"); LI->replaceAllUsesWith(V); - Pass.DeadInsts.push_back(LI); + Pass.DeadInsts.insert(LI); } } }; @@ -2134,8 +2134,13 @@ static bool isVectorPromotionViable(const DataLayout &TD, } else if (I->U->get()->getType()->getPointerElementType()->isStructTy()) { // Disable vector promotion when there are loads or stores of an FCA. return false; - } else if (!isa(I->U->getUser()) && - !isa(I->U->getUser())) { + } else if (LoadInst *LI = dyn_cast(I->U->getUser())) { + if (LI->isVolatile()) + return false; + } else if (StoreInst *SI = dyn_cast(I->U->getUser())) { + if (SI->isVolatile()) + return false; + } else { return false; } } @@ -2241,18 +2246,23 @@ static bool isIntegerWideningViable(const DataLayout &TD, static Value *extractInteger(const DataLayout &DL, IRBuilder<> &IRB, Value *V, IntegerType *Ty, uint64_t Offset, const Twine &Name) { + DEBUG(dbgs() << " start: " << *V << "\n"); IntegerType *IntTy = cast(V->getType()); assert(DL.getTypeStoreSize(Ty) + Offset <= DL.getTypeStoreSize(IntTy) && "Element extends past full value"); uint64_t ShAmt = 8*Offset; if (DL.isBigEndian()) ShAmt = 8*(DL.getTypeStoreSize(IntTy) - DL.getTypeStoreSize(Ty) - Offset); - if (ShAmt) + if (ShAmt) { V = IRB.CreateLShr(V, ShAmt, Name + ".shift"); + DEBUG(dbgs() << " shifted: " << *V << "\n"); + } assert(Ty->getBitWidth() <= IntTy->getBitWidth() && "Cannot extract to a larger integer!"); - if (Ty != IntTy) + if (Ty != IntTy) { V = IRB.CreateTrunc(V, Ty, Name + ".trunc"); + DEBUG(dbgs() << " trunced: " << *V << "\n"); + } return V; } @@ -2262,20 +2272,27 @@ static Value *insertInteger(const DataLayout &DL, IRBuilder<> &IRB, Value *Old, IntegerType *Ty = cast(V->getType()); assert(Ty->getBitWidth() <= IntTy->getBitWidth() && "Cannot insert a larger integer!"); - if (Ty != IntTy) + DEBUG(dbgs() << " start: " << *V << "\n"); + if (Ty != IntTy) { V = IRB.CreateZExt(V, IntTy, Name + ".ext"); + DEBUG(dbgs() << " extended: " << *V << "\n"); + } assert(DL.getTypeStoreSize(Ty) + Offset <= DL.getTypeStoreSize(IntTy) && "Element store outside of alloca store"); uint64_t ShAmt = 8*Offset; if (DL.isBigEndian()) ShAmt = 8*(DL.getTypeStoreSize(IntTy) - DL.getTypeStoreSize(Ty) - Offset); - if (ShAmt) + if (ShAmt) { V = IRB.CreateShl(V, ShAmt, Name + ".shift"); + DEBUG(dbgs() << " shifted: " << *V << "\n"); + } if (ShAmt || Ty->getBitWidth() < IntTy->getBitWidth()) { APInt Mask = ~Ty->getMask().zext(IntTy->getBitWidth()).shl(ShAmt); Old = IRB.CreateAnd(Old, Mask, Name + ".mask"); + DEBUG(dbgs() << " masked: " << *Old << "\n"); V = IRB.CreateOr(Old, V, Name + ".insert"); + DEBUG(dbgs() << " inserted: " << *V << "\n"); } return V; } @@ -2442,30 +2459,21 @@ private: void deleteIfTriviallyDead(Value *V) { Instruction *I = cast(V); if (isInstructionTriviallyDead(I)) - Pass.DeadInsts.push_back(I); + Pass.DeadInsts.insert(I); } - bool rewriteVectorizedLoadInst(IRBuilder<> &IRB, LoadInst &LI, Value *OldOp) { - Value *Result; + Value *rewriteVectorizedLoadInst(IRBuilder<> &IRB, LoadInst &LI, Value *OldOp) { + Value *V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), + getName(".load")); if (LI.getType() == VecTy->getElementType() || BeginOffset > NewAllocaBeginOffset || EndOffset < NewAllocaEndOffset) { - Result = IRB.CreateExtractElement( - IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), getName(".load")), - getIndex(IRB, BeginOffset), getName(".extract")); - } else { - Result = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), - getName(".load")); + V = IRB.CreateExtractElement(V, getIndex(IRB, BeginOffset), + getName(".extract")); } - if (Result->getType() != LI.getType()) - Result = convertValue(TD, IRB, Result, LI.getType()); - LI.replaceAllUsesWith(Result); - Pass.DeadInsts.push_back(&LI); - - DEBUG(dbgs() << " to: " << *Result << "\n"); - return true; + return V; } - bool rewriteIntegerLoad(IRBuilder<> &IRB, LoadInst &LI) { + Value *rewriteIntegerLoad(IRBuilder<> &IRB, LoadInst &LI) { assert(IntTy && "We cannot insert an integer to the alloca"); assert(!LI.isVolatile()); Value *V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), @@ -2473,12 +2481,10 @@ private: V = convertValue(TD, IRB, V, IntTy); assert(BeginOffset >= NewAllocaBeginOffset && "Out of bounds offset"); uint64_t Offset = BeginOffset - NewAllocaBeginOffset; - V = extractInteger(TD, IRB, V, cast(LI.getType()), Offset, - getName(".extract")); - LI.replaceAllUsesWith(V); - Pass.DeadInsts.push_back(&LI); - DEBUG(dbgs() << " to: " << *V << "\n"); - return true; + if (Offset > 0 || EndOffset < NewAllocaEndOffset) + V = extractInteger(TD, IRB, V, cast(LI.getType()), Offset, + getName(".extract")); + return V; } bool visitLoadInst(LoadInst &LI) { @@ -2488,7 +2494,46 @@ private: IRBuilder<> IRB(&LI); uint64_t Size = EndOffset - BeginOffset; - if (Size < TD.getTypeStoreSize(LI.getType())) { + bool IsSplitIntLoad = Size < TD.getTypeStoreSize(LI.getType()); + + // If this memory access can be shown to *statically* extend outside the + // bounds of the original allocation it's behavior is undefined. Rather + // than trying to transform it, just replace it with undef. + // FIXME: We should do something more clever for functions being + // instrumented by asan. + // FIXME: Eventually, once ASan and friends can flush out bugs here, this + // should be transformed to a load of null making it unreachable. + uint64_t OldAllocSize = TD.getTypeAllocSize(OldAI.getAllocatedType()); + if (TD.getTypeStoreSize(LI.getType()) > OldAllocSize) { + LI.replaceAllUsesWith(UndefValue::get(LI.getType())); + Pass.DeadInsts.insert(&LI); + deleteIfTriviallyDead(OldOp); + DEBUG(dbgs() << " to: undef!!\n"); + return true; + } + + Type *TargetTy = IsSplitIntLoad ? Type::getIntNTy(LI.getContext(), Size * 8) + : LI.getType(); + bool IsPtrAdjusted = false; + Value *V; + if (VecTy) { + V = rewriteVectorizedLoadInst(IRB, LI, OldOp); + } else if (IntTy && LI.getType()->isIntegerTy()) { + V = rewriteIntegerLoad(IRB, LI); + } else if (BeginOffset == NewAllocaBeginOffset && + canConvertValue(TD, NewAllocaTy, LI.getType())) { + V = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), + LI.isVolatile(), getName(".load")); + } else { + Type *LTy = TargetTy->getPointerTo(); + V = IRB.CreateAlignedLoad(getAdjustedAllocaPtr(IRB, LTy), + getPartitionTypeAlign(TargetTy), + LI.isVolatile(), getName(".load")); + IsPtrAdjusted = true; + } + V = convertValue(TD, IRB, V, TargetTy); + + if (IsSplitIntLoad) { assert(!LI.isVolatile()); assert(LI.getType()->isIntegerTy() && "Only integer type loads and stores are split"); @@ -2498,21 +2543,8 @@ private: assert(LI.getType()->getIntegerBitWidth() == TD.getTypeAllocSizeInBits(OldAI.getAllocatedType()) && "Only alloca-wide loads can be split and recomposed"); - IntegerType *NarrowTy = Type::getIntNTy(LI.getContext(), Size * 8); - bool IsConvertable = (BeginOffset - NewAllocaBeginOffset == 0) && - canConvertValue(TD, NewAllocaTy, NarrowTy); - Value *V; // Move the insertion point just past the load so that we can refer to it. IRB.SetInsertPoint(llvm::next(BasicBlock::iterator(&LI))); - if (IsConvertable) - V = convertValue(TD, IRB, - IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), - getName(".load")), - NarrowTy); - else - V = IRB.CreateAlignedLoad( - getAdjustedAllocaPtr(IRB, NarrowTy->getPointerTo()), - getPartitionTypeAlign(NarrowTy), getName(".load")); // Create a placeholder value with the same type as LI to use as the // basis for the new value. This allows us to replace the uses of LI with // the computed value, and then replace the placeholder with LI, leaving @@ -2524,44 +2556,18 @@ private: LI.replaceAllUsesWith(V); Placeholder->replaceAllUsesWith(&LI); delete Placeholder; - if (Pass.DeadSplitInsts.insert(&LI)) - Pass.DeadInsts.push_back(&LI); - DEBUG(dbgs() << " to: " << *V << "\n"); - return IsConvertable; - } - - if (VecTy) - return rewriteVectorizedLoadInst(IRB, LI, OldOp); - if (IntTy && LI.getType()->isIntegerTy()) - return rewriteIntegerLoad(IRB, LI); - - if (BeginOffset == NewAllocaBeginOffset && - canConvertValue(TD, NewAllocaTy, LI.getType())) { - Value *NewLI = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), - LI.isVolatile(), getName(".load")); - Value *NewV = convertValue(TD, IRB, NewLI, LI.getType()); - LI.replaceAllUsesWith(NewV); - Pass.DeadInsts.push_back(&LI); - - DEBUG(dbgs() << " to: " << *NewLI << "\n"); - return !LI.isVolatile(); + } else { + LI.replaceAllUsesWith(V); } - assert(!IntTy && "Invalid load found with int-op widening enabled"); - - Value *NewPtr = getAdjustedAllocaPtr(IRB, - LI.getPointerOperand()->getType()); - LI.setOperand(0, NewPtr); - LI.setAlignment(getPartitionTypeAlign(LI.getType())); - DEBUG(dbgs() << " to: " << LI << "\n"); - + Pass.DeadInsts.insert(&LI); deleteIfTriviallyDead(OldOp); - return NewPtr == &NewAI && !LI.isVolatile(); + DEBUG(dbgs() << " to: " << *V << "\n"); + return !LI.isVolatile() && !IsPtrAdjusted; } - bool rewriteVectorizedStoreInst(IRBuilder<> &IRB, StoreInst &SI, - Value *OldOp) { - Value *V = SI.getValueOperand(); + bool rewriteVectorizedStoreInst(IRBuilder<> &IRB, Value *V, + StoreInst &SI, Value *OldOp) { if (V->getType() == ElementTy || BeginOffset > NewAllocaBeginOffset || EndOffset < NewAllocaEndOffset) { if (V->getType() != ElementTy) @@ -2574,17 +2580,16 @@ private: V = convertValue(TD, IRB, V, VecTy); } StoreInst *Store = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment()); - Pass.DeadInsts.push_back(&SI); + Pass.DeadInsts.insert(&SI); (void)Store; DEBUG(dbgs() << " to: " << *Store << "\n"); return true; } - bool rewriteIntegerStore(IRBuilder<> &IRB, StoreInst &SI) { + bool rewriteIntegerStore(IRBuilder<> &IRB, Value *V, StoreInst &SI) { assert(IntTy && "We cannot extract an integer from the alloca"); assert(!SI.isVolatile()); - Value *V = SI.getValueOperand(); if (TD.getTypeSizeInBits(V->getType()) != IntTy->getBitWidth()) { Value *Old = IRB.CreateAlignedLoad(&NewAI, NewAI.getAlignment(), getName(".oldload")); @@ -2596,7 +2601,7 @@ private: } V = convertValue(TD, IRB, V, NewAllocaTy); StoreInst *Store = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment()); - Pass.DeadInsts.push_back(&SI); + Pass.DeadInsts.insert(&SI); (void)Store; DEBUG(dbgs() << " to: " << *Store << "\n"); return true; @@ -2608,74 +2613,53 @@ private: assert(OldOp == OldPtr); IRBuilder<> IRB(&SI); - if (VecTy) - return rewriteVectorizedStoreInst(IRB, SI, OldOp); - Type *ValueTy = SI.getValueOperand()->getType(); + Value *V = SI.getValueOperand(); + + // Strip all inbounds GEPs and pointer casts to try to dig out any root + // alloca that should be re-examined after promoting this alloca. + if (V->getType()->isPointerTy()) + if (AllocaInst *AI = dyn_cast(V->stripInBoundsOffsets())) + Pass.PostPromotionWorklist.insert(AI); uint64_t Size = EndOffset - BeginOffset; - if (Size < TD.getTypeStoreSize(ValueTy)) { + if (Size < TD.getTypeStoreSize(V->getType())) { assert(!SI.isVolatile()); - assert(ValueTy->isIntegerTy() && + assert(V->getType()->isIntegerTy() && "Only integer type loads and stores are split"); - assert(ValueTy->getIntegerBitWidth() == - TD.getTypeStoreSizeInBits(ValueTy) && + assert(V->getType()->getIntegerBitWidth() == + TD.getTypeStoreSizeInBits(V->getType()) && "Non-byte-multiple bit width"); - assert(ValueTy->getIntegerBitWidth() == + assert(V->getType()->getIntegerBitWidth() == TD.getTypeSizeInBits(OldAI.getAllocatedType()) && "Only alloca-wide stores can be split and recomposed"); IntegerType *NarrowTy = Type::getIntNTy(SI.getContext(), Size * 8); - Value *V = extractInteger(TD, IRB, SI.getValueOperand(), NarrowTy, - BeginOffset, getName(".extract")); - StoreInst *NewSI; - bool IsConvertable = (BeginOffset - NewAllocaBeginOffset == 0) && - canConvertValue(TD, NarrowTy, NewAllocaTy); - if (IsConvertable) - NewSI = IRB.CreateAlignedStore(convertValue(TD, IRB, V, NewAllocaTy), - &NewAI, NewAI.getAlignment()); - else - NewSI = IRB.CreateAlignedStore( - V, getAdjustedAllocaPtr(IRB, NarrowTy->getPointerTo()), - getPartitionTypeAlign(NarrowTy)); - (void)NewSI; - if (Pass.DeadSplitInsts.insert(&SI)) - Pass.DeadInsts.push_back(&SI); - - DEBUG(dbgs() << " to: " << *NewSI << "\n"); - return IsConvertable; + V = extractInteger(TD, IRB, V, NarrowTy, BeginOffset, + getName(".extract")); } - if (IntTy && ValueTy->isIntegerTy()) - return rewriteIntegerStore(IRB, SI); - - // Strip all inbounds GEPs and pointer casts to try to dig out any root - // alloca that should be re-examined after promoting this alloca. - if (ValueTy->isPointerTy()) - if (AllocaInst *AI = dyn_cast(SI.getValueOperand() - ->stripInBoundsOffsets())) - Pass.PostPromotionWorklist.insert(AI); + if (VecTy) + return rewriteVectorizedStoreInst(IRB, V, SI, OldOp); + if (IntTy && V->getType()->isIntegerTy()) + return rewriteIntegerStore(IRB, V, SI); + StoreInst *NewSI; if (BeginOffset == NewAllocaBeginOffset && - canConvertValue(TD, ValueTy, NewAllocaTy)) { - Value *NewV = convertValue(TD, IRB, SI.getValueOperand(), NewAllocaTy); - StoreInst *NewSI = IRB.CreateAlignedStore(NewV, &NewAI, NewAI.getAlignment(), - SI.isVolatile()); - (void)NewSI; - Pass.DeadInsts.push_back(&SI); - - DEBUG(dbgs() << " to: " << *NewSI << "\n"); - return !SI.isVolatile(); + canConvertValue(TD, V->getType(), NewAllocaTy)) { + V = convertValue(TD, IRB, V, NewAllocaTy); + NewSI = IRB.CreateAlignedStore(V, &NewAI, NewAI.getAlignment(), + SI.isVolatile()); + } else { + Value *NewPtr = getAdjustedAllocaPtr(IRB, V->getType()->getPointerTo()); + NewSI = IRB.CreateAlignedStore(V, NewPtr, + getPartitionTypeAlign(V->getType()), + SI.isVolatile()); } - - assert(!IntTy && "Invalid store found with int-op widening enabled"); - - Value *NewPtr = getAdjustedAllocaPtr(IRB, - SI.getPointerOperand()->getType()); - SI.setOperand(1, NewPtr); - SI.setAlignment(getPartitionTypeAlign(SI.getValueOperand()->getType())); - DEBUG(dbgs() << " to: " << SI << "\n"); - + (void)NewSI; + Pass.DeadInsts.insert(&SI); deleteIfTriviallyDead(OldOp); - return NewPtr == &NewAI && !SI.isVolatile(); + + DEBUG(dbgs() << " to: " << *NewSI << "\n"); + return NewSI->getPointerOperand() == &NewAI && !SI.isVolatile(); } bool visitMemSetInst(MemSetInst &II) { @@ -2695,8 +2679,7 @@ private: } // Record this instruction for deletion. - if (Pass.DeadSplitInsts.insert(&II)) - Pass.DeadInsts.push_back(&II); + Pass.DeadInsts.insert(&II); Type *AllocaTy = NewAI.getAllocatedType(); Type *ScalarTy = AllocaTy->getScalarType(); @@ -2852,8 +2835,7 @@ private: return false; } // Record this instruction for deletion. - if (Pass.DeadSplitInsts.insert(&II)) - Pass.DeadInsts.push_back(&II); + Pass.DeadInsts.insert(&II); bool IsWholeAlloca = BeginOffset == NewAllocaBeginOffset && EndOffset == NewAllocaEndOffset; @@ -2963,8 +2945,7 @@ private: assert(II.getArgOperand(1) == OldPtr); // Record this instruction for deletion. - if (Pass.DeadSplitInsts.insert(&II)) - Pass.DeadInsts.push_back(&II); + Pass.DeadInsts.insert(&II); ConstantInt *Size = ConstantInt::get(cast(II.getArgOperand(0)->getType()), @@ -3533,7 +3514,7 @@ bool SROA::runOnAlloca(AllocaInst &AI) { DI != DE; ++DI) { Changed = true; (*DI)->replaceAllUsesWith(UndefValue::get((*DI)->getType())); - DeadInsts.push_back(*DI); + DeadInsts.insert(*DI); } for (AllocaPartitioning::dead_op_iterator DO = P.dead_op_begin(), DE = P.dead_op_end(); @@ -3544,7 +3525,7 @@ bool SROA::runOnAlloca(AllocaInst &AI) { if (Instruction *OldI = dyn_cast(OldV)) if (isInstructionTriviallyDead(OldI)) { Changed = true; - DeadInsts.push_back(OldI); + DeadInsts.insert(OldI); } } @@ -3565,7 +3546,6 @@ bool SROA::runOnAlloca(AllocaInst &AI) { /// We also record the alloca instructions deleted here so that they aren't /// subsequently handed to mem2reg to promote. void SROA::deleteDeadInstructions(SmallPtrSet &DeletedAllocas) { - DeadSplitInsts.clear(); while (!DeadInsts.empty()) { Instruction *I = DeadInsts.pop_back_val(); DEBUG(dbgs() << "Deleting dead instruction: " << *I << "\n"); @@ -3577,7 +3557,7 @@ void SROA::deleteDeadInstructions(SmallPtrSet &DeletedAllocas) { // Zero out the operand and see if it becomes trivially dead. *OI = 0; if (isInstructionTriviallyDead(U)) - DeadInsts.push_back(U); + DeadInsts.insert(U); } if (AllocaInst *AI = dyn_cast(I)) -- cgit v1.2.3 From b30ce3e484f1e7f37a709e6fa7a91712a3d85e97 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 18:55:44 +0000 Subject: Merging r168035: into 3.2 release branch. Fix a crash observed by Shuxin Yang. The issue here is that LinearizeExprTree, the utility for extracting a chain of operations from the IR, thought that it might as well combine any constants it came across (rather than just returning them along with everything else). On the other hand, the factorization code would like to see the individual constants (this is quite reasonable: it is much easier to pull a factor of 3 out of 2*3 than it is to pull it out of 6; you may think 6/3 isn't so hard, but due to overflow it's not as easy to undo multiplications of constants as it may at first appear). This patch therefore makes LinearizeExprTree stupider: it now leaves optimizing to the optimization part of reassociate, and sticks to just analysing the IR. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168446 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/Reassociate.cpp | 75 ++++++++++------------------------- 1 file changed, 21 insertions(+), 54 deletions(-) (limited to 'lib') diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index 09687d8909..f19b7fec0a 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -339,36 +339,6 @@ static void IncorporateWeight(APInt &LHS, const APInt &RHS, unsigned Opcode) { } } -/// EvaluateRepeatedConstant - Compute C op C op ... op C where the constant C -/// is repeated Weight times. -static Constant *EvaluateRepeatedConstant(unsigned Opcode, Constant *C, - APInt Weight) { - // For addition the result can be efficiently computed as the product of the - // constant and the weight. - if (Opcode == Instruction::Add) - return ConstantExpr::getMul(C, ConstantInt::get(C->getContext(), Weight)); - - // The weight might be huge, so compute by repeated squaring to ensure that - // compile time is proportional to the logarithm of the weight. - Constant *Result = 0; - Constant *Power = C; // Successively C, C op C, (C op C) op (C op C) etc. - // Visit the bits in Weight. - while (Weight != 0) { - // If the current bit in Weight is non-zero do Result = Result op Power. - if (Weight[0]) - Result = Result ? ConstantExpr::get(Opcode, Result, Power) : Power; - // Move on to the next bit if any more are non-zero. - Weight = Weight.lshr(1); - if (Weight.isMinValue()) - break; - // Square the power. - Power = ConstantExpr::get(Opcode, Power, Power); - } - - assert(Result && "Only positive weights supported!"); - return Result; -} - typedef std::pair RepeatedValue; /// LinearizeExprTree - Given an associative binary expression, return the leaf @@ -382,9 +352,7 @@ typedef std::pair RepeatedValue; /// op /// (Ops[N].first op Ops[N].first op ... Ops[N].first) <- Ops[N].second times /// -/// Note that the values Ops[0].first, ..., Ops[N].first are all distinct, and -/// they are all non-constant except possibly for the last one, which if it is -/// constant will have weight one (Ops[N].second === 1). +/// Note that the values Ops[0].first, ..., Ops[N].first are all distinct. /// /// This routine may modify the function, in which case it returns 'true'. The /// changes it makes may well be destructive, changing the value computed by 'I' @@ -604,7 +572,6 @@ static bool LinearizeExprTree(BinaryOperator *I, // The leaves, repeated according to their weights, represent the linearized // form of the expression. - Constant *Cst = 0; // Accumulate constants here. for (unsigned i = 0, e = LeafOrder.size(); i != e; ++i) { Value *V = LeafOrder[i]; LeafMap::iterator It = Leaves.find(V); @@ -618,31 +585,14 @@ static bool LinearizeExprTree(BinaryOperator *I, continue; // Ensure the leaf is only output once. It->second = 0; - // Glob all constants together into Cst. - if (Constant *C = dyn_cast(V)) { - C = EvaluateRepeatedConstant(Opcode, C, Weight); - Cst = Cst ? ConstantExpr::get(Opcode, Cst, C) : C; - continue; - } - // Add non-constant Ops.push_back(std::make_pair(V, Weight)); } - // Add any constants back into Ops, all globbed together and reduced to having - // weight 1 for the convenience of users. - Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, I->getType()); - if (Cst && Cst != Identity) { - // If combining multiple constants resulted in the absorber then the entire - // expression must evaluate to the absorber. - if (Cst == Absorber) - Ops.clear(); - Ops.push_back(std::make_pair(Cst, APInt(Bitwidth, 1))); - } - // For nilpotent operations or addition there may be no operands, for example // because the expression was "X xor X" or consisted of 2^Bitwidth additions: // in both cases the weight reduces to 0 causing the value to be skipped. if (Ops.empty()) { + Constant *Identity = ConstantExpr::getBinOpIdentity(Opcode, I->getType()); assert(Identity && "Associative operation without identity!"); Ops.push_back(std::make_pair(Identity, APInt(Bitwidth, 1))); } @@ -1446,9 +1396,26 @@ Value *Reassociate::OptimizeExpression(BinaryOperator *I, SmallVectorImpl &Ops) { // Now that we have the linearized expression tree, try to optimize it. // Start by folding any constants that we found. - if (Ops.size() == 1) return Ops[0].Op; - + Constant *Cst = 0; unsigned Opcode = I->getOpcode(); + while (!Ops.empty() && isa(Ops.back().Op)) { + Constant *C = cast(Ops.pop_back_val().Op); + Cst = Cst ? ConstantExpr::get(Opcode, C, Cst) : C; + } + // If there was nothing but constants then we are done. + if (Ops.empty()) + return Cst; + + // Put the combined constant back at the end of the operand list, except if + // there is no point. For example, an add of 0 gets dropped here, while a + // multiplication by zero turns the whole expression into zero. + if (Cst && Cst != ConstantExpr::getBinOpIdentity(Opcode, I->getType())) { + if (Cst == ConstantExpr::getBinOpAbsorber(Opcode, I->getType())) + return Cst; + Ops.push_back(ValueEntry(0, Cst)); + } + + if (Ops.size() == 1) return Ops[0].Op; // Handle destructive annihilation due to identities between elements in the // argument list here. -- cgit v1.2.3 From 07d7748544abaaf97123233804a194478ed020b3 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 19:01:53 +0000 Subject: Merging r168181: into 3.2 release branch. Fix PR14361: wrong simplification of A+B==B+A. You may think that the old logic replaced by this patch is equivalent to the new logic, but you'd be wrong, and that's exactly where the bug was. There's a similar bug in instsimplify which manifests itself as instsimplify failing to simplify this, rather than doing it wrong, see next commit. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168447 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineCompares.cpp | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/Transforms/InstCombine/InstCombineCompares.cpp b/lib/Transforms/InstCombine/InstCombineCompares.cpp index 8cb4a59cba..e223a049f0 100644 --- a/lib/Transforms/InstCombine/InstCombineCompares.cpp +++ b/lib/Transforms/InstCombine/InstCombineCompares.cpp @@ -2356,8 +2356,20 @@ Instruction *InstCombiner::visitICmpInst(ICmpInst &I) { // Try not to increase register pressure. BO0->hasOneUse() && BO1->hasOneUse()) { // Determine Y and Z in the form icmp (X+Y), (X+Z). - Value *Y = (A == C || A == D) ? B : A; - Value *Z = (C == A || C == B) ? D : C; + Value *Y, *Z; + if (A == C) { + Y = B; + Z = D; + } else if (A == D) { + Y = B; + Z = C; + } else if (B == C) { + Y = A; + Z = D; + } else if (B == D) { + Y = A; + Z = C; + } return new ICmpInst(Pred, Y, Z); } -- cgit v1.2.3 From 7022c651cab8a4e3e310e024a2028eb9fa5b482e Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 20:30:37 +0000 Subject: Merging r168354, r168355 and r168379 into the 3.2 release branch. Set of Attributes patches. Merging r168354: 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. Merging r168355: Merging r168379 git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168457 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AsmParser/LLParser.cpp | 6 +- lib/Bitcode/Reader/BitcodeReader.cpp | 2 +- lib/Transforms/IPO/ArgumentPromotion.cpp | 8 ++- lib/Transforms/IPO/DeadArgumentElimination.cpp | 6 +- lib/Transforms/InstCombine/InstCombineCalls.cpp | 5 +- lib/Transforms/Utils/BuildLibCalls.cpp | 43 +++++++---- lib/VMCore/Attributes.cpp | 96 ++++--------------------- lib/VMCore/AttributesImpl.h | 24 ++++++- lib/VMCore/LLVMContextImpl.cpp | 9 ++- lib/VMCore/LLVMContextImpl.h | 3 +- 10 files changed, 91 insertions(+), 111 deletions(-) (limited to 'lib') diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index e8e6e27725..b24291ffb3 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2794,7 +2794,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Attributes::get(RetType->getContext(), FuncAttrs))); - AttrListPtr PAL = AttrListPtr::get(Attrs); + AttrListPtr PAL = AttrListPtr::get(Context, Attrs); if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) && !RetType->isVoidTy()) @@ -3351,7 +3351,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { FnAttrs))); // 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); II->setCallingConv(CC); @@ -3753,7 +3753,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, FnAttrs))); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs); + AttrListPtr PAL = AttrListPtr::get(Context, Attrs); CallInst *CI = CallInst::Create(Callee, Args); CI->setTailCall(isTail); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 279343c48c..4ec9da12dd 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -487,7 +487,7 @@ bool BitcodeReader::ParseAttributeBlock() { Attributes::get(Context, B))); } - MAttributes.push_back(AttrListPtr::get(Attrs)); + MAttributes.push_back(AttrListPtr::get(Context, Attrs)); Attrs.clear(); break; } diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index 8a0274b5ff..be48b2063f 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -611,7 +611,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, // Recompute the parameter attributes list based on the new arguments for // the function. - NF->setAttributes(AttrListPtr::get(AttributesVec)); + NF->setAttributes(AttrListPtr::get(F->getContext(), AttributesVec)); AttributesVec.clear(); F->getParent()->getFunctionList().insert(F, NF); @@ -731,11 +731,13 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), Args, "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setAttributes(AttrListPtr::get(AttributesVec)); + cast(New)->setAttributes(AttrListPtr::get(II->getContext(), + AttributesVec)); } else { New = CallInst::Create(NF, Args, "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setAttributes(AttrListPtr::get(AttributesVec)); + cast(New)->setAttributes(AttrListPtr::get(New->getContext(), + AttributesVec)); if (cast(Call)->isTailCall()) cast(New)->setTailCall(); } diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index fc22548db7..4cfd0b235a 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -280,7 +280,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { if (FnAttrs.hasAttributes()) AttributesVec.push_back(AttributeWithIndex::get(AttrListPtr::FunctionIndex, FnAttrs)); - PAL = AttrListPtr::get(AttributesVec); + PAL = AttrListPtr::get(Fn.getContext(), AttributesVec); } Instruction *New; @@ -806,7 +806,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { FnAttrs)); // 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. FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg()); @@ -874,7 +874,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { FnAttrs)); // Reconstruct the AttributesList based on the vector we constructed. - AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec); + AttrListPtr NewCallPAL = AttrListPtr::get(F->getContext(), AttributesVec); Instruction *New; if (InvokeInst *II = dyn_cast(Call)) { diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 5ad6f9111c..48f270429e 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1177,7 +1177,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { if (NewRetTy->isVoidTy()) 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; if (InvokeInst *II = dyn_cast(Caller)) { @@ -1355,7 +1356,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS, NestF->getType() == PointerType::getUnqual(NewFTy) ? NestF : ConstantExpr::getBitCast(NestF, PointerType::getUnqual(NewFTy)); - const AttrListPtr &NewPAL = AttrListPtr::get(NewAttrs); + const AttrListPtr &NewPAL = AttrListPtr::get(FTy->getContext(), NewAttrs); Instruction *NewCaller; if (InvokeInst *II = dyn_cast(Caller)) { diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp index fa2faa2dad..74b2ee10e0 100644 --- a/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/lib/Transforms/Utils/BuildLibCalls.cpp @@ -47,7 +47,9 @@ Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD, ArrayRef(AVs, 2)); 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), B.getInt8PtrTy(), NULL); @@ -74,7 +76,9 @@ Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B, ArrayRef(AVs, 2)); 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), B.getInt8PtrTy(), TD->getIntPtrType(Context), @@ -102,7 +106,9 @@ Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, Type *I8Ptr = B.getInt8PtrTy(); 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); CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), ConstantInt::get(I32Ty, C), "strchr"); @@ -127,7 +133,9 @@ Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, ArrayRef(AVs, 2)); 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.getInt8PtrTy(), B.getInt8PtrTy(), @@ -155,7 +163,8 @@ Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); 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); CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Name); @@ -178,7 +187,9 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); 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, Len->getType(), NULL); 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); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *MemCpy = M->getOrInsertFunction("__memcpy_chk", - AttrListPtr::get(AWI), + AttrListPtr::get(M->getContext(), AWI), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt8PtrTy(), @@ -231,7 +242,8 @@ Value *llvm::EmitMemChr(Value *Ptr, Value *Val, AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, ArrayRef(AVs, 2)); 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.getInt32Ty(), @@ -261,7 +273,8 @@ Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2, ArrayRef(AVs, 2)); 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.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, Attributes::NoUnwind); - Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI), + Value *PutS = M->getOrInsertFunction("puts", + AttrListPtr::get(M->getContext(), AWI), B.getInt32Ty(), B.getInt8PtrTy(), NULL); @@ -362,7 +376,8 @@ Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, Attributes::NoUnwind); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI), + F = M->getOrInsertFunction("fputc", + AttrListPtr::get(M->getContext(), AWI), B.getInt32Ty(), B.getInt32Ty(), File->getType(), NULL); @@ -396,7 +411,8 @@ Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, StringRef FPutsName = TLI->getName(LibFunc::fputs); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI), + F = M->getOrInsertFunction(FPutsName, + AttrListPtr::get(M->getContext(), AWI), B.getInt32Ty(), B.getInt8PtrTy(), File->getType(), NULL); @@ -429,7 +445,8 @@ Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File, StringRef FWriteName = TLI->getName(LibFunc::fwrite); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI), + F = M->getOrInsertFunction(FWriteName, + AttrListPtr::get(M->getContext(), AWI), TD->getIntPtrType(Context), B.getInt8PtrTy(), TD->getIntPtrType(Context), diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 5a552c34e1..f1268e6ef8 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -355,62 +355,8 @@ uint64_t AttributesImpl::getStackAlignment() const { // AttributeListImpl Definition //===----------------------------------------------------------------------===// -namespace llvm { - class AttributeListImpl; -} - -static ManagedStatic > AttributesLists; - -namespace llvm { -static ManagedStatic > 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 Attrs; - - AttributeListImpl(ArrayRef attrs) - : Attrs(attrs.begin(), attrs.end()) { - RefCount = 0; - } - - void AddRef() { - sys::SmartScopedLock Lock(*ALMutex); - ++RefCount; - } - void DropRef() { - sys::SmartScopedLock 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 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 Attrs) { +AttrListPtr AttrListPtr::get(LLVMContext &C, + ArrayRef Attrs) { // If there are no attributes then return a null AttributesList pointer. if (Attrs.empty()) return AttrListPtr(); @@ -425,51 +371,36 @@ AttrListPtr AttrListPtr::get(ArrayRef Attrs) { #endif // Otherwise, build a key to look up the existing attributes. + LLVMContextImpl *pImpl = C.pImpl; FoldingSetNodeID ID; AttributeListImpl::Profile(ID, Attrs); - void *InsertPos; - - sys::SmartScopedLock Lock(*ALMutex); - AttributeListImpl *PAL = - AttributesLists->FindNodeOrInsertPos(ID, InsertPos); + void *InsertPoint; + AttributeListImpl *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. - if (!PAL) { - PAL = new AttributeListImpl(Attrs); - AttributesLists->InsertNode(PAL, InsertPos); + if (!PA) { + PA = new AttributeListImpl(Attrs); + pImpl->AttrsLists.InsertNode(PA, InsertPoint); } // Return the AttributesList that we found or created. - return AttrListPtr(PAL); + return AttrListPtr(PA); } //===----------------------------------------------------------------------===// // 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) { - sys::SmartScopedLock Lock(*ALMutex); if (AttrList == RHS.AttrList) return *this; - if (AttrList) AttrList->DropRef(); + AttrList = RHS.AttrList; - if (AttrList) AttrList->AddRef(); return *this; } -AttrListPtr::~AttrListPtr() { - if (AttrList) AttrList->DropRef(); -} - /// getNumSlots - Return the number of slots used in this attribute list. /// This is the number of arguments that have an attribute set on them /// (including the function itself). @@ -507,6 +438,7 @@ bool AttrListPtr::hasAttrSomewhere(Attributes::AttrVal Attr) const { for (unsigned i = 0, e = Attrs.size(); i != e; ++i) if (Attrs[i].Attrs.hasAttribute(Attr)) return true; + return false; } @@ -562,7 +494,7 @@ AttrListPtr AttrListPtr::addAttr(LLVMContext &C, unsigned Idx, OldAttrList.begin()+i, OldAttrList.end()); } - return get(NewAttrList); + return get(C, NewAttrList); } AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx, @@ -601,7 +533,7 @@ AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx, NewAttrList.insert(NewAttrList.end(), OldAttrList.begin()+i, OldAttrList.end()); - return get(NewAttrList); + return get(C, NewAttrList); } void AttrListPtr::dump() const { diff --git a/lib/VMCore/AttributesImpl.h b/lib/VMCore/AttributesImpl.h index b4a0f615f3..5c107e1ebb 100644 --- a/lib/VMCore/AttributesImpl.h +++ b/lib/VMCore/AttributesImpl.h @@ -15,12 +15,11 @@ #ifndef LLVM_ATTRIBUTESIMPL_H #define LLVM_ATTRIBUTESIMPL_H +#include "llvm/Attributes.h" #include "llvm/ADT/FoldingSet.h" namespace llvm { -class Attributes; - class AttributesImpl : public FoldingSetNode { uint64_t Bits; // FIXME: We will be expanding this. 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 Attrs; + + AttributeListImpl(ArrayRef attrs) + : Attrs(attrs.begin(), attrs.end()) {} + + void Profile(FoldingSetNodeID &ID) const { + Profile(ID, Attrs); + } + static void Profile(FoldingSetNodeID &ID, ArrayRef 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 #endif diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index 74247bdde1..d35d2844b8 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -97,11 +97,18 @@ LLVMContextImpl::~LLVMContextImpl() { // Destroy attributes. for (FoldingSetIterator I = AttrsSet.begin(), - E = AttrsSet.end(); I != E;) { + E = AttrsSet.end(); I != E; ) { FoldingSetIterator Elem = I++; delete &*Elem; } + // Destroy attribute lists. + for (FoldingSetIterator I = AttrsLists.begin(), + E = AttrsLists.end(); I != E; ) { + FoldingSetIterator Elem = I++; + delete &*Elem; + } + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. SmallVector MDNodes; diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index ee31814c05..90cf424a3c 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -256,7 +256,8 @@ public: FPMapTy FPConstants; FoldingSet AttrsSet; - + FoldingSet AttrsLists; + StringMap MDStringCache; FoldingSet MDNodeSet; -- cgit v1.2.3 From 3e2cbf9d08ffd6f26302c19fdc7997e441c741e9 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Wed, 21 Nov 2012 22:21:40 +0000 Subject: Reverting 168457 git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168465 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AsmParser/LLParser.cpp | 6 +- lib/Bitcode/Reader/BitcodeReader.cpp | 2 +- lib/Transforms/IPO/ArgumentPromotion.cpp | 8 +-- lib/Transforms/IPO/DeadArgumentElimination.cpp | 6 +- lib/Transforms/InstCombine/InstCombineCalls.cpp | 5 +- lib/Transforms/Utils/BuildLibCalls.cpp | 43 ++++------- lib/VMCore/Attributes.cpp | 96 +++++++++++++++++++++---- lib/VMCore/AttributesImpl.h | 24 +------ lib/VMCore/LLVMContextImpl.cpp | 9 +-- lib/VMCore/LLVMContextImpl.h | 3 +- 10 files changed, 111 insertions(+), 91 deletions(-) (limited to 'lib') diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index b24291ffb3..e8e6e27725 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2794,7 +2794,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Attributes::get(RetType->getContext(), FuncAttrs))); - AttrListPtr PAL = AttrListPtr::get(Context, Attrs); + AttrListPtr PAL = AttrListPtr::get(Attrs); if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) && !RetType->isVoidTy()) @@ -3351,7 +3351,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { FnAttrs))); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Context, Attrs); + AttrListPtr PAL = AttrListPtr::get(Attrs); InvokeInst *II = InvokeInst::Create(Callee, NormalBB, UnwindBB, Args); II->setCallingConv(CC); @@ -3753,7 +3753,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, FnAttrs))); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Context, Attrs); + AttrListPtr PAL = AttrListPtr::get(Attrs); CallInst *CI = CallInst::Create(Callee, Args); CI->setTailCall(isTail); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 4ec9da12dd..279343c48c 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -487,7 +487,7 @@ bool BitcodeReader::ParseAttributeBlock() { Attributes::get(Context, B))); } - MAttributes.push_back(AttrListPtr::get(Context, Attrs)); + MAttributes.push_back(AttrListPtr::get(Attrs)); Attrs.clear(); break; } diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index be48b2063f..8a0274b5ff 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -611,7 +611,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, // Recompute the parameter attributes list based on the new arguments for // the function. - NF->setAttributes(AttrListPtr::get(F->getContext(), AttributesVec)); + NF->setAttributes(AttrListPtr::get(AttributesVec)); AttributesVec.clear(); F->getParent()->getFunctionList().insert(F, NF); @@ -731,13 +731,11 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), Args, "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setAttributes(AttrListPtr::get(II->getContext(), - AttributesVec)); + cast(New)->setAttributes(AttrListPtr::get(AttributesVec)); } else { New = CallInst::Create(NF, Args, "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setAttributes(AttrListPtr::get(New->getContext(), - AttributesVec)); + cast(New)->setAttributes(AttrListPtr::get(AttributesVec)); if (cast(Call)->isTailCall()) cast(New)->setTailCall(); } diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index 4cfd0b235a..fc22548db7 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -280,7 +280,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { if (FnAttrs.hasAttributes()) AttributesVec.push_back(AttributeWithIndex::get(AttrListPtr::FunctionIndex, FnAttrs)); - PAL = AttrListPtr::get(Fn.getContext(), AttributesVec); + PAL = AttrListPtr::get(AttributesVec); } Instruction *New; @@ -806,7 +806,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { FnAttrs)); // Reconstruct the AttributesList based on the vector we constructed. - AttrListPtr NewPAL = AttrListPtr::get(F->getContext(), AttributesVec); + AttrListPtr NewPAL = AttrListPtr::get(AttributesVec); // Create the new function type based on the recomputed parameters. FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg()); @@ -874,7 +874,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { FnAttrs)); // Reconstruct the AttributesList based on the vector we constructed. - AttrListPtr NewCallPAL = AttrListPtr::get(F->getContext(), AttributesVec); + AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec); Instruction *New; if (InvokeInst *II = dyn_cast(Call)) { diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 48f270429e..5ad6f9111c 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1177,8 +1177,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { if (NewRetTy->isVoidTy()) Caller->setName(""); // Void type should not have a name. - const AttrListPtr &NewCallerPAL = AttrListPtr::get(Callee->getContext(), - attrVec); + const AttrListPtr &NewCallerPAL = AttrListPtr::get(attrVec); Instruction *NC; if (InvokeInst *II = dyn_cast(Caller)) { @@ -1356,7 +1355,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS, NestF->getType() == PointerType::getUnqual(NewFTy) ? NestF : ConstantExpr::getBitCast(NestF, PointerType::getUnqual(NewFTy)); - const AttrListPtr &NewPAL = AttrListPtr::get(FTy->getContext(), NewAttrs); + const AttrListPtr &NewPAL = AttrListPtr::get(NewAttrs); Instruction *NewCaller; if (InvokeInst *II = dyn_cast(Caller)) { diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp index 74b2ee10e0..fa2faa2dad 100644 --- a/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/lib/Transforms/Utils/BuildLibCalls.cpp @@ -47,9 +47,7 @@ Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD, ArrayRef(AVs, 2)); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Constant *StrLen = M->getOrInsertFunction("strlen", - AttrListPtr::get(M->getContext(), - AWI), + Constant *StrLen = M->getOrInsertFunction("strlen", AttrListPtr::get(AWI), TD->getIntPtrType(Context), B.getInt8PtrTy(), NULL); @@ -76,9 +74,7 @@ Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B, ArrayRef(AVs, 2)); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Constant *StrNLen = M->getOrInsertFunction("strnlen", - AttrListPtr::get(M->getContext(), - AWI), + Constant *StrNLen = M->getOrInsertFunction("strnlen", AttrListPtr::get(AWI), TD->getIntPtrType(Context), B.getInt8PtrTy(), TD->getIntPtrType(Context), @@ -106,9 +102,7 @@ Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, Type *I8Ptr = B.getInt8PtrTy(); Type *I32Ty = B.getInt32Ty(); - Constant *StrChr = M->getOrInsertFunction("strchr", - AttrListPtr::get(M->getContext(), - AWI), + Constant *StrChr = M->getOrInsertFunction("strchr", AttrListPtr::get(AWI), I8Ptr, I8Ptr, I32Ty, NULL); CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), ConstantInt::get(I32Ty, C), "strchr"); @@ -133,9 +127,7 @@ Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, ArrayRef(AVs, 2)); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Value *StrNCmp = M->getOrInsertFunction("strncmp", - AttrListPtr::get(M->getContext(), - AWI), + Value *StrNCmp = M->getOrInsertFunction("strncmp", AttrListPtr::get(AWI), B.getInt32Ty(), B.getInt8PtrTy(), B.getInt8PtrTy(), @@ -163,8 +155,7 @@ Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); Type *I8Ptr = B.getInt8PtrTy(); - Value *StrCpy = M->getOrInsertFunction(Name, - AttrListPtr::get(M->getContext(), AWI), + Value *StrCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI), I8Ptr, I8Ptr, I8Ptr, NULL); CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Name); @@ -187,9 +178,7 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); Type *I8Ptr = B.getInt8PtrTy(); - Value *StrNCpy = M->getOrInsertFunction(Name, - AttrListPtr::get(M->getContext(), - AWI), + Value *StrNCpy = M->getOrInsertFunction(Name, AttrListPtr::get(AWI), I8Ptr, I8Ptr, I8Ptr, Len->getType(), NULL); CallInst *CI = B.CreateCall3(StrNCpy, CastToCStr(Dst, B), CastToCStr(Src, B), @@ -214,7 +203,7 @@ Value *llvm::EmitMemCpyChk(Value *Dst, Value *Src, Value *Len, Value *ObjSize, Attributes::NoUnwind); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *MemCpy = M->getOrInsertFunction("__memcpy_chk", - AttrListPtr::get(M->getContext(), AWI), + AttrListPtr::get(AWI), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt8PtrTy(), @@ -242,8 +231,7 @@ Value *llvm::EmitMemChr(Value *Ptr, Value *Val, AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, ArrayRef(AVs, 2)); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Value *MemChr = M->getOrInsertFunction("memchr", - AttrListPtr::get(M->getContext(), AWI), + Value *MemChr = M->getOrInsertFunction("memchr", AttrListPtr::get(AWI), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt32Ty(), @@ -273,8 +261,7 @@ Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2, ArrayRef(AVs, 2)); LLVMContext &Context = B.GetInsertBlock()->getContext(); - Value *MemCmp = M->getOrInsertFunction("memcmp", - AttrListPtr::get(M->getContext(), AWI), + Value *MemCmp = M->getOrInsertFunction("memcmp", AttrListPtr::get(AWI), B.getInt32Ty(), B.getInt8PtrTy(), B.getInt8PtrTy(), @@ -351,8 +338,7 @@ Value *llvm::EmitPutS(Value *Str, IRBuilder<> &B, const DataLayout *TD, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); - Value *PutS = M->getOrInsertFunction("puts", - AttrListPtr::get(M->getContext(), AWI), + Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI), B.getInt32Ty(), B.getInt8PtrTy(), NULL); @@ -376,8 +362,7 @@ Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, Attributes::NoUnwind); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction("fputc", - AttrListPtr::get(M->getContext(), AWI), + F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI), B.getInt32Ty(), B.getInt32Ty(), File->getType(), NULL); @@ -411,8 +396,7 @@ Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, StringRef FPutsName = TLI->getName(LibFunc::fputs); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction(FPutsName, - AttrListPtr::get(M->getContext(), AWI), + F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI), B.getInt32Ty(), B.getInt8PtrTy(), File->getType(), NULL); @@ -445,8 +429,7 @@ Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File, StringRef FWriteName = TLI->getName(LibFunc::fwrite); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction(FWriteName, - AttrListPtr::get(M->getContext(), AWI), + F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI), TD->getIntPtrType(Context), B.getInt8PtrTy(), TD->getIntPtrType(Context), diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index f1268e6ef8..5a552c34e1 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -355,8 +355,62 @@ uint64_t AttributesImpl::getStackAlignment() const { // AttributeListImpl Definition //===----------------------------------------------------------------------===// -AttrListPtr AttrListPtr::get(LLVMContext &C, - ArrayRef Attrs) { +namespace llvm { + class AttributeListImpl; +} + +static ManagedStatic > AttributesLists; + +namespace llvm { +static ManagedStatic > 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 Attrs; + + AttributeListImpl(ArrayRef attrs) + : Attrs(attrs.begin(), attrs.end()) { + RefCount = 0; + } + + void AddRef() { + sys::SmartScopedLock Lock(*ALMutex); + ++RefCount; + } + void DropRef() { + sys::SmartScopedLock 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 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 Attrs) { // If there are no attributes then return a null AttributesList pointer. if (Attrs.empty()) return AttrListPtr(); @@ -371,36 +425,51 @@ AttrListPtr AttrListPtr::get(LLVMContext &C, #endif // Otherwise, build a key to look up the existing attributes. - LLVMContextImpl *pImpl = C.pImpl; FoldingSetNodeID ID; AttributeListImpl::Profile(ID, Attrs); + void *InsertPos; - void *InsertPoint; - AttributeListImpl *PA = pImpl->AttrsLists.FindNodeOrInsertPos(ID, - InsertPoint); + sys::SmartScopedLock Lock(*ALMutex); + + AttributeListImpl *PAL = + AttributesLists->FindNodeOrInsertPos(ID, InsertPos); // If we didn't find any existing attributes of the same shape then // create a new one and insert it. - if (!PA) { - PA = new AttributeListImpl(Attrs); - pImpl->AttrsLists.InsertNode(PA, InsertPoint); + if (!PAL) { + PAL = new AttributeListImpl(Attrs); + AttributesLists->InsertNode(PAL, InsertPos); } // Return the AttributesList that we found or created. - return AttrListPtr(PA); + return AttrListPtr(PAL); } //===----------------------------------------------------------------------===// // 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) { + sys::SmartScopedLock Lock(*ALMutex); if (AttrList == RHS.AttrList) return *this; - + if (AttrList) AttrList->DropRef(); AttrList = RHS.AttrList; + if (AttrList) AttrList->AddRef(); return *this; } +AttrListPtr::~AttrListPtr() { + if (AttrList) AttrList->DropRef(); +} + /// getNumSlots - Return the number of slots used in this attribute list. /// This is the number of arguments that have an attribute set on them /// (including the function itself). @@ -438,7 +507,6 @@ bool AttrListPtr::hasAttrSomewhere(Attributes::AttrVal Attr) const { for (unsigned i = 0, e = Attrs.size(); i != e; ++i) if (Attrs[i].Attrs.hasAttribute(Attr)) return true; - return false; } @@ -494,7 +562,7 @@ AttrListPtr AttrListPtr::addAttr(LLVMContext &C, unsigned Idx, OldAttrList.begin()+i, OldAttrList.end()); } - return get(C, NewAttrList); + return get(NewAttrList); } AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx, @@ -533,7 +601,7 @@ AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx, NewAttrList.insert(NewAttrList.end(), OldAttrList.begin()+i, OldAttrList.end()); - return get(C, NewAttrList); + return get(NewAttrList); } void AttrListPtr::dump() const { diff --git a/lib/VMCore/AttributesImpl.h b/lib/VMCore/AttributesImpl.h index 5c107e1ebb..b4a0f615f3 100644 --- a/lib/VMCore/AttributesImpl.h +++ b/lib/VMCore/AttributesImpl.h @@ -15,11 +15,12 @@ #ifndef LLVM_ATTRIBUTESIMPL_H #define LLVM_ATTRIBUTESIMPL_H -#include "llvm/Attributes.h" #include "llvm/ADT/FoldingSet.h" namespace llvm { +class Attributes; + class AttributesImpl : public FoldingSetNode { uint64_t Bits; // FIXME: We will be expanding this. public: @@ -45,27 +46,6 @@ 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 Attrs; - - AttributeListImpl(ArrayRef attrs) - : Attrs(attrs.begin(), attrs.end()) {} - - void Profile(FoldingSetNodeID &ID) const { - Profile(ID, Attrs); - } - static void Profile(FoldingSetNodeID &ID, ArrayRef 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 #endif diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index d35d2844b8..74247bdde1 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -97,18 +97,11 @@ LLVMContextImpl::~LLVMContextImpl() { // Destroy attributes. for (FoldingSetIterator I = AttrsSet.begin(), - E = AttrsSet.end(); I != E; ) { + E = AttrsSet.end(); I != E;) { FoldingSetIterator Elem = I++; delete &*Elem; } - // Destroy attribute lists. - for (FoldingSetIterator I = AttrsLists.begin(), - E = AttrsLists.end(); I != E; ) { - FoldingSetIterator Elem = I++; - delete &*Elem; - } - // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. SmallVector MDNodes; diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index 90cf424a3c..ee31814c05 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -256,8 +256,7 @@ public: FPMapTy FPConstants; FoldingSet AttrsSet; - FoldingSet AttrsLists; - + StringMap MDStringCache; FoldingSet MDNodeSet; -- cgit v1.2.3 From ddf07067bc7ec9897a17352c2db23fb4d1a55db4 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Thu, 22 Nov 2012 00:43:18 +0000 Subject: Merging r168280: into 3.2 release branch. Don't try to calculate the alignment of an unsigned type. Fixes PR14371! git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168480 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp index 4ab5b6e4a0..4d106fc188 100644 --- a/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp +++ b/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp @@ -164,7 +164,8 @@ static unsigned getPointeeAlignment(Value *V, const DataLayout &TD) { return TD.getPreferredAlignment(GV); if (PointerType *PT = dyn_cast(V->getType())) - return TD.getABITypeAlignment(PT->getElementType()); + if (PT->getElementType()->isSized()) + return TD.getABITypeAlignment(PT->getElementType()); return 0; } -- cgit v1.2.3 From d11161f404bf670f4f4b3b993bdad6894fbfd5ba Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Thu, 22 Nov 2012 06:08:33 +0000 Subject: Merging r168354: into 3.2 release branch 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/branches/release_32@168486 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AsmParser/LLParser.cpp | 6 +- lib/Bitcode/Reader/BitcodeReader.cpp | 2 +- lib/Transforms/IPO/ArgumentPromotion.cpp | 8 ++- lib/Transforms/IPO/DeadArgumentElimination.cpp | 6 +- lib/Transforms/InstCombine/InstCombineCalls.cpp | 5 +- lib/Transforms/Utils/BuildLibCalls.cpp | 43 +++++++---- lib/VMCore/Attributes.cpp | 96 ++++--------------------- lib/VMCore/AttributesImpl.h | 24 ++++++- lib/VMCore/LLVMContextImpl.cpp | 9 ++- lib/VMCore/LLVMContextImpl.h | 3 +- 10 files changed, 91 insertions(+), 111 deletions(-) (limited to 'lib') diff --git a/lib/AsmParser/LLParser.cpp b/lib/AsmParser/LLParser.cpp index e8e6e27725..b24291ffb3 100644 --- a/lib/AsmParser/LLParser.cpp +++ b/lib/AsmParser/LLParser.cpp @@ -2794,7 +2794,7 @@ bool LLParser::ParseFunctionHeader(Function *&Fn, bool isDefine) { Attributes::get(RetType->getContext(), FuncAttrs))); - AttrListPtr PAL = AttrListPtr::get(Attrs); + AttrListPtr PAL = AttrListPtr::get(Context, Attrs); if (PAL.getParamAttributes(1).hasAttribute(Attributes::StructRet) && !RetType->isVoidTy()) @@ -3351,7 +3351,7 @@ bool LLParser::ParseInvoke(Instruction *&Inst, PerFunctionState &PFS) { FnAttrs))); // 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); II->setCallingConv(CC); @@ -3753,7 +3753,7 @@ bool LLParser::ParseCall(Instruction *&Inst, PerFunctionState &PFS, FnAttrs))); // Finish off the Attributes and check them - AttrListPtr PAL = AttrListPtr::get(Attrs); + AttrListPtr PAL = AttrListPtr::get(Context, Attrs); CallInst *CI = CallInst::Create(Callee, Args); CI->setTailCall(isTail); diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 279343c48c..4ec9da12dd 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -487,7 +487,7 @@ bool BitcodeReader::ParseAttributeBlock() { Attributes::get(Context, B))); } - MAttributes.push_back(AttrListPtr::get(Attrs)); + MAttributes.push_back(AttrListPtr::get(Context, Attrs)); Attrs.clear(); break; } diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp index 8a0274b5ff..be48b2063f 100644 --- a/lib/Transforms/IPO/ArgumentPromotion.cpp +++ b/lib/Transforms/IPO/ArgumentPromotion.cpp @@ -611,7 +611,7 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, // Recompute the parameter attributes list based on the new arguments for // the function. - NF->setAttributes(AttrListPtr::get(AttributesVec)); + NF->setAttributes(AttrListPtr::get(F->getContext(), AttributesVec)); AttributesVec.clear(); F->getParent()->getFunctionList().insert(F, NF); @@ -731,11 +731,13 @@ CallGraphNode *ArgPromotion::DoPromotion(Function *F, New = InvokeInst::Create(NF, II->getNormalDest(), II->getUnwindDest(), Args, "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setAttributes(AttrListPtr::get(AttributesVec)); + cast(New)->setAttributes(AttrListPtr::get(II->getContext(), + AttributesVec)); } else { New = CallInst::Create(NF, Args, "", Call); cast(New)->setCallingConv(CS.getCallingConv()); - cast(New)->setAttributes(AttrListPtr::get(AttributesVec)); + cast(New)->setAttributes(AttrListPtr::get(New->getContext(), + AttributesVec)); if (cast(Call)->isTailCall()) cast(New)->setTailCall(); } diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp index fc22548db7..4cfd0b235a 100644 --- a/lib/Transforms/IPO/DeadArgumentElimination.cpp +++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp @@ -280,7 +280,7 @@ bool DAE::DeleteDeadVarargs(Function &Fn) { if (FnAttrs.hasAttributes()) AttributesVec.push_back(AttributeWithIndex::get(AttrListPtr::FunctionIndex, FnAttrs)); - PAL = AttrListPtr::get(AttributesVec); + PAL = AttrListPtr::get(Fn.getContext(), AttributesVec); } Instruction *New; @@ -806,7 +806,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { FnAttrs)); // 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. FunctionType *NFTy = FunctionType::get(NRetTy, Params, FTy->isVarArg()); @@ -874,7 +874,7 @@ bool DAE::RemoveDeadStuffFromFunction(Function *F) { FnAttrs)); // Reconstruct the AttributesList based on the vector we constructed. - AttrListPtr NewCallPAL = AttrListPtr::get(AttributesVec); + AttrListPtr NewCallPAL = AttrListPtr::get(F->getContext(), AttributesVec); Instruction *New; if (InvokeInst *II = dyn_cast(Call)) { diff --git a/lib/Transforms/InstCombine/InstCombineCalls.cpp b/lib/Transforms/InstCombine/InstCombineCalls.cpp index 5ad6f9111c..48f270429e 100644 --- a/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1177,7 +1177,8 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) { if (NewRetTy->isVoidTy()) 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; if (InvokeInst *II = dyn_cast(Caller)) { @@ -1355,7 +1356,7 @@ InstCombiner::transformCallThroughTrampoline(CallSite CS, NestF->getType() == PointerType::getUnqual(NewFTy) ? NestF : ConstantExpr::getBitCast(NestF, PointerType::getUnqual(NewFTy)); - const AttrListPtr &NewPAL = AttrListPtr::get(NewAttrs); + const AttrListPtr &NewPAL = AttrListPtr::get(FTy->getContext(), NewAttrs); Instruction *NewCaller; if (InvokeInst *II = dyn_cast(Caller)) { diff --git a/lib/Transforms/Utils/BuildLibCalls.cpp b/lib/Transforms/Utils/BuildLibCalls.cpp index fa2faa2dad..74b2ee10e0 100644 --- a/lib/Transforms/Utils/BuildLibCalls.cpp +++ b/lib/Transforms/Utils/BuildLibCalls.cpp @@ -47,7 +47,9 @@ Value *llvm::EmitStrLen(Value *Ptr, IRBuilder<> &B, const DataLayout *TD, ArrayRef(AVs, 2)); 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), B.getInt8PtrTy(), NULL); @@ -74,7 +76,9 @@ Value *llvm::EmitStrNLen(Value *Ptr, Value *MaxLen, IRBuilder<> &B, ArrayRef(AVs, 2)); 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), B.getInt8PtrTy(), TD->getIntPtrType(Context), @@ -102,7 +106,9 @@ Value *llvm::EmitStrChr(Value *Ptr, char C, IRBuilder<> &B, Type *I8Ptr = B.getInt8PtrTy(); 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); CallInst *CI = B.CreateCall2(StrChr, CastToCStr(Ptr, B), ConstantInt::get(I32Ty, C), "strchr"); @@ -127,7 +133,9 @@ Value *llvm::EmitStrNCmp(Value *Ptr1, Value *Ptr2, Value *Len, ArrayRef(AVs, 2)); 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.getInt8PtrTy(), B.getInt8PtrTy(), @@ -155,7 +163,8 @@ Value *llvm::EmitStrCpy(Value *Dst, Value *Src, IRBuilder<> &B, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); 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); CallInst *CI = B.CreateCall2(StrCpy, CastToCStr(Dst, B), CastToCStr(Src, B), Name); @@ -178,7 +187,9 @@ Value *llvm::EmitStrNCpy(Value *Dst, Value *Src, Value *Len, AWI[1] = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, Attributes::NoUnwind); 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, Len->getType(), NULL); 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); LLVMContext &Context = B.GetInsertBlock()->getContext(); Value *MemCpy = M->getOrInsertFunction("__memcpy_chk", - AttrListPtr::get(AWI), + AttrListPtr::get(M->getContext(), AWI), B.getInt8PtrTy(), B.getInt8PtrTy(), B.getInt8PtrTy(), @@ -231,7 +242,8 @@ Value *llvm::EmitMemChr(Value *Ptr, Value *Val, AWI = AttributeWithIndex::get(M->getContext(), AttrListPtr::FunctionIndex, ArrayRef(AVs, 2)); 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.getInt32Ty(), @@ -261,7 +273,8 @@ Value *llvm::EmitMemCmp(Value *Ptr1, Value *Ptr2, ArrayRef(AVs, 2)); 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.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, Attributes::NoUnwind); - Value *PutS = M->getOrInsertFunction("puts", AttrListPtr::get(AWI), + Value *PutS = M->getOrInsertFunction("puts", + AttrListPtr::get(M->getContext(), AWI), B.getInt32Ty(), B.getInt8PtrTy(), NULL); @@ -362,7 +376,8 @@ Value *llvm::EmitFPutC(Value *Char, Value *File, IRBuilder<> &B, Attributes::NoUnwind); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction("fputc", AttrListPtr::get(AWI), + F = M->getOrInsertFunction("fputc", + AttrListPtr::get(M->getContext(), AWI), B.getInt32Ty(), B.getInt32Ty(), File->getType(), NULL); @@ -396,7 +411,8 @@ Value *llvm::EmitFPutS(Value *Str, Value *File, IRBuilder<> &B, StringRef FPutsName = TLI->getName(LibFunc::fputs); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction(FPutsName, AttrListPtr::get(AWI), + F = M->getOrInsertFunction(FPutsName, + AttrListPtr::get(M->getContext(), AWI), B.getInt32Ty(), B.getInt8PtrTy(), File->getType(), NULL); @@ -429,7 +445,8 @@ Value *llvm::EmitFWrite(Value *Ptr, Value *Size, Value *File, StringRef FWriteName = TLI->getName(LibFunc::fwrite); Constant *F; if (File->getType()->isPointerTy()) - F = M->getOrInsertFunction(FWriteName, AttrListPtr::get(AWI), + F = M->getOrInsertFunction(FWriteName, + AttrListPtr::get(M->getContext(), AWI), TD->getIntPtrType(Context), B.getInt8PtrTy(), TD->getIntPtrType(Context), diff --git a/lib/VMCore/Attributes.cpp b/lib/VMCore/Attributes.cpp index 5a552c34e1..f1268e6ef8 100644 --- a/lib/VMCore/Attributes.cpp +++ b/lib/VMCore/Attributes.cpp @@ -355,62 +355,8 @@ uint64_t AttributesImpl::getStackAlignment() const { // AttributeListImpl Definition //===----------------------------------------------------------------------===// -namespace llvm { - class AttributeListImpl; -} - -static ManagedStatic > AttributesLists; - -namespace llvm { -static ManagedStatic > 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 Attrs; - - AttributeListImpl(ArrayRef attrs) - : Attrs(attrs.begin(), attrs.end()) { - RefCount = 0; - } - - void AddRef() { - sys::SmartScopedLock Lock(*ALMutex); - ++RefCount; - } - void DropRef() { - sys::SmartScopedLock 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 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 Attrs) { +AttrListPtr AttrListPtr::get(LLVMContext &C, + ArrayRef Attrs) { // If there are no attributes then return a null AttributesList pointer. if (Attrs.empty()) return AttrListPtr(); @@ -425,51 +371,36 @@ AttrListPtr AttrListPtr::get(ArrayRef Attrs) { #endif // Otherwise, build a key to look up the existing attributes. + LLVMContextImpl *pImpl = C.pImpl; FoldingSetNodeID ID; AttributeListImpl::Profile(ID, Attrs); - void *InsertPos; - - sys::SmartScopedLock Lock(*ALMutex); - AttributeListImpl *PAL = - AttributesLists->FindNodeOrInsertPos(ID, InsertPos); + void *InsertPoint; + AttributeListImpl *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. - if (!PAL) { - PAL = new AttributeListImpl(Attrs); - AttributesLists->InsertNode(PAL, InsertPos); + if (!PA) { + PA = new AttributeListImpl(Attrs); + pImpl->AttrsLists.InsertNode(PA, InsertPoint); } // Return the AttributesList that we found or created. - return AttrListPtr(PAL); + return AttrListPtr(PA); } //===----------------------------------------------------------------------===// // 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) { - sys::SmartScopedLock Lock(*ALMutex); if (AttrList == RHS.AttrList) return *this; - if (AttrList) AttrList->DropRef(); + AttrList = RHS.AttrList; - if (AttrList) AttrList->AddRef(); return *this; } -AttrListPtr::~AttrListPtr() { - if (AttrList) AttrList->DropRef(); -} - /// getNumSlots - Return the number of slots used in this attribute list. /// This is the number of arguments that have an attribute set on them /// (including the function itself). @@ -507,6 +438,7 @@ bool AttrListPtr::hasAttrSomewhere(Attributes::AttrVal Attr) const { for (unsigned i = 0, e = Attrs.size(); i != e; ++i) if (Attrs[i].Attrs.hasAttribute(Attr)) return true; + return false; } @@ -562,7 +494,7 @@ AttrListPtr AttrListPtr::addAttr(LLVMContext &C, unsigned Idx, OldAttrList.begin()+i, OldAttrList.end()); } - return get(NewAttrList); + return get(C, NewAttrList); } AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx, @@ -601,7 +533,7 @@ AttrListPtr AttrListPtr::removeAttr(LLVMContext &C, unsigned Idx, NewAttrList.insert(NewAttrList.end(), OldAttrList.begin()+i, OldAttrList.end()); - return get(NewAttrList); + return get(C, NewAttrList); } void AttrListPtr::dump() const { diff --git a/lib/VMCore/AttributesImpl.h b/lib/VMCore/AttributesImpl.h index b4a0f615f3..5c107e1ebb 100644 --- a/lib/VMCore/AttributesImpl.h +++ b/lib/VMCore/AttributesImpl.h @@ -15,12 +15,11 @@ #ifndef LLVM_ATTRIBUTESIMPL_H #define LLVM_ATTRIBUTESIMPL_H +#include "llvm/Attributes.h" #include "llvm/ADT/FoldingSet.h" namespace llvm { -class Attributes; - class AttributesImpl : public FoldingSetNode { uint64_t Bits; // FIXME: We will be expanding this. 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 Attrs; + + AttributeListImpl(ArrayRef attrs) + : Attrs(attrs.begin(), attrs.end()) {} + + void Profile(FoldingSetNodeID &ID) const { + Profile(ID, Attrs); + } + static void Profile(FoldingSetNodeID &ID, ArrayRef 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 #endif diff --git a/lib/VMCore/LLVMContextImpl.cpp b/lib/VMCore/LLVMContextImpl.cpp index 74247bdde1..d35d2844b8 100644 --- a/lib/VMCore/LLVMContextImpl.cpp +++ b/lib/VMCore/LLVMContextImpl.cpp @@ -97,11 +97,18 @@ LLVMContextImpl::~LLVMContextImpl() { // Destroy attributes. for (FoldingSetIterator I = AttrsSet.begin(), - E = AttrsSet.end(); I != E;) { + E = AttrsSet.end(); I != E; ) { FoldingSetIterator Elem = I++; delete &*Elem; } + // Destroy attribute lists. + for (FoldingSetIterator I = AttrsLists.begin(), + E = AttrsLists.end(); I != E; ) { + FoldingSetIterator Elem = I++; + delete &*Elem; + } + // Destroy MDNodes. ~MDNode can move and remove nodes between the MDNodeSet // and the NonUniquedMDNodes sets, so copy the values out first. SmallVector MDNodes; diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index ee31814c05..90cf424a3c 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -256,7 +256,8 @@ public: FPMapTy FPConstants; FoldingSet AttrsSet; - + FoldingSet AttrsLists; + StringMap MDStringCache; FoldingSet MDNodeSet; -- cgit v1.2.3 From df46b9004b0ac81d6cd37a644e5c8243af0afc61 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Thu, 22 Nov 2012 06:21:31 +0000 Subject: Merging r168291: into the 3.2 release branch. Fix PR14060, an infinite loop in reassociate. The problem was that one of the operands of the expression being written was wrongly thought to be reusable as an inner node of the expression resulting in it turning up as both an inner node *and* a leaf, creating a cycle in the def-use graph. This would have caused the verifier to blow up if things had gotten that far, however it managed to provoke an infinite loop first. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168489 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Transforms/Scalar/Reassociate.cpp | 30 ++++++++++++++++++++++++------ 1 file changed, 24 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/Transforms/Scalar/Reassociate.cpp b/lib/Transforms/Scalar/Reassociate.cpp index f19b7fec0a..7a4079784b 100644 --- a/lib/Transforms/Scalar/Reassociate.cpp +++ b/lib/Transforms/Scalar/Reassociate.cpp @@ -606,8 +606,8 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, SmallVectorImpl &Ops) { assert(Ops.size() > 1 && "Single values should be used directly!"); - // Since our optimizations never increase the number of operations, the new - // expression can always be written by reusing the existing binary operators + // Since our optimizations should never increase the number of operations, the + // new expression can usually be written reusing the existing binary operators // from the original expression tree, without creating any new instructions, // though the rewritten expression may have a completely different topology. // We take care to not change anything if the new expression will be the same @@ -621,6 +621,20 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, unsigned Opcode = I->getOpcode(); BinaryOperator *Op = I; + /// NotRewritable - The operands being written will be the leaves of the new + /// expression and must not be used as inner nodes (via NodesToRewrite) by + /// mistake. Inner nodes are always reassociable, and usually leaves are not + /// (if they were they would have been incorporated into the expression and so + /// would not be leaves), so most of the time there is no danger of this. But + /// in rare cases a leaf may become reassociable if an optimization kills uses + /// of it, or it may momentarily become reassociable during rewriting (below) + /// due it being removed as an operand of one of its uses. Ensure that misuse + /// of leaf nodes as inner nodes cannot occur by remembering all of the future + /// leaves and refusing to reuse any of them as inner nodes. + SmallPtrSet NotRewritable; + for (unsigned i = 0, e = Ops.size(); i != e; ++i) + NotRewritable.insert(Ops[i].Op); + // ExpressionChanged - Non-null if the rewritten expression differs from the // original in some non-trivial way, requiring the clearing of optional flags. // Flags are cleared from the operator in ExpressionChanged up to I inclusive. @@ -653,12 +667,14 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, // the old operands with the new ones. DEBUG(dbgs() << "RA: " << *Op << '\n'); if (NewLHS != OldLHS) { - if (BinaryOperator *BO = isReassociableOp(OldLHS, Opcode)) + BinaryOperator *BO = isReassociableOp(OldLHS, Opcode); + if (BO && !NotRewritable.count(BO)) NodesToRewrite.push_back(BO); Op->setOperand(0, NewLHS); } if (NewRHS != OldRHS) { - if (BinaryOperator *BO = isReassociableOp(OldRHS, Opcode)) + BinaryOperator *BO = isReassociableOp(OldRHS, Opcode); + if (BO && !NotRewritable.count(BO)) NodesToRewrite.push_back(BO); Op->setOperand(1, NewRHS); } @@ -682,7 +698,8 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, Op->swapOperands(); } else { // Overwrite with the new right-hand side. - if (BinaryOperator *BO = isReassociableOp(Op->getOperand(1), Opcode)) + BinaryOperator *BO = isReassociableOp(Op->getOperand(1), Opcode); + if (BO && !NotRewritable.count(BO)) NodesToRewrite.push_back(BO); Op->setOperand(1, NewRHS); ExpressionChanged = Op; @@ -695,7 +712,8 @@ void Reassociate::RewriteExprTree(BinaryOperator *I, // Now deal with the left-hand side. If this is already an operation node // from the original expression then just rewrite the rest of the expression // into it. - if (BinaryOperator *BO = isReassociableOp(Op->getOperand(0), Opcode)) { + BinaryOperator *BO = isReassociableOp(Op->getOperand(0), Opcode); + if (BO && !NotRewritable.count(BO)) { Op = BO; continue; } -- cgit v1.2.3 From 024e48b43d3fbafe24b0205fb8b94015d43ff3a6 Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Fri, 23 Nov 2012 19:56:57 +0000 Subject: Merging r168512: into 3.2 release branch. Update call to the new syntax. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168526 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/CppBackend/CPPBackend.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/Target/CppBackend/CPPBackend.cpp b/lib/Target/CppBackend/CPPBackend.cpp index 0f3efd8345..5c909903f9 100644 --- a/lib/Target/CppBackend/CPPBackend.cpp +++ b/lib/Target/CppBackend/CPPBackend.cpp @@ -518,7 +518,7 @@ void CppWriter::printAttributes(const AttrListPtr &PAL, Out << "Attrs.push_back(PAWI);"; nl(Out); } - Out << name << "_PAL = AttrListPtr::get(Attrs);"; + Out << name << "_PAL = AttrListPtr::get(mod->getContext(), Attrs);"; nl(Out); out(); nl(Out); Out << '}'; nl(Out); -- cgit v1.2.3 From 12c349d44181f8083ee9120ddd3b2664c0a1fe8f Mon Sep 17 00:00:00 2001 From: Pawel Wodnicki Date: Fri, 23 Nov 2012 20:02:28 +0000 Subject: Merging r168320: into 3.2 relase branch. Handle mixed normal and early-clobber defs on inline asm. PR14376. git-svn-id: https://llvm.org/svn/llvm-project/llvm/branches/release_32@168527 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/CodeGen/LiveInterval.cpp | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/CodeGen/LiveInterval.cpp b/lib/CodeGen/LiveInterval.cpp index c3bf2d234c..8585cbb30d 100644 --- a/lib/CodeGen/LiveInterval.cpp +++ b/lib/CodeGen/LiveInterval.cpp @@ -59,8 +59,16 @@ VNInfo *LiveInterval::createDeadDef(SlotIndex Def, return VNI; } if (SlotIndex::isSameInstr(Def, I->start)) { - assert(I->start == Def && "Cannot insert def, already live"); - assert(I->valno->def == Def && "Inconsistent existing value def"); + assert(I->valno->def == I->start && "Inconsistent existing value def"); + + // It is possible to have both normal and early-clobber defs of the same + // register on an instruction. It doesn't make a lot of sense, but it is + // possible to specify in inline assembly. + // + // Just convert everything to early-clobber. + Def = std::min(Def, I->start); + if (Def != I->start) + I->start = I->valno->def = Def; return I->valno; } assert(SlotIndex::isEarlierInstr(Def, I->start) && "Already live at def"); -- cgit v1.2.3