diff options
author | Anders Carlsson <andersca@mac.com> | 2008-08-31 04:05:03 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2008-08-31 04:05:03 +0000 |
commit | 2abd89c039e835e84519a4cd8a7495899a70153d (patch) | |
tree | d0f14f41d42c5eb75f43e04428bf5d37d56d0c24 /lib/CodeGen/CGObjC.cpp | |
parent | f484c31f4d6934f56070c2942d4dfdf3fee84074 (diff) |
Handle mutation while enumerating correctly. Fix some bugs.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@55583 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CGObjC.cpp')
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 55 |
1 files changed, 48 insertions, 7 deletions
diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index 26f678cc4e..5376d0f3c7 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -281,10 +281,10 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) llvm::AllocaInst *StatePtr = CreateTempAlloca(ConvertType(StateTy), "state.ptr"); StatePtr->setAlignment(getContext().getTypeAlign(StateTy) >> 3); - EmitMemSetToZero(StatePtr,StateTy); + EmitMemSetToZero(StatePtr, StateTy); // Number of elements in the items array. - static const unsigned NumItems = 2; + static const unsigned NumItems = 16; // Get selector llvm::SmallVector<IdentifierInfo*, 3> II; @@ -323,23 +323,64 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) Builder.CreateStore(CountRV.getScalarVal(), LimitPtr); llvm::BasicBlock *NoElements = llvm::BasicBlock::Create("noelements"); - llvm::BasicBlock *LoopStart = llvm::BasicBlock::Create("loopstart"); + llvm::BasicBlock *SetStartMutations = + llvm::BasicBlock::Create("setstartmutations"); llvm::Value *Limit = Builder.CreateLoad(LimitPtr); llvm::Value *Zero = llvm::Constant::getNullValue(UnsignedLongLTy); llvm::Value *IsZero = Builder.CreateICmpEQ(Limit, Zero, "iszero"); - Builder.CreateCondBr(IsZero, NoElements, LoopStart); + Builder.CreateCondBr(IsZero, NoElements, SetStartMutations); + EmitBlock(SetStartMutations); + + llvm::Value *StartMutationsPtr = + CreateTempAlloca(UnsignedLongLTy); + + llvm::Value *StateMutationsPtrPtr = + Builder.CreateStructGEP(StatePtr, 2, "mutationsptr.ptr"); + llvm::Value *StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, + "mutationsptr"); + + llvm::Value *StateMutations = Builder.CreateLoad(StateMutationsPtr, + "mutations"); + + Builder.CreateStore(StateMutations, StartMutationsPtr); + + llvm::BasicBlock *LoopStart = llvm::BasicBlock::Create("loopstart"); EmitBlock(LoopStart); - llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("loopbody"); - llvm::Value *CounterPtr = CreateTempAlloca(UnsignedLongLTy, "counter.ptr"); Builder.CreateStore(Zero, CounterPtr); + llvm::BasicBlock *LoopBody = llvm::BasicBlock::Create("loopbody"); EmitBlock(LoopBody); + StateMutationsPtr = Builder.CreateLoad(StateMutationsPtrPtr, "mutationsptr"); + StateMutations = Builder.CreateLoad(StateMutationsPtr, "statemutations"); + + llvm::Value *StartMutations = Builder.CreateLoad(StartMutationsPtr, + "mutations"); + llvm::Value *MutationsEqual = Builder.CreateICmpEQ(StateMutations, + StartMutations, + "tobool"); + + + llvm::BasicBlock *WasMutated = llvm::BasicBlock::Create("wasmutated"); + llvm::BasicBlock *WasNotMutated = llvm::BasicBlock::Create("wasnotmutated"); + + Builder.CreateCondBr(MutationsEqual, WasNotMutated, WasMutated); + + EmitBlock(WasMutated); + llvm::Value *V = + Builder.CreateBitCast(Collection, + ConvertType(getContext().getObjCIdType()), + "tmp"); + Builder.CreateCall(CGM.getObjCRuntime().EnumerationMutationFunction(), + V); + + EmitBlock(WasNotMutated); + llvm::Value *StateItemsPtr = Builder.CreateStructGEP(StatePtr, 1, "stateitems.ptr"); @@ -384,7 +425,7 @@ void CodeGenFunction::EmitObjCForCollectionStmt(const ObjCForCollectionStmt &S) llvm::BasicBlock *FetchMore = llvm::BasicBlock::Create("fetchmore"); llvm::Value *IsLess = Builder.CreateICmpULT(Counter, Limit, "isless"); - Builder.CreateCondBr(IsLess, LoopBody, FetchMore); + Builder.CreateCondBr(IsLess, LoopStart, FetchMore); // Fetch more elements. EmitBlock(FetchMore); |