forked from OSchip/llvm-project
Move getMallocAllocatedType and getMallocArraySize to GlobalOpt [NFC]
These are implementation details of the global-opt transform and not easily reuseable, so remove them from the analysis header.
This commit is contained in:
parent
67a3331e4f
commit
7052670e96
|
@ -114,26 +114,6 @@ bool isOpNewLikeFn(const Value *V, const TargetLibraryInfo *TLI,
|
|||
bool isStrdupLikeFn(const Value *V, const TargetLibraryInfo *TLI,
|
||||
bool LookThroughBitCast = false);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// malloc Call Utility Functions.
|
||||
//
|
||||
|
||||
/// getMallocAllocatedType - Returns the Type allocated by malloc call.
|
||||
/// The Type depends on the number of bitcast uses of the malloc call:
|
||||
/// 0: PointerType is the malloc calls' return type.
|
||||
/// 1: PointerType is the bitcast's result type.
|
||||
/// >1: Unique PointerType cannot be determined, return NULL.
|
||||
Type *getMallocAllocatedType(const CallInst *CI, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// getMallocArraySize - Returns the array size of a malloc call. If the
|
||||
/// argument passed to malloc is a multiple of the size of the malloced type,
|
||||
/// then return that multiple. For non-array mallocs, the multiple is
|
||||
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
|
||||
/// determined.
|
||||
Value *getMallocArraySize(CallInst *CI, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
bool LookThroughSExt = false);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// free Call Utility Functions.
|
||||
//
|
||||
|
|
|
@ -334,85 +334,6 @@ bool llvm::isStrdupLikeFn(const Value *V, const TargetLibraryInfo *TLI,
|
|||
return getAllocationData(V, StrDupLike, TLI, LookThroughBitCast).hasValue();
|
||||
}
|
||||
|
||||
static Value *computeArraySize(const CallInst *CI, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
bool LookThroughSExt = false) {
|
||||
if (!CI)
|
||||
return nullptr;
|
||||
|
||||
// The size of the malloc's result type must be known to determine array size.
|
||||
Type *T = getMallocAllocatedType(CI, TLI);
|
||||
if (!T || !T->isSized())
|
||||
return nullptr;
|
||||
|
||||
unsigned ElementSize = DL.getTypeAllocSize(T);
|
||||
if (StructType *ST = dyn_cast<StructType>(T))
|
||||
ElementSize = DL.getStructLayout(ST)->getSizeInBytes();
|
||||
|
||||
// If malloc call's arg can be determined to be a multiple of ElementSize,
|
||||
// return the multiple. Otherwise, return NULL.
|
||||
Value *MallocArg = CI->getArgOperand(0);
|
||||
Value *Multiple = nullptr;
|
||||
if (ComputeMultiple(MallocArg, ElementSize, Multiple, LookThroughSExt))
|
||||
return Multiple;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// getMallocType - Returns the PointerType resulting from the malloc call.
|
||||
/// The PointerType depends on the number of bitcast uses of the malloc call:
|
||||
/// 0: PointerType is the calls' return type.
|
||||
/// 1: PointerType is the bitcast's result type.
|
||||
/// >1: Unique PointerType cannot be determined, return NULL.
|
||||
static PointerType *getMallocType(const CallInst *CI,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
assert(isMallocLikeFn(CI, TLI) && "getMallocType and not malloc call");
|
||||
|
||||
PointerType *MallocType = nullptr;
|
||||
unsigned NumOfBitCastUses = 0;
|
||||
|
||||
// Determine if CallInst has a bitcast use.
|
||||
for (const User *U : CI->users())
|
||||
if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
|
||||
MallocType = cast<PointerType>(BCI->getDestTy());
|
||||
NumOfBitCastUses++;
|
||||
}
|
||||
|
||||
// Malloc call has 1 bitcast use, so type is the bitcast's destination type.
|
||||
if (NumOfBitCastUses == 1)
|
||||
return MallocType;
|
||||
|
||||
// Malloc call was not bitcast, so type is the malloc function's return type.
|
||||
if (NumOfBitCastUses == 0)
|
||||
return cast<PointerType>(CI->getType());
|
||||
|
||||
// Type could not be determined.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// getMallocAllocatedType - Returns the Type allocated by malloc call.
|
||||
/// The Type depends on the number of bitcast uses of the malloc call:
|
||||
/// 0: PointerType is the malloc calls' return type.
|
||||
/// 1: PointerType is the bitcast's result type.
|
||||
/// >1: Unique PointerType cannot be determined, return NULL.
|
||||
Type *llvm::getMallocAllocatedType(const CallInst *CI,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
PointerType *PT = getMallocType(CI, TLI);
|
||||
return PT ? PT->getElementType() : nullptr;
|
||||
}
|
||||
|
||||
/// getMallocArraySize - Returns the array size of a malloc call. If the
|
||||
/// argument passed to malloc is a multiple of the size of the malloced type,
|
||||
/// then return that multiple. For non-array mallocs, the multiple is
|
||||
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
|
||||
/// determined.
|
||||
Value *llvm::getMallocArraySize(CallInst *CI, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
bool LookThroughSExt) {
|
||||
assert(isMallocLikeFn(CI, TLI) && "getMallocArraySize and not malloc call");
|
||||
return computeArraySize(CI, DL, TLI, LookThroughSExt);
|
||||
}
|
||||
|
||||
/// isLibFreeFunction - Returns true if the function is a builtin free()
|
||||
bool llvm::isLibFreeFunction(const Function *F, const LibFunc TLIFn) {
|
||||
unsigned ExpectedNumParams;
|
||||
|
|
|
@ -1066,6 +1066,86 @@ valueIsOnlyUsedLocallyOrStoredToOneGlobal(const CallInst *CI,
|
|||
return true;
|
||||
}
|
||||
|
||||
/// getMallocType - Returns the PointerType resulting from the malloc call.
|
||||
/// The PointerType depends on the number of bitcast uses of the malloc call:
|
||||
/// 0: PointerType is the calls' return type.
|
||||
/// 1: PointerType is the bitcast's result type.
|
||||
/// >1: Unique PointerType cannot be determined, return NULL.
|
||||
static PointerType *getMallocType(const CallInst *CI,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
assert(isMallocLikeFn(CI, TLI) && "getMallocType and not malloc call");
|
||||
|
||||
PointerType *MallocType = nullptr;
|
||||
unsigned NumOfBitCastUses = 0;
|
||||
|
||||
// Determine if CallInst has a bitcast use.
|
||||
for (const User *U : CI->users())
|
||||
if (const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
|
||||
MallocType = cast<PointerType>(BCI->getDestTy());
|
||||
NumOfBitCastUses++;
|
||||
}
|
||||
|
||||
// Malloc call has 1 bitcast use, so type is the bitcast's destination type.
|
||||
if (NumOfBitCastUses == 1)
|
||||
return MallocType;
|
||||
|
||||
// Malloc call was not bitcast, so type is the malloc function's return type.
|
||||
if (NumOfBitCastUses == 0)
|
||||
return cast<PointerType>(CI->getType());
|
||||
|
||||
// Type could not be determined.
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// getMallocAllocatedType - Returns the Type allocated by malloc call.
|
||||
/// The Type depends on the number of bitcast uses of the malloc call:
|
||||
/// 0: PointerType is the malloc calls' return type.
|
||||
/// 1: PointerType is the bitcast's result type.
|
||||
/// >1: Unique PointerType cannot be determined, return NULL.
|
||||
static Type *getMallocAllocatedType(const CallInst *CI,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
PointerType *PT = getMallocType(CI, TLI);
|
||||
return PT ? PT->getElementType() : nullptr;
|
||||
}
|
||||
|
||||
static Value *computeArraySize(const CallInst *CI, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
bool LookThroughSExt = false) {
|
||||
if (!CI)
|
||||
return nullptr;
|
||||
|
||||
// The size of the malloc's result type must be known to determine array size.
|
||||
Type *T = getMallocAllocatedType(CI, TLI);
|
||||
if (!T || !T->isSized())
|
||||
return nullptr;
|
||||
|
||||
unsigned ElementSize = DL.getTypeAllocSize(T);
|
||||
if (StructType *ST = dyn_cast<StructType>(T))
|
||||
ElementSize = DL.getStructLayout(ST)->getSizeInBytes();
|
||||
|
||||
// If malloc call's arg can be determined to be a multiple of ElementSize,
|
||||
// return the multiple. Otherwise, return NULL.
|
||||
Value *MallocArg = CI->getArgOperand(0);
|
||||
Value *Multiple = nullptr;
|
||||
if (ComputeMultiple(MallocArg, ElementSize, Multiple, LookThroughSExt))
|
||||
return Multiple;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
/// getMallocArraySize - Returns the array size of a malloc call. If the
|
||||
/// argument passed to malloc is a multiple of the size of the malloced type,
|
||||
/// then return that multiple. For non-array mallocs, the multiple is
|
||||
/// constant 1. Otherwise, return NULL for mallocs whose array size cannot be
|
||||
/// determined.
|
||||
static Value *getMallocArraySize(CallInst *CI, const DataLayout &DL,
|
||||
const TargetLibraryInfo *TLI,
|
||||
bool LookThroughSExt) {
|
||||
assert(isMallocLikeFn(CI, TLI) && "getMallocArraySize and not malloc call");
|
||||
return computeArraySize(CI, DL, TLI, LookThroughSExt);
|
||||
}
|
||||
|
||||
|
||||
/// This function is called when we see a pointer global variable with a single
|
||||
/// value stored it that is a malloc or cast of malloc.
|
||||
static bool tryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, CallInst *CI,
|
||||
|
|
Loading…
Reference in New Issue