[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