diff options
author | Victor Hernandez <vhernandez@apple.com> | 2009-10-15 20:14:52 +0000 |
---|---|---|
committer | Victor Hernandez <vhernandez@apple.com> | 2009-10-15 20:14:52 +0000 |
commit | 2491ce03535cf8ec171570d2e28df63e4db3dd6b (patch) | |
tree | f989d52d9bee2406d249320485604cfc15d171b1 /lib/Transforms/IPO/GlobalOpt.cpp | |
parent | 5814fefc7f27caba408d75194a40d880c64eaac6 (diff) |
Fix bug where array malloc with unexpected computation of the size argument resulted in MallocHelper
identifying the malloc as a non-array malloc. This broke GlobalOpt's optimization of stores of mallocs
to global variables.
The fix is to classify malloc's into 3 categories:
1. non-array mallocs
2. array mallocs whose array size can be determined
3. mallocs that cannot be determined to be of type 1 or 2 and cannot be optimized
getMallocArraySize() returns NULL for category 3, and all users of this function must avoid their
malloc optimization if this function returns NULL.
Eventually, currently unexpected codegen for computing the malloc's size argument will be supported in
isArrayMalloc() and getMallocArraySize(), extending malloc optimizations to those examples.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@84199 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO/GlobalOpt.cpp')
-rw-r--r-- | lib/Transforms/IPO/GlobalOpt.cpp | 34 |
1 files changed, 17 insertions, 17 deletions
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp index a44386e6c1..0d9818fdfa 100644 --- a/lib/Transforms/IPO/GlobalOpt.cpp +++ b/lib/Transforms/IPO/GlobalOpt.cpp @@ -950,12 +950,14 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, BitCastInst *BCI, LLVMContext &Context, TargetData* TD) { + DEBUG(errs() << "PROMOTING MALLOC GLOBAL: " << *GV + << " CALL = " << *CI << " BCI = " << *BCI << '\n'); + const Type *IntPtrTy = TD->getIntPtrType(Context); - DEBUG(errs() << "PROMOTING MALLOC GLOBAL: " << *GV << " MALLOC = " << *CI); - - ConstantInt *NElements = cast<ConstantInt>(getMallocArraySize(CI, - Context, TD)); + Value* ArraySize = getMallocArraySize(CI, Context, TD); + assert(ArraySize && "not a malloc whose array size can be determined"); + ConstantInt *NElements = cast<ConstantInt>(ArraySize); if (NElements->getZExtValue() != 1) { // If we have an array allocation, transform it to a single element // allocation to make the code below simpler. @@ -976,9 +978,6 @@ static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV, // Create the new global variable. The contents of the malloc'd memory is // undefined, so initialize with an undef value. - // FIXME: This new global should have the alignment returned by malloc. Code - // could depend on malloc returning large alignment (on the mac, 16 bytes) but - // this would only guarantee some lower alignment. const Type *MAT = getMallocAllocatedType(CI); Constant *Init = UndefValue::get(MAT); GlobalVariable *NewGV = new GlobalVariable(*GV->getParent(), @@ -1892,16 +1891,17 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, // transform the program to use global memory instead of malloc'd memory. // This eliminates dynamic allocation, avoids an indirection accessing the // data, and exposes the resultant global to further GlobalOpt. - if (ConstantInt *NElements = - dyn_cast<ConstantInt>(getMallocArraySize(CI, Context, TD))) { - // Restrict this transformation to only working on small allocations - // (2048 bytes currently), as we don't want to introduce a 16M global or - // something. - if (TD && - NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) { - GVI = OptimizeGlobalAddressOfMalloc(GV, CI, BCI, Context, TD); - return true; - } + Value *NElems = getMallocArraySize(CI, Context, TD); + if (NElems) { + if (ConstantInt *NElements = dyn_cast<ConstantInt>(NElems)) + // Restrict this transformation to only working on small allocations + // (2048 bytes currently), as we don't want to introduce a 16M global or + // something. + if (TD && + NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) { + GVI = OptimizeGlobalAddressOfMalloc(GV, CI, BCI, Context, TD); + return true; + } } // If the allocation is an array of structures, consider transforming this |