diff --git a/llvm/include/llvm/Analysis/MemoryBuiltins.h b/llvm/include/llvm/Analysis/MemoryBuiltins.h index 7ad83612880f5..b0ff7f969484a 100644 --- a/llvm/include/llvm/Analysis/MemoryBuiltins.h +++ b/llvm/include/llvm/Analysis/MemoryBuiltins.h @@ -91,15 +91,16 @@ inline CallInst *isFreeCall(Value *I, const TargetLibraryInfo *TLI) { // Properties of allocation functions // -/// Return false if the allocation can have side effects on the program state -/// we are required to preserve beyond the effect of allocating a new object. +/// Return true if this is a call to an allocation function that does not have +/// side effects that we are required to preserve beyond the effect of +/// allocating a new object. /// Ex: If our allocation routine has a counter for the number of objects /// allocated, and the program prints it on exit, can the value change due /// to optimization? Answer is highly language dependent. /// Note: *Removable* really does mean removable; it does not mean observable. /// A language (e.g. C++) can allow removing allocations without allowing /// insertion or speculative execution of allocation routines. -bool isAllocRemovable(const CallBase *V, const TargetLibraryInfo *TLI); +bool isRemovableAlloc(const CallBase *V, const TargetLibraryInfo *TLI); /// Gets the alignment argument for an aligned_alloc-like function, using either /// built-in knowledge based on fuction names/signatures or allocalign diff --git a/llvm/lib/Analysis/MemoryBuiltins.cpp b/llvm/lib/Analysis/MemoryBuiltins.cpp index f5b121c98ec48..5c9f9cc94fd1e 100644 --- a/llvm/lib/Analysis/MemoryBuiltins.cpp +++ b/llvm/lib/Analysis/MemoryBuiltins.cpp @@ -319,15 +319,14 @@ bool llvm::isReallocLikeFn(const Function *F, const TargetLibraryInfo *TLI) { return getAllocationDataForFunction(F, ReallocLike, TLI).has_value(); } -bool llvm::isAllocRemovable(const CallBase *CB, const TargetLibraryInfo *TLI) { - assert(isAllocationFn(CB, TLI)); - +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 // [basic.stc.dynamic.allocation] to be observable unless part of a new // expression [expr.new paragraph 13]. - // Historically we've treated the C family allocation routines as removable + // Historically we've treated the C family allocation routines and operator + // new as removable return isAllocLikeFn(CB, TLI); } diff --git a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp index 501b902812827..af515c9fe34a1 100644 --- a/llvm/lib/Transforms/IPO/AttributorAttributes.cpp +++ b/llvm/lib/Transforms/IPO/AttributorAttributes.cpp @@ -5836,7 +5836,7 @@ struct AAHeapToStackFunction final : public AAHeapToStack { // To do heap to stack, we need to know that the allocation itself is // removable once uses are rewritten, and that we can initialize the // alloca to the same pattern as the original allocation result. - if (isAllocationFn(CB, TLI) && isAllocRemovable(CB, TLI)) { + if (isRemovableAlloc(CB, TLI)) { auto *I8Ty = Type::getInt8Ty(CB->getParent()->getContext()); if (nullptr != getInitialValueOfAllocation(CB, TLI, I8Ty)) { AllocationInfo *AI = new (A.Allocator) AllocationInfo{CB}; diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 1ad6e2b2a1d24..ec26db8bfc0b4 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -1040,7 +1040,7 @@ static bool tryToOptimizeStoreOfAllocationToGlobal(GlobalVariable *GV, CallInst *CI, const DataLayout &DL, TargetLibraryInfo *TLI) { - if (!isAllocRemovable(CI, TLI)) + if (!isRemovableAlloc(CI, TLI)) // Must be able to remove the call when we get done.. return false; diff --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp index 741725d226623..6a2cfd63573a4 100644 --- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -3079,8 +3079,7 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) { Call, Builder.CreateBitOrPointerCast(ReturnedArg, CallTy)); } - if (isAllocationFn(&Call, &TLI) && - isAllocRemovable(&cast(Call), &TLI)) + if (isRemovableAlloc(&Call, &TLI)) return visitAllocSite(Call); // Handle intrinsics which can be used in both call and invoke context. diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp index 42c6433270db0..98292c49e714c 100644 --- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp +++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp @@ -2832,7 +2832,7 @@ static bool isAllocSiteRemovable(Instruction *AI, } Instruction *InstCombinerImpl::visitAllocSite(Instruction &MI) { - assert(isa(MI) || isAllocRemovable(&cast(MI), &TLI)); + assert(isa(MI) || isRemovableAlloc(&cast(MI), &TLI)); // If we have a malloc call which is only used in any amount of comparisons to // null and free calls, delete the calls and replace the comparisons with true diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp index 9b1bb93b29153..83e67b108ed9f 100644 --- a/llvm/lib/Transforms/Utils/Local.cpp +++ b/llvm/lib/Transforms/Utils/Local.cpp @@ -439,8 +439,9 @@ bool llvm::wouldInstructionBeTriviallyDead(Instruction *I, return true; } - if (isAllocationFn(I, TLI) && isAllocRemovable(cast(I), TLI)) - return true; + if (auto *CB = dyn_cast(I)) + if (isRemovableAlloc(CB, TLI)) + return true; if (!I->willReturn()) return false;