aboutsummaryrefslogtreecommitdiff
path: root/lib/CodeGen/CGObjC.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2008-08-31 04:05:03 +0000
committerAnders Carlsson <andersca@mac.com>2008-08-31 04:05:03 +0000
commit2abd89c039e835e84519a4cd8a7495899a70153d (patch)
treed0f14f41d42c5eb75f43e04428bf5d37d56d0c24 /lib/CodeGen/CGObjC.cpp
parentf484c31f4d6934f56070c2942d4dfdf3fee84074 (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.cpp55
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);