[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