[cfe-commits] r91247 - in /cfe/trunk/lib/CodeGen: CGCXX.cpp CGExprCXX.cpp

Anders Carlsson andersca at mac.com
Sun Dec 13 12:04:39 PST 2009


Author: andersca
Date: Sun Dec 13 14:04:38 2009
New Revision: 91247

URL: http://llvm.org/viewvc/llvm-project?rev=91247&view=rev
Log:
More array cookie improvements.

Modified:
    cfe/trunk/lib/CodeGen/CGCXX.cpp
    cfe/trunk/lib/CodeGen/CGExprCXX.cpp

Modified: cfe/trunk/lib/CodeGen/CGCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCXX.cpp?rev=91247&r1=91246&r2=91247&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCXX.cpp Sun Dec 13 14:04:38 2009
@@ -397,8 +397,9 @@
   const ConstantArrayType *CA = dyn_cast<ConstantArrayType>(Array);
   assert(CA && "Do we support VLA for destruction ?");
   uint64_t ElementCount = getContext().getConstantArrayElementCount(CA);
-  llvm::Value* ElementCountPtr =
-    llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext), ElementCount);
+  
+  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
+  llvm::Value* ElementCountPtr = llvm::ConstantInt::get(SizeLTy, ElementCount);
   EmitCXXAggrDestructorCall(D, ElementCountPtr, This);
 }
 
@@ -408,13 +409,14 @@
 CodeGenFunction::EmitCXXAggrDestructorCall(const CXXDestructorDecl *D,
                                            llvm::Value *UpperCount,
                                            llvm::Value *This) {
-  llvm::Value *One = llvm::ConstantInt::get(llvm::Type::getInt64Ty(VMContext),
-                                            1);
+  const llvm::Type *SizeLTy = ConvertType(getContext().getSizeType());
+  llvm::Value *One = llvm::ConstantInt::get(SizeLTy, 1);
+  
   // Create a temporary for the loop index and initialize it with count of
   // array elements.
-  llvm::Value *IndexPtr = CreateTempAlloca(llvm::Type::getInt64Ty(VMContext),
-                                           "loop.index");
-  // Index = ElementCount;
+  llvm::Value *IndexPtr = CreateTempAlloca(SizeLTy, "loop.index");
+
+  // Store the number of elements in the index pointer.
   Builder.CreateStore(UpperCount, IndexPtr);
 
   // Start the loop with a block that tests the condition.
@@ -428,7 +430,7 @@
   // Generate: if (loop-index != 0 fall to the loop body,
   // otherwise, go to the block after the for-loop.
   llvm::Value* zeroConstant =
-    llvm::Constant::getNullValue(llvm::Type::getInt64Ty(VMContext));
+    llvm::Constant::getNullValue(SizeLTy);
   llvm::Value *Counter = Builder.CreateLoad(IndexPtr);
   llvm::Value *IsNE = Builder.CreateICmpNE(Counter, zeroConstant,
                                             "isne");

Modified: cfe/trunk/lib/CodeGen/CGExprCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExprCXX.cpp?rev=91247&r1=91246&r2=91247&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGExprCXX.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExprCXX.cpp Sun Dec 13 14:04:38 2009
@@ -15,13 +15,8 @@
 using namespace clang;
 using namespace CodeGen;
 
-static uint64_t CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
-  if (!E->isArray())
-    return 0;
-  
-  QualType T = E->getAllocatedType();
-  
-  const RecordType *RT = T->getAs<RecordType>();
+static uint64_t CalculateCookiePadding(ASTContext &Ctx, QualType ElementType) {
+  const RecordType *RT = ElementType->getAs<RecordType>();
   if (!RT)
     return 0;
   
@@ -31,13 +26,38 @@
   
   // Check if the class has a trivial destructor.
   if (RD->hasTrivialDestructor()) {
-    // FIXME: Check for a two-argument delete.
-    return 0;
+    // Check if the usual deallocation function takes two arguments.
+    DeclarationName OpName =
+      Ctx.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
+    
+    DeclContext::lookup_const_iterator Op, OpEnd;
+    for (llvm::tie(Op, OpEnd) = RD->lookup(OpName);
+         Op != OpEnd; ++Op) {
+      CXXMethodDecl *Delete = cast<CXXMethodDecl>(*Op);
+
+      if (Delete->isUsualDeallocationFunction()) {
+        // We don't need a cookie.
+        if (Delete->getNumParams() == 1)
+          return 0;
+        
+        assert(Delete->getNumParams() == 2 && 
+               "Unexpected deallocation function type!");
+        break;
+      }
+    }
   }
   
-  // Padding is the maximum of sizeof(size_t) and alignof(T)
+  // Padding is the maximum of sizeof(size_t) and alignof(ElementType)
   return std::max(Ctx.getTypeSize(Ctx.getSizeType()),
-                  static_cast<uint64_t>(Ctx.getTypeAlign(T))) / 8;
+                  static_cast<uint64_t>(Ctx.getTypeAlign(ElementType))) / 8;
+}
+
+static uint64_t CalculateCookiePadding(ASTContext &Ctx, const CXXNewExpr *E) {
+  if (!E->isArray())
+    return 0;
+
+  return CalculateCookiePadding(Ctx, E->getAllocatedType());
+  QualType T = E->getAllocatedType();
 }
 
 static llvm::Value *EmitCXXNewAllocSize(CodeGenFunction &CGF, 
@@ -237,6 +257,40 @@
   return NewPtr;
 }
 
