mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-08 03:30:22 +00:00
- Code clean up to reduce indentation.
- TryToOptimizeStoreOfMallocToGlobal should check if TargetData is available and bail out if it is not. The transformations being done requires TD. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@101285 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7b975f411f
commit
86cd445645
@ -1462,6 +1462,9 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
const Type *AllocTy,
|
const Type *AllocTy,
|
||||||
Module::global_iterator &GVI,
|
Module::global_iterator &GVI,
|
||||||
TargetData *TD) {
|
TargetData *TD) {
|
||||||
|
if (!TD)
|
||||||
|
return false;
|
||||||
|
|
||||||
// If this is a malloc of an abstract type, don't touch it.
|
// If this is a malloc of an abstract type, don't touch it.
|
||||||
if (!AllocTy->isSized())
|
if (!AllocTy->isSized())
|
||||||
return false;
|
return false;
|
||||||
@ -1480,66 +1483,66 @@ static bool TryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV,
|
|||||||
// malloc to be stored into the specified global, loaded setcc'd, and
|
// malloc to be stored into the specified global, loaded setcc'd, and
|
||||||
// GEP'd. These are all things we could transform to using the global
|
// GEP'd. These are all things we could transform to using the global
|
||||||
// for.
|
// for.
|
||||||
{
|
SmallPtrSet<const PHINode*, 8> PHIs;
|
||||||
SmallPtrSet<const PHINode*, 8> PHIs;
|
if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(CI, GV, PHIs))
|
||||||
if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(CI, GV, PHIs))
|
return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// If we have a global that is only initialized with a fixed size malloc,
|
// If we have a global that is only initialized with a fixed size malloc,
|
||||||
// transform the program to use global memory instead of malloc'd memory.
|
// transform the program to use global memory instead of malloc'd memory.
|
||||||
// This eliminates dynamic allocation, avoids an indirection accessing the
|
// This eliminates dynamic allocation, avoids an indirection accessing the
|
||||||
// data, and exposes the resultant global to further GlobalOpt.
|
// data, and exposes the resultant global to further GlobalOpt.
|
||||||
// We cannot optimize the malloc if we cannot determine malloc array size.
|
// We cannot optimize the malloc if we cannot determine malloc array size.
|
||||||
if (Value *NElems = getMallocArraySize(CI, TD, true)) {
|
Value *NElems = getMallocArraySize(CI, TD, true);
|
||||||
if (ConstantInt *NElements = dyn_cast<ConstantInt>(NElems))
|
if (!NElems)
|
||||||
// Restrict this transformation to only working on small allocations
|
return false;
|
||||||
// (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, AllocTy, NElements, 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
|
if (ConstantInt *NElements = dyn_cast<ConstantInt>(NElems))
|
||||||
// variable size array. malloc [100 x struct],1 -> malloc struct, 100
|
// Restrict this transformation to only working on small allocations
|
||||||
if (NElems == ConstantInt::get(CI->getOperand(1)->getType(), 1))
|
// (2048 bytes currently), as we don't want to introduce a 16M global or
|
||||||
if (const ArrayType *AT = dyn_cast<ArrayType>(AllocTy))
|
// something.
|
||||||
AllocTy = AT->getElementType();
|
if (NElements->getZExtValue() * TD->getTypeAllocSize(AllocTy) < 2048) {
|
||||||
|
GVI = OptimizeGlobalAddressOfMalloc(GV, CI, AllocTy, NElements, TD);
|
||||||
if (const StructType *AllocSTy = dyn_cast<StructType>(AllocTy)) {
|
return true;
|
||||||
// This the structure has an unreasonable number of fields, leave it
|
|
||||||
// alone.
|
|
||||||
if (AllocSTy->getNumElements() <= 16 && AllocSTy->getNumElements() != 0 &&
|
|
||||||
AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, CI)) {
|
|
||||||
|
|
||||||
// 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))) {
|
|
||||||
const Type *IntPtrTy = TD->getIntPtrType(CI->getContext());
|
|
||||||
unsigned TypeSize = TD->getStructLayout(AllocSTy)->getSizeInBytes();
|
|
||||||
Value *AllocSize = ConstantInt::get(IntPtrTy, TypeSize);
|
|
||||||
Value *NumElements = ConstantInt::get(IntPtrTy, AT->getNumElements());
|
|
||||||
Instruction *Malloc = CallInst::CreateMalloc(CI, IntPtrTy, AllocSTy,
|
|
||||||
AllocSize, NumElements,
|
|
||||||
CI->getName());
|
|
||||||
Instruction *Cast = new BitCastInst(Malloc, CI->getType(), "tmp", CI);
|
|
||||||
CI->replaceAllUsesWith(Cast);
|
|
||||||
CI->eraseFromParent();
|
|
||||||
CI = dyn_cast<BitCastInst>(Malloc) ?
|
|
||||||
extractMallocCallFromBitCast(Malloc) : cast<CallInst>(Malloc);
|
|
||||||
}
|
|
||||||
|
|
||||||
GVI = PerformHeapAllocSRoA(GV, CI, getMallocArraySize(CI, TD, true),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 (NElems == ConstantInt::get(CI->getOperand(1)->getType(), 1))
|
||||||
|
if (const ArrayType *AT = dyn_cast<ArrayType>(AllocTy))
|
||||||
|
AllocTy = AT->getElementType();
|
||||||
|
|
||||||
|
const StructType *AllocSTy = dyn_cast<StructType>(AllocTy);
|
||||||
|
if (!AllocSTy)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// This the structure has an unreasonable number of fields, leave it
|
||||||
|
// alone.
|
||||||
|
if (AllocSTy->getNumElements() <= 16 && AllocSTy->getNumElements() != 0 &&
|
||||||
|
AllGlobalLoadUsesSimpleEnoughForHeapSRA(GV, CI)) {
|
||||||
|
|
||||||
|
// 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))) {
|
||||||
|
const Type *IntPtrTy = TD->getIntPtrType(CI->getContext());
|
||||||
|
unsigned TypeSize = TD->getStructLayout(AllocSTy)->getSizeInBytes();
|
||||||
|
Value *AllocSize = ConstantInt::get(IntPtrTy, TypeSize);
|
||||||
|
Value *NumElements = ConstantInt::get(IntPtrTy, AT->getNumElements());
|
||||||
|
Instruction *Malloc = CallInst::CreateMalloc(CI, IntPtrTy, AllocSTy,
|
||||||
|
AllocSize, NumElements,
|
||||||
|
CI->getName());
|
||||||
|
Instruction *Cast = new BitCastInst(Malloc, CI->getType(), "tmp", CI);
|
||||||
|
CI->replaceAllUsesWith(Cast);
|
||||||
|
CI->eraseFromParent();
|
||||||
|
CI = dyn_cast<BitCastInst>(Malloc) ?
|
||||||
|
extractMallocCallFromBitCast(Malloc) : cast<CallInst>(Malloc);
|
||||||
|
}
|
||||||
|
|
||||||
|
GVI = PerformHeapAllocSRoA(GV, CI, getMallocArraySize(CI, TD, true),TD);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
Loading…
Reference in New Issue
Block a user