]> granicus.if.org Git - clang/commitdiff
Re-implemented generation of objc_memmove_collectable
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 31 Aug 2009 19:33:16 +0000 (19:33 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 31 Aug 2009 19:33:16 +0000 (19:33 +0000)
API for copying GC'able aggregates (Next runtime only).

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@80607 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGExprAgg.cpp
lib/CodeGen/CGObjCGNU.cpp
lib/CodeGen/CGObjCMac.cpp
lib/CodeGen/CGObjCRuntime.h
lib/CodeGen/CodeGenFunction.h
test/CodeGenObjC/objc-gc-aggr-assign.m

index 4155738a22f01cee3fe15607cd91a5b3a0e1b528..f8e9c56b1825d2bca6fde316f883ef17ed35915f 100644 (file)
@@ -37,12 +37,13 @@ class VISIBILITY_HIDDEN AggExprEmitter : public StmtVisitor<AggExprEmitter> {
   bool VolatileDest;
   bool IgnoreResult;
   bool IsInitializer;
+  bool RequiresGCollection;
 public:
   AggExprEmitter(CodeGenFunction &cgf, llvm::Value *destPtr, bool v,
-                 bool ignore, bool isinit)
+                 bool ignore, bool isinit, bool requiresGCollection)
     : CGF(cgf), Builder(CGF.Builder),
       DestPtr(destPtr), VolatileDest(v), IgnoreResult(ignore),
-      IsInitializer(isinit) {
+      IsInitializer(isinit), RequiresGCollection(requiresGCollection) {
   }
 
   //===--------------------------------------------------------------------===//
@@ -145,6 +146,12 @@ void AggExprEmitter::EmitFinalDestCopy(const Expr *E, RValue Src, bool Ignore) {
     DestPtr = CGF.CreateTempAlloca(CGF.ConvertType(E->getType()), "agg.tmp");
   }
 
+  if (RequiresGCollection) {
+    CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF,
+                                              DestPtr, Src.getAggregateAddr(),
+                                              E->getType());
+    return;
+  }
   // If the result of the assignment is used, copy the LHS there also.
   // FIXME: Pass VolatileDest as well.  I think we also need to merge volatile
   // from the source as well, as we can't eliminate it if either operand
@@ -262,19 +269,15 @@ void AggExprEmitter::VisitBinAssign(const BinaryOperator *E) {
     CGF.EmitObjCPropertySet(LHS.getKVCRefExpr(), 
                             RValue::getAggregate(AggLoc, VolatileDest));
   } else {
+    bool RequiresGCollection = false;
     if (CGF.getContext().getLangOptions().NeXTRuntime) {
       QualType LHSTy = E->getLHS()->getType();
       if (const RecordType *FDTTy = LHSTy.getTypePtr()->getAs<RecordType>())
-        if (FDTTy->getDecl()->hasObjectMember()) {
-          LValue RHS = CGF.EmitLValue(E->getRHS());
-          CGF.CGM.getObjCRuntime().EmitGCMemmoveCollectable(CGF, LHS.getAddress(), 
-                                      RHS.getAddress(),
-                                      CGF.getContext().getTypeSize(LHSTy) / 8);
-          return;
-        }
+        RequiresGCollection = FDTTy->getDecl()->hasObjectMember(); 
     }
     // Codegen the RHS so that it stores directly into the LHS.
-    CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified());
+    CGF.EmitAggExpr(E->getRHS(), LHS.getAddress(), LHS.isVolatileQualified(),
+                    false, false, RequiresGCollection);
     EmitFinalDestCopy(E, LHS, true);
   }
 }
@@ -525,13 +528,15 @@ void AggExprEmitter::VisitInitListExpr(InitListExpr *E) {
 /// true, DestPtr cannot be 0.
 void CodeGenFunction::EmitAggExpr(const Expr *E, llvm::Value *DestPtr,
                                   bool VolatileDest, bool IgnoreResult,
-                                  bool IsInitializer) {
+                                  bool IsInitializer, 
+                                  bool RequiresGCollection) {
   assert(E && hasAggregateLLVMType(E->getType()) &&
          "Invalid aggregate expression to emit");
   assert ((DestPtr != 0 || VolatileDest == false)
           && "volatile aggregate can't be 0");
   
-  AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer)
+  AggExprEmitter(*this, DestPtr, VolatileDest, IgnoreResult, IsInitializer,
+                 RequiresGCollection)
     .Visit(const_cast<Expr*>(E));
 }
 
index 6ed13a444f86539074ddbf6b002e05514320c1b6..63d45e9bd7b2b9a33c60aea48bc6eb3ecde20b49 100644 (file)
@@ -162,7 +162,7 @@ public:
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *DestPtr, 
                                         llvm::Value *SrcPtr,
-                                        unsigned long size);
+                                        QualType Ty);
   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
                                       QualType ObjectTy,
                                       llvm::Value *BaseValue,
@@ -1598,7 +1598,7 @@ void CGObjCGNU::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
 void CGObjCGNU::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                          llvm::Value *DestPtr, 
                                          llvm::Value *SrcPtr,
-                                         unsigned long size) {
+                                         QualType Ty) {
   return;
 }
 
index e16c3ee2582ed669e306c2539571f13e19b4f673..26bc976a86c1a5a78d6b20ed4aecd4990aab915f 100644 (file)
@@ -1130,7 +1130,7 @@ public:
                                         llvm::Value *src, llvm::Value *dest);
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *dest, llvm::Value *src,
-                                        unsigned long size);
+                                        QualType Ty);
 
   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
                                       QualType ObjectTy,
@@ -1359,7 +1359,7 @@ public:
                                         llvm::Value *src, llvm::Value *dest);
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *dest, llvm::Value *src,
-                                        unsigned long size);
+                                        QualType Ty);
   virtual LValue EmitObjCValueForIvar(CodeGen::CodeGenFunction &CGF,
                                       QualType ObjectTy,
                                       llvm::Value *BaseValue,
@@ -2786,7 +2786,10 @@ void CGObjCMac::EmitObjCStrongCastAssign(CodeGen::CodeGenFunction &CGF,
 void CGObjCMac::EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                          llvm::Value *DestPtr,
                                          llvm::Value *SrcPtr,
-                                         unsigned long size) {
+                                         QualType Ty) {
+  // Get size info for this aggregate.
+  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
+  unsigned long size = TypeInfo.second/8;
   SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
   DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
   llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size);
@@ -5315,7 +5318,10 @@ void CGObjCNonFragileABIMac::EmitGCMemmoveCollectable(
   CodeGen::CodeGenFunction &CGF,
   llvm::Value *DestPtr,
   llvm::Value *SrcPtr,
-  unsigned long size) {
+  QualType Ty) {
+  // Get size info for this aggregate.
+  std::pair<uint64_t, unsigned> TypeInfo = CGM.getContext().getTypeInfo(Ty);
+  unsigned long size = TypeInfo.second/8;
   SrcPtr = CGF.Builder.CreateBitCast(SrcPtr, ObjCTypes.Int8PtrTy);
   DestPtr = CGF.Builder.CreateBitCast(DestPtr, ObjCTypes.Int8PtrTy);
   llvm::Value *N = llvm::ConstantInt::get(ObjCTypes.LongTy, size);
index ec72bcd599999248ac06f5f81329e9688415cf4a..d82df9d881d71adaa197f62875f76728e1addf74 100644 (file)
@@ -197,7 +197,7 @@ public:
   virtual void EmitGCMemmoveCollectable(CodeGen::CodeGenFunction &CGF,
                                         llvm::Value *DestPtr, 
                                         llvm::Value *SrcPtr,
-                                        unsigned long) = 0;
+                                        QualType Ty) = 0;
 };
 
 /// Creates an instance of an Objective-C runtime class.  
index 2815939517b8baa064d4a1b92618cdc3beb509e2..046a619e8a7b432f726b86aaaef2c10fe21ac029 100644 (file)
@@ -897,12 +897,13 @@ public:
   /// aggregate type.  The result is computed into DestPtr.  Note that if
   /// DestPtr is null, the value of the aggregate expression is not needed.
   void EmitAggExpr(const Expr *E, llvm::Value *DestPtr, bool VolatileDest,
-                   bool IgnoreResult = false, bool IsInitializer = false);
+                   bool IgnoreResult = false, bool IsInitializer = false,
+                   bool RequiresGCollection = false);
 
   /// EmitGCMemmoveCollectable - Emit special API for structs with object
   /// pointers.
   void EmitGCMemmoveCollectable(llvm::Value *DestPtr, llvm::Value *SrcPtr,
-                                unsigned long);
+                                QualType Ty);
 
   /// EmitComplexExpr - Emit the computation of the specified expression of
   /// complex type, returning the result.
index b6b08ffefdb79f690203ced617ca36a462365fed..96a9fdf6540914b3774739cc3f30f9b924b7ae6e 100644 (file)
@@ -1,5 +1,5 @@
 // RUN: clang-cc -fnext-runtime -fobjc-gc -emit-llvm -o %t %s &&
-// RUN: grep objc_memmove_collectable %t | grep call | count 2
+// RUN: grep objc_memmove_collectable %t | grep call | count 3
 
 static int count;
 
@@ -40,3 +40,7 @@ struct type_s get(void)
   return some;
 }
 
+void f(const struct type_s *in, struct type_s *out) {
+  *out = *in;
+}
+