+
+static std::pair<llvm::Value *, llvm::Value *>
+GetAllocatedObjectPtrAndNumElements(CodeGenFunction &CGF,
+                                    llvm::Value *Ptr, QualType DeleteTy) {
+  QualType SizeTy = CGF.getContext().getSizeType();
+  const llvm::Type *SizeLTy = CGF.ConvertType(SizeTy);
+  
+  uint64_t DeleteTypeAlign = CGF.getContext().getTypeAlign(DeleteTy);
+  uint64_t CookiePadding = std::max(CGF.getContext().getTypeSize(SizeTy),
+                                    DeleteTypeAlign) / 8;
+  assert(CookiePadding && "CookiePadding should not be 0.");
+
+  const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(CGF.getLLVMContext());
+  uint64_t CookieOffset = 
+    CookiePadding - CGF.getContext().getTypeSize(SizeTy) / 8;
+
+  llvm::Value *AllocatedObjectPtr = CGF.Builder.CreateBitCast(Ptr, Int8PtrTy);
+  AllocatedObjectPtr = 
+    CGF.Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr,
+                                           -CookiePadding);
+
+  llvm::Value *NumElementsPtr =
+    CGF.Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, 
+                                           CookieOffset);
+  NumElementsPtr = 
+    CGF.Builder.CreateBitCast(NumElementsPtr, SizeLTy->getPointerTo());
+  
+  llvm::Value *NumElements = CGF.Builder.CreateLoad(NumElementsPtr);
+  NumElements = 
+    CGF.Builder.CreateIntCast(NumElements, SizeLTy, /*isSigned=*/false);
+  
+  return std::make_pair(AllocatedObjectPtr, NumElements);
+}
+
 void CodeGenFunction::EmitDeleteCall(const FunctionDecl *DeleteFD,
                                      llvm::Value *Ptr,
                                      QualType DeleteTy) {
@@ -245,38 +299,37 @@
 
   CallArgList DeleteArgs;
 
-  QualType ArgTy = DeleteFTy->getArgType(0);
-  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
-  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
-
+  // Check if we need to pass the size to the delete operator.
+  llvm::Value *Size = 0;
+  QualType SizeTy;
   if (DeleteFTy->getNumArgs() == 2) {
+    SizeTy = DeleteFTy->getArgType(1);
     uint64_t DeleteTypeSize = getContext().getTypeSize(DeleteTy) / 8;
-    QualType SizeTy = DeleteFTy->getArgType(1);
-    llvm::Value *Size = 
-      llvm::ConstantInt::get(ConvertType(SizeTy), DeleteTypeSize);
-
-    if (DeleteFD->getOverloadedOperator() == OO_Array_Delete) {
-      // We need to get the number of elements in the array from the cookie.
-      uint64_t DeleteTypeAlign = getContext().getTypeAlign(DeleteTy);
-      unsigned CookiePadding = std::max(getContext().getTypeSize(SizeTy),
-                                        DeleteTypeAlign) / 8;
-      assert(CookiePadding && "CookiePadding should not be 0.");
+    Size = llvm::ConstantInt::get(ConvertType(SizeTy), DeleteTypeSize);
+  }
+  
+  if (DeleteFD->getOverloadedOperator() == OO_Array_Delete &&
       
-      uint64_t CookieOffset =
-        CookiePadding - getContext().getTypeSize(SizeTy) / 8;
-      llvm::Value *NumElementsPtr =
-        Builder.CreateConstInBoundsGEP1_64(Ptr, CookieOffset);
-      NumElementsPtr = 
-        Builder.CreateBitCast(NumElementsPtr,
-                              ConvertType(SizeTy)->getPointerTo());
-      llvm::Value *NumElements = Builder.CreateLoad(NumElementsPtr);
+      CalculateCookiePadding(getContext(), DeleteTy)) {
+    // We need to get the number of elements in the array from the cookie.
+    llvm::Value *AllocatedObjectPtr;
+    llvm::Value *NumElements;
+    llvm::tie(AllocatedObjectPtr, NumElements) =
+      GetAllocatedObjectPtrAndNumElements(*this, Ptr, DeleteTy);
     
-      // Multiply the size with the number of elements.
+    // Multiply the size with the number of elements.
+    if (Size)
       Size = Builder.CreateMul(NumElements, Size);
-    }
-     
-    DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy));
+    
+    Ptr = AllocatedObjectPtr;
   }
+  
+  QualType ArgTy = DeleteFTy->getArgType(0);
+  llvm::Value *DeletePtr = Builder.CreateBitCast(Ptr, ConvertType(ArgTy));
+  DeleteArgs.push_back(std::make_pair(RValue::get(DeletePtr), ArgTy));
+
+  if (Size)
+    DeleteArgs.push_back(std::make_pair(RValue::get(Size), SizeTy));
 
   // Emit the call to delete.
   EmitCall(CGM.getTypes().getFunctionInfo(DeleteFTy->getResultType(),
@@ -321,31 +374,12 @@
       if (!RD->hasTrivialDestructor()) {
         const CXXDestructorDecl *Dtor = RD->getDestructor(getContext());
         if (E->isArrayForm()) {
-          QualType SizeTy = getContext().getSizeType();
-          uint64_t CookiePadding = std::max(getContext().getTypeSize(SizeTy),
-                static_cast<uint64_t>(getContext().getTypeAlign(DeleteTy))) / 8;
-          assert(CookiePadding && "CookiePadding should not be 0.");
-                 
-          const llvm::Type *Int8PtrTy = llvm::Type::getInt8PtrTy(VMContext);
-          uint64_t CookieOffset =
-            CookiePadding - getContext().getTypeSize(SizeTy) / 8;
-          llvm::Value *AllocatedObjectPtr = 
-            Builder.CreateConstInBoundsGEP1_64(
-                          Builder.CreateBitCast(Ptr, Int8PtrTy), 
-                                               -CookiePadding);
-          llvm::Value *NumElementsPtr =
-            Builder.CreateConstInBoundsGEP1_64(AllocatedObjectPtr, 
-                                               CookieOffset);
-          NumElementsPtr = Builder.CreateBitCast(NumElementsPtr,
-                                        ConvertType(SizeTy)->getPointerTo());
-            
-          llvm::Value *NumElements = Builder.CreateLoad(NumElementsPtr);
-          NumElements = 
-            Builder.CreateIntCast(NumElements, 
-                                  llvm::Type::getInt64Ty(VMContext), false, 
-                                  "count.tmp");
+          llvm::Value *AllocatedObjectPtr;
+          llvm::Value *NumElements;
+          llvm::tie(AllocatedObjectPtr, NumElements) =
+            GetAllocatedObjectPtrAndNumElements(*this, Ptr, DeleteTy);
+          
           EmitCXXAggrDestructorCall(Dtor, NumElements, Ptr);
-          Ptr = AllocatedObjectPtr;
         } else if (Dtor->isVirtual()) {
           const llvm::Type *Ty =
             CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(Dtor),





More information about the cfe-commits mailing list