[cfe-commits] r55583 - in /cfe/trunk/lib/CodeGen: CGObjC.cpp CGObjCGNU.cpp CGObjCMac.cpp CGObjCRuntime.h
Anders Carlsson
andersca at mac.com
Sat Aug 30 21:05:05 PDT 2008
Author: andersca
Date: Sat Aug 30 23:05:03 2008
New Revision: 55583
URL: http://llvm.org/viewvc/llvm-project?rev=55583&view=rev
Log:
Handle mutation while enumerating correctly. Fix some bugs.
Modified:
cfe/trunk/lib/CodeGen/CGObjC.cpp
cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
cfe/trunk/lib/CodeGen/CGObjCMac.cpp
cfe/trunk/lib/CodeGen/CGObjCRuntime.h
Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=55583&r1=55582&r2=55583&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Sat Aug 30 23:05:03 2008
@@ -281,10 +281,10 @@
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 @@
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 @@
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);
Modified: cfe/trunk/lib/CodeGen/CGObjCGNU.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCGNU.cpp?rev=55583&r1=55582&r2=55583&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCGNU.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCGNU.cpp Sat Aug 30 23:05:03 2008
@@ -120,6 +120,7 @@
const ObjCProtocolDecl *PD);
virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
virtual llvm::Function *ModuleInitFunction();
+ virtual llvm::Function *EnumerationMutationFunction();
};
} // end anonymous namespace
@@ -958,6 +959,13 @@
return Method;
}
+llvm::Function *CGObjCGNU::EnumerationMutationFunction()
+{
+ assert(0 && "No enumeration mutation function in the GNU runtime!");
+
+ return 0;
+}
+
CodeGen::CGObjCRuntime *CodeGen::CreateGNUObjCRuntime(CodeGen::CodeGenModule &CGM){
return new CGObjCGNU(CGM);
}
Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=55583&r1=55582&r2=55583&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Sat Aug 30 23:05:03 2008
@@ -130,6 +130,7 @@
/// MethodListPtrTy - LLVM type for struct objc_method_list *.
const llvm::Type *MethodListPtrTy;
+ llvm::Function *EnumerationMutationFn;
public:
ObjCTypesHelper(CodeGen::CodeGenModule &cgm);
~ObjCTypesHelper();
@@ -370,6 +371,7 @@
virtual void GenerateProtocol(const ObjCProtocolDecl *PD);
virtual llvm::Function *ModuleInitFunction();
+ virtual llvm::Function *EnumerationMutationFunction();
};
} // end anonymous namespace
@@ -1379,6 +1381,11 @@
return NULL;
}
+llvm::Function *CGObjCMac::EnumerationMutationFunction()
+{
+ return ObjCTypes.EnumerationMutationFn;
+}
+
/* *** Private Interface *** */
/// EmitImageInfo - Emit the image info marker used to encode some module
@@ -1934,6 +1941,18 @@
llvm::Function::ExternalLinkage,
"objc_msgSendSuper_stret",
&CGM.getModule());
+
+ // Enumeration mutation.
+
+ Params.clear();
+ Params.push_back(ObjectPtrTy);
+ EnumerationMutationFn =
+ llvm::Function::Create(llvm::FunctionType::get(llvm::Type::VoidTy,
+ Params,
+ false),
+ llvm::Function::ExternalLinkage,
+ "objc_enumerationMutation",
+ &CGM.getModule());
}
ObjCTypesHelper::~ObjCTypesHelper() {
Modified: cfe/trunk/lib/CodeGen/CGObjCRuntime.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCRuntime.h?rev=55583&r1=55582&r2=55583&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCRuntime.h (original)
+++ cfe/trunk/lib/CodeGen/CGObjCRuntime.h Sat Aug 30 23:05:03 2008
@@ -122,6 +122,10 @@
virtual llvm::Value *GetClass(BuilderType &Builder,
const ObjCInterfaceDecl *OID) = 0;
+ /// EnumerationMutationFunction - Return the function that's called by the
+ /// compiler when a mutation is detected during foreach iteration.
+ virtual llvm::Function *EnumerationMutationFunction() = 0;
+
/// If instance variable addresses are determined at runtime then this should
/// return true, otherwise instance variables will be accessed directly from
/// the structure. If this returns true then @defs is invalid for this
More information about the cfe-commits
mailing list