[llvm-commits] [llvm] r84288 - in /llvm/trunk: lib/Transforms/IPO/GlobalOpt.cpp test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll
Victor Hernandez
vhernandez at apple.com
Fri Oct 16 16:12:27 PDT 2009
Author: hernande
Date: Fri Oct 16 18:12:25 2009
New Revision: 84288
URL: http://llvm.org/viewvc/llvm-project?rev=84288&view=rev
Log:
HeapAllocSRoA also needs to check if malloc array size can be computed.
Added:
llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll
Modified:
llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
Modified: llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp?rev=84288&r1=84287&r2=84288&view=diff
==============================================================================
--- llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp (original)
+++ llvm/trunk/lib/Transforms/IPO/GlobalOpt.cpp Fri Oct 16 18:12:25 2009
@@ -1586,6 +1586,8 @@
<< " BITCAST = " << *BCI << '\n');
const Type* MAT = getMallocAllocatedType(CI);
const StructType *STy = cast<StructType>(MAT);
+ Value* ArraySize = getMallocArraySize(CI, Context, TD);
+ assert(ArraySize && "not a malloc whose array size can be determined");
// There is guaranteed to be at least one use of the malloc (storing
// it into GV). If there are other uses, change them to be uses of
@@ -1610,8 +1612,8 @@
GV->isThreadLocal());
FieldGlobals.push_back(NGV);
- Value *NMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context), FieldTy,
- getMallocArraySize(CI, Context, TD),
+ Value *NMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context),
+ FieldTy, ArraySize,
BCI->getName() + ".f" + Twine(FieldNo));
FieldMallocs.push_back(NMI);
new StoreInst(NMI, NGV, BCI);
@@ -1892,6 +1894,7 @@
// This eliminates dynamic allocation, avoids an indirection accessing the
// data, and exposes the resultant global to further GlobalOpt.
Value *NElems = getMallocArraySize(CI, Context, TD);
+ // We cannot optimize the malloc if we cannot determine malloc array size.
if (NElems) {
if (ConstantInt *NElements = dyn_cast<ConstantInt>(NElems))
// Restrict this transformation to only working on small allocations
@@ -1902,42 +1905,43 @@
GVI = OptimizeGlobalAddressOfMalloc(GV, CI, BCI, Context, TD);
return true;
}
- }
- // If the allocation is an array of structures, consider transforming this
- // into multiple malloc'd arrays, one for each field. This is basically
- // SRoA for malloc'd memory.
-
- // If this is an allocation of a fixed size array of structs, analyze as a
- // variable size array. malloc [100 x struct],1 -> malloc struct, 100
- if (!isArrayMalloc(CI, Context, TD))
- if (const ArrayType *AT = dyn_cast<ArrayType>(AllocTy))
- AllocTy = AT->getElementType();
-
- if (const StructType *AllocSTy = dyn_cast<StructType>(AllocTy)) {
- // This the structure has an unreasonable number of fields, leave it
- // alone.
- if (AllocSTy->getNumElements() <= 16 && AllocSTy->getNumElements() != 0 &&
- AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, BCI)) {
-
- // If this is a fixed size array, transform the Malloc to be an alloc of
- // structs. malloc [100 x struct],1 -> malloc struct, 100
- if (const ArrayType *AT = dyn_cast<ArrayType>(getMallocAllocatedType(CI))) {
- Value* NumElements = ConstantInt::get(Type::getInt32Ty(Context),
- AT->getNumElements());
- Value* NewMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context),
- AllocSTy, NumElements,
- BCI->getName());
- Value *Cast = new BitCastInst(NewMI, getMallocType(CI), "tmp", CI);
- BCI->replaceAllUsesWith(Cast);
- BCI->eraseFromParent();
- CI->eraseFromParent();
- BCI = cast<BitCastInst>(NewMI);
- CI = extractMallocCallFromBitCast(NewMI);
- }
+ // If the allocation is an array of structures, consider transforming this
+ // into multiple malloc'd arrays, one for each field. This is basically
+ // SRoA for malloc'd memory.
+
+ // If this is an allocation of a fixed size array of structs, analyze as a
+ // variable size array. malloc [100 x struct],1 -> malloc struct, 100
+ if (!isArrayMalloc(CI, Context, TD))
+ if (const ArrayType *AT = dyn_cast<ArrayType>(AllocTy))
+ AllocTy = AT->getElementType();
+
+ if (const StructType *AllocSTy = dyn_cast<StructType>(AllocTy)) {
+ // This the structure has an unreasonable number of fields, leave it
+ // alone.
+ if (AllocSTy->getNumElements() <= 16 && AllocSTy->getNumElements() != 0 &&
+ AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, BCI)) {
+
+ // If this is a fixed size array, transform the Malloc to be an alloc of
+ // structs. malloc [100 x struct],1 -> malloc struct, 100
+ if (const ArrayType *AT =
+ dyn_cast<ArrayType>(getMallocAllocatedType(CI))) {
+ Value* NumElements = ConstantInt::get(Type::getInt32Ty(Context),
+ AT->getNumElements());
+ Value* NewMI = CallInst::CreateMalloc(CI, TD->getIntPtrType(Context),
+ AllocSTy, NumElements,
+ BCI->getName());
+ Value *Cast = new BitCastInst(NewMI, getMallocType(CI), "tmp", CI);
+ BCI->replaceAllUsesWith(Cast);
+ BCI->eraseFromParent();
+ CI->eraseFromParent();
+ BCI = cast<BitCastInst>(NewMI);
+ CI = extractMallocCallFromBitCast(NewMI);
+ }
- GVI = PerformHeapAllocSRoA(GV, CI, BCI, Context, TD);
- return true;
+ GVI = PerformHeapAllocSRoA(GV, CI, BCI, Context, TD);
+ return true;
+ }
}
}
Added: llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll?rev=84288&view=auto
==============================================================================
--- llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll (added)
+++ llvm/trunk/test/Transforms/GlobalOpt/2009-11-16-BrokenPerformHeapAllocSRoA.ll Fri Oct 16 18:12:25 2009
@@ -0,0 +1,26 @@
+; RUN: opt < %s -globalopt -S | FileCheck %s
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
+target triple = "x86_64-apple-darwin10.0"
+
+%struct.hashheader = type { i16, i16, i16, i16, i16, i16, i32, i32, i32, i32, i32, i32, i32, i32, i32, [5 x i8], [13 x i8], i8, i8, i8, [228 x i16], [228 x i8], [228 x i8], [228 x i8], [228 x i8], [228 x i8], [228 x i8], [128 x i8], [100 x [11 x i8]], [100 x i32], [100 x i32], i16 }
+%struct.strchartype = type { i8*, i8*, i8* }
+
+ at hashheader = internal global %struct.hashheader zeroinitializer, align 32 ; <%struct.hashheader*> [#uses=1]
+ at chartypes = internal global %struct.strchartype* null ; <%struct.strchartype**> [#uses=1]
+; CHECK-NOT: @hashheader
+; CHECK-NOT: @chartypes
+
+; based on linit in office-ispell
+define void @test() nounwind ssp {
+ %1 = load i32* getelementptr inbounds (%struct.hashheader* @hashheader, i64 0, i32 13), align 8 ; <i32> [#uses=1]
+ %2 = sext i32 %1 to i64 ; <i64> [#uses=1]
+ %3 = mul i64 %2, ptrtoint (%struct.strchartype* getelementptr (%struct.strchartype* null, i64 1) to i64) ; <i64> [#uses=1]
+ %4 = tail call i8* @malloc(i64 %3) ; <i8*> [#uses=1]
+; CHECK: call i8* @malloc(i64
+ %5 = bitcast i8* %4 to %struct.strchartype* ; <%struct.strchartype*> [#uses=1]
+ store %struct.strchartype* %5, %struct.strchartype** @chartypes, align 8
+ ret void
+}
+
+declare noalias i8* @malloc(i64)
More information about the llvm-commits
mailing list