forked from OSchip/llvm-project
[MemoryBuiltins] Add getReallocatedOperand() function (NFC)
Replace the value-accepting isReallocLikeFn() overload with a getReallocatedOperand() function, which returns which operand is the one being reallocated. Currently, this is always the first one, but once allockind(realloc) is respected, the reallocated operand will be determined by the allocptr parameter attribute.
This commit is contained in:
parent
46e6dd84b7
commit
1f69503107
|
@ -65,14 +65,13 @@ bool isMallocOrCallocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
|
|||
/// allocates memory (either malloc, calloc, or strdup like).
|
||||
bool isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Tests if a value is a call or invoke to a library function that
|
||||
/// reallocates memory (e.g., realloc).
|
||||
bool isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// Tests if a function is a call or invoke to a library function that
|
||||
/// reallocates memory (e.g., realloc).
|
||||
bool isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI);
|
||||
|
||||
/// If this is a call to a realloc function, return the reallocated operand.
|
||||
Value *getReallocatedOperand(const CallBase *CB, const TargetLibraryInfo *TLI);
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// free Call Utility Functions.
|
||||
//
|
||||
|
|
|
@ -312,18 +312,21 @@ bool llvm::isAllocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
|
|||
return getAllocationData(V, AllocLike, TLI).has_value();
|
||||
}
|
||||
|
||||
/// Tests if a value is a call or invoke to a library function that
|
||||
/// reallocates memory (e.g., realloc).
|
||||
bool llvm::isReallocLikeFn(const Value *V, const TargetLibraryInfo *TLI) {
|
||||
return getAllocationData(V, ReallocLike, TLI).has_value();
|
||||
}
|
||||
|
||||
/// Tests if a functions is a call or invoke to a library function that
|
||||
/// reallocates memory (e.g., realloc).
|
||||
bool llvm::isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI) {
|
||||
return getAllocationDataForFunction(F, ReallocLike, TLI).has_value();
|
||||
}
|
||||
|
||||
Value *llvm::getReallocatedOperand(const CallBase *CB,
|
||||
const TargetLibraryInfo *TLI) {
|
||||
if (getAllocationData(CB, ReallocLike, TLI).has_value()) {
|
||||
// All currently supported realloc functions reallocate the first argument.
|
||||
return CB->getArgOperand(0);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
bool llvm::isRemovableAlloc(const CallBase *CB, const TargetLibraryInfo *TLI) {
|
||||
// Note: Removability is highly dependent on the source language. For
|
||||
// example, recent C++ requires direct calls to the global allocation
|
||||
|
|
|
@ -2808,7 +2808,7 @@ static bool isAllocSiteRemovable(Instruction *AI,
|
|||
continue;
|
||||
}
|
||||
|
||||
if (isReallocLikeFn(I, &TLI) &&
|
||||
if (getReallocatedOperand(cast<CallBase>(I), &TLI) == PI &&
|
||||
getAllocationFamily(I, &TLI) == Family) {
|
||||
assert(Family);
|
||||
Users.emplace_back(I);
|
||||
|
@ -3050,12 +3050,10 @@ Instruction *InstCombinerImpl::visitFree(CallInst &FI, Value *Op) {
|
|||
|
||||
// If we had free(realloc(...)) with no intervening uses, then eliminate the
|
||||
// realloc() entirely.
|
||||
if (CallInst *CI = dyn_cast<CallInst>(Op)) {
|
||||
if (CI->hasOneUse() && isReallocLikeFn(CI, &TLI)) {
|
||||
return eraseInstFromFunction(
|
||||
*replaceInstUsesWith(*CI, CI->getOperand(0)));
|
||||
}
|
||||
}
|
||||
CallInst *CI = dyn_cast<CallInst>(Op);
|
||||
if (CI && CI->hasOneUse())
|
||||
if (Value *ReallocatedOp = getReallocatedOperand(CI, &TLI))
|
||||
return eraseInstFromFunction(*replaceInstUsesWith(*CI, ReallocatedOp));
|
||||
|
||||
// If we optimize for code size, try to move the call to free before the null
|
||||
// test so that simplify cfg can remove the empty block and dead code
|
||||
|
|
Loading…
Reference in New Issue