mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 10:42:39 +01:00
[Analysis] Support aligned new/delete functions.
Summary: Clang's __builtin_operator_new/delete was recently taught about the aligned allocation overloads (r328134). This patch makes LLVM aware of them as well. This allows the compiler to perform certain optimizations including eliding new/delete calls. Reviewers: rsmith, majnemer, dblaikie, vsk, bkramer Reviewed By: bkramer Subscribers: ckennelly, llvm-commits Differential Revision: https://reviews.llvm.org/D44769 llvm-svn: 329218
This commit is contained in:
parent
04890db857
commit
bf060d4e97
@ -119,6 +119,12 @@ TLI_DEFINE_STRING_INTERNAL("_ZdaPv")
|
||||
/// void operator delete[](void*, nothrow);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdaPvRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdaPvRKSt9nothrow_t")
|
||||
/// void operator delete[](void*, align_val_t);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdaPvSt11align_val_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdaPvSt11align_val_t")
|
||||
/// void operator delete[](void*, align_val_t, nothrow)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdaPvSt11align_val_tRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdaPvSt11align_val_tRKSt9nothrow_t")
|
||||
/// void operator delete[](void*, unsigned int);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdaPvj)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdaPvj")
|
||||
@ -131,6 +137,12 @@ TLI_DEFINE_STRING_INTERNAL("_ZdlPv")
|
||||
/// void operator delete(void*, nothrow);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdlPvRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdlPvRKSt9nothrow_t")
|
||||
/// void operator delete(void*, align_val_t)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdlPvSt11align_val_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdlPvSt11align_val_t")
|
||||
/// void operator delete(void*, align_val_t, nothrow)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdlPvSt11align_val_tRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdlPvSt11align_val_tRKSt9nothrow_t")
|
||||
/// void operator delete(void*, unsigned int);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZdlPvj)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZdlPvj")
|
||||
@ -143,24 +155,48 @@ TLI_DEFINE_STRING_INTERNAL("_Znaj")
|
||||
/// void *new[](unsigned int, nothrow);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnajRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnajRKSt9nothrow_t")
|
||||
/// void *new[](unsigned int, align_val_t)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnajSt11align_val_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnajSt11align_val_t")
|
||||
/// void *new[](unsigned int, align_val_t, nothrow)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnajSt11align_val_tRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnajSt11align_val_tRKSt9nothrow_t")
|
||||
/// void *new[](unsigned long);
|
||||
TLI_DEFINE_ENUM_INTERNAL(Znam)
|
||||
TLI_DEFINE_STRING_INTERNAL("_Znam")
|
||||
/// void *new[](unsigned long, nothrow);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnamRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnamRKSt9nothrow_t")
|
||||
/// void *new[](unsigned long, align_val_t)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnamSt11align_val_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnamSt11align_val_t")
|
||||
/// void *new[](unsigned long, align_val_t, nothrow)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnamSt11align_val_tRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnamSt11align_val_tRKSt9nothrow_t")
|
||||
/// void *new(unsigned int);
|
||||
TLI_DEFINE_ENUM_INTERNAL(Znwj)
|
||||
TLI_DEFINE_STRING_INTERNAL("_Znwj")
|
||||
/// void *new(unsigned int, nothrow);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnwjRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnwjRKSt9nothrow_t")
|
||||
/// void *new(unsigned int, align_val_t)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnwjSt11align_val_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnwjSt11align_val_t")
|
||||
/// void *new(unsigned int, align_val_t, nothrow)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnwjSt11align_val_tRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnwjSt11align_val_tRKSt9nothrow_t")
|
||||
/// void *new(unsigned long);
|
||||
TLI_DEFINE_ENUM_INTERNAL(Znwm)
|
||||
TLI_DEFINE_STRING_INTERNAL("_Znwm")
|
||||
/// void *new(unsigned long, nothrow);
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t")
|
||||
/// void *new(unsigned long, align_val_t)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnwmSt11align_val_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnwmSt11align_val_t")
|
||||
/// void *new(unsigned long, align_val_t, nothrow)
|
||||
TLI_DEFINE_ENUM_INTERNAL(ZnwmSt11align_val_tRKSt9nothrow_t)
|
||||
TLI_DEFINE_STRING_INTERNAL("_ZnwmSt11align_val_tRKSt9nothrow_t")
|
||||
/// double __acos_finite(double x);
|
||||
TLI_DEFINE_ENUM_INTERNAL(acos_finite)
|
||||
TLI_DEFINE_STRING_INTERNAL("__acos_finite")
|
||||
|
@ -75,12 +75,24 @@ static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
|
||||
{LibFunc_valloc, {MallocLike, 1, 0, -1}},
|
||||
{LibFunc_Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int)
|
||||
{LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow)
|
||||
{LibFunc_ZnwjSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new(unsigned int, align_val_t)
|
||||
{LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t, // new(unsigned int, align_val_t, nothrow)
|
||||
{MallocLike, 3, 0, -1}},
|
||||
{LibFunc_Znwm, {OpNewLike, 1, 0, -1}}, // new(unsigned long)
|
||||
{LibFunc_ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned long, nothrow)
|
||||
{LibFunc_ZnwmSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new(unsigned long, align_val_t)
|
||||
{LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t, // new(unsigned long, align_val_t, nothrow)
|
||||
{MallocLike, 3, 0, -1}},
|
||||
{LibFunc_Znaj, {OpNewLike, 1, 0, -1}}, // new[](unsigned int)
|
||||
{LibFunc_ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow)
|
||||
{LibFunc_ZnajSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new[](unsigned int, align_val_t)
|
||||
{LibFunc_ZnajSt11align_val_tRKSt9nothrow_t, // new[](unsigned int, align_val_t, nothrow)
|
||||
{MallocLike, 3, 0, -1}},
|
||||
{LibFunc_Znam, {OpNewLike, 1, 0, -1}}, // new[](unsigned long)
|
||||
{LibFunc_ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned long, nothrow)
|
||||
{LibFunc_ZnamSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new[](unsigned long, align_val_t)
|
||||
{LibFunc_ZnamSt11align_val_tRKSt9nothrow_t, // new[](unsigned long, align_val_t, nothrow)
|
||||
{MallocLike, 3, 0, -1}},
|
||||
{LibFunc_msvc_new_int, {OpNewLike, 1, 0, -1}}, // new(unsigned int)
|
||||
{LibFunc_msvc_new_int_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow)
|
||||
{LibFunc_msvc_new_longlong, {OpNewLike, 1, 0, -1}}, // new(unsigned long long)
|
||||
@ -372,9 +384,11 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
|
||||
else if (TLIFn == LibFunc_ZdlPvj || // delete(void*, uint)
|
||||
TLIFn == LibFunc_ZdlPvm || // delete(void*, ulong)
|
||||
TLIFn == LibFunc_ZdlPvRKSt9nothrow_t || // delete(void*, nothrow)
|
||||
TLIFn == LibFunc_ZdlPvSt11align_val_t || // delete(void*, align_val_t)
|
||||
TLIFn == LibFunc_ZdaPvj || // delete[](void*, uint)
|
||||
TLIFn == LibFunc_ZdaPvm || // delete[](void*, ulong)
|
||||
TLIFn == LibFunc_ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow)
|
||||
TLIFn == LibFunc_ZdaPvSt11align_val_t || // delete[](void*, align_val_t)
|
||||
TLIFn == LibFunc_msvc_delete_ptr32_int || // delete(void*, uint)
|
||||
TLIFn == LibFunc_msvc_delete_ptr64_longlong || // delete(void*, ulonglong)
|
||||
TLIFn == LibFunc_msvc_delete_ptr32_nothrow || // delete(void*, nothrow)
|
||||
@ -384,6 +398,9 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
|
||||
TLIFn == LibFunc_msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow)
|
||||
TLIFn == LibFunc_msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow)
|
||||
ExpectedNumParams = 2;
|
||||
else if (TLIFn == LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t || // delete(void*, align_val_t, nothrow)
|
||||
TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t) // delete[](void*, align_val_t, nothrow)
|
||||
ExpectedNumParams = 3;
|
||||
else
|
||||
return nullptr;
|
||||
|
||||
|
@ -992,8 +992,26 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
|
||||
case LibFunc_msvc_new_array_int_nothrow:
|
||||
// new[](unsigned long long, nothrow);
|
||||
case LibFunc_msvc_new_array_longlong_nothrow:
|
||||
// new(unsigned int, align_val_t)
|
||||
case LibFunc_ZnwjSt11align_val_t:
|
||||
// new(unsigned long, align_val_t)
|
||||
case LibFunc_ZnwmSt11align_val_t:
|
||||
// new[](unsigned int, align_val_t)
|
||||
case LibFunc_ZnajSt11align_val_t:
|
||||
// new[](unsigned long, align_val_t)
|
||||
case LibFunc_ZnamSt11align_val_t:
|
||||
return (NumParams == 2 && FTy.getReturnType()->isPointerTy());
|
||||
|
||||
// new(unsigned int, align_val_t, nothrow)
|
||||
case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t:
|
||||
// new(unsigned long, align_val_t, nothrow)
|
||||
case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
|
||||
// new[](unsigned int, align_val_t, nothrow)
|
||||
case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t:
|
||||
// new[](unsigned long, align_val_t, nothrow)
|
||||
case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
|
||||
return (NumParams == 3 && FTy.getReturnType()->isPointerTy());
|
||||
|
||||
// void operator delete[](void*);
|
||||
case LibFunc_ZdaPv:
|
||||
// void operator delete(void*);
|
||||
@ -1020,6 +1038,10 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
|
||||
case LibFunc_ZdlPvj:
|
||||
// void operator delete(void*, unsigned long);
|
||||
case LibFunc_ZdlPvm:
|
||||
// void operator delete(void*, align_val_t)
|
||||
case LibFunc_ZdlPvSt11align_val_t:
|
||||
// void operator delete[](void*, align_val_t)
|
||||
case LibFunc_ZdaPvSt11align_val_t:
|
||||
// void operator delete[](void*, unsigned int);
|
||||
case LibFunc_msvc_delete_array_ptr32_int:
|
||||
// void operator delete[](void*, nothrow);
|
||||
@ -1038,6 +1060,12 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
|
||||
case LibFunc_msvc_delete_ptr64_nothrow:
|
||||
return (NumParams == 2 && FTy.getParamType(0)->isPointerTy());
|
||||
|
||||
// void operator delete(void*, align_val_t, nothrow)
|
||||
case LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t:
|
||||
// void operator delete[](void*, align_val_t, nothrow)
|
||||
case LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t:
|
||||
return (NumParams == 3 && FTy.getParamType(0)->isPointerTy());
|
||||
|
||||
case LibFunc_memset_pattern16:
|
||||
return (!FTy.isVarArg() && NumParams == 3 &&
|
||||
FTy.getParamType(0)->isPointerTy() &&
|
||||
|
@ -173,9 +173,33 @@ define linkonce void @_ZdaPvj(i8* %p, i32) nobuiltin {
|
||||
ret void
|
||||
}
|
||||
|
||||
|
||||
; new(size_t, align_val_t)
|
||||
declare i8* @_ZnwmSt11align_val_t(i64, i64) nobuiltin
|
||||
declare i8* @_ZnwjSt11align_val_t(i32, i32) nobuiltin
|
||||
; new[](size_t, align_val_t)
|
||||
declare i8* @_ZnamSt11align_val_t(i64, i64) nobuiltin
|
||||
declare i8* @_ZnajSt11align_val_t(i32, i32) nobuiltin
|
||||
; new(size_t, align_val_t, nothrow)
|
||||
declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64, i64, i8*) nobuiltin
|
||||
declare i8* @_ZnwjSt11align_val_tRKSt9nothrow_t(i32, i32, i8*) nobuiltin
|
||||
; new[](size_t, align_val_t, nothrow)
|
||||
declare i8* @_ZnamSt11align_val_tRKSt9nothrow_t(i64, i64, i8*) nobuiltin
|
||||
declare i8* @_ZnajSt11align_val_tRKSt9nothrow_t(i32, i32, i8*) nobuiltin
|
||||
; delete(void*, align_val_t)
|
||||
declare void @_ZdlPvSt11align_val_t(i8*, i64) nobuiltin
|
||||
; delete[](void*, align_val_t)
|
||||
declare void @_ZdaPvSt11align_val_t(i8*, i64) nobuiltin
|
||||
; delete(void*, align_val_t, nothrow)
|
||||
declare void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8*, i64, i8*) nobuiltin
|
||||
; delete[](void*, align_val_t, nothrow)
|
||||
declare void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8*, i64, i8*) nobuiltin
|
||||
|
||||
|
||||
; CHECK-LABEL: @test8(
|
||||
define void @test8() {
|
||||
; CHECK-NOT: call
|
||||
%nt = alloca i8
|
||||
%nw = call i8* @_Znwm(i64 32) builtin
|
||||
call void @_ZdlPv(i8* %nw) builtin
|
||||
%na = call i8* @_Znam(i64 32) builtin
|
||||
@ -188,6 +212,22 @@ define void @test8() {
|
||||
call void @_ZdaPvm(i8* %nam, i64 32) builtin
|
||||
%naj = call i8* @_Znaj(i32 32) builtin
|
||||
call void @_ZdaPvj(i8* %naj, i32 32) builtin
|
||||
%nwa = call i8* @_ZnwmSt11align_val_t(i64 32, i64 8) builtin
|
||||
call void @_ZdlPvSt11align_val_t(i8* %nwa, i64 8) builtin
|
||||
%naa = call i8* @_ZnamSt11align_val_t(i64 32, i64 8) builtin
|
||||
call void @_ZdaPvSt11align_val_t(i8* %naa, i64 8) builtin
|
||||
%nwja = call i8* @_ZnwjSt11align_val_t(i32 32, i32 8) builtin
|
||||
call void @_ZdlPvSt11align_val_t(i8* %nwja, i64 8) builtin
|
||||
%naja = call i8* @_ZnajSt11align_val_t(i32 32, i32 8) builtin
|
||||
call void @_ZdaPvSt11align_val_t(i8* %naja, i64 8) builtin
|
||||
%nwat = call i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64 32, i64 8, i8* %nt) builtin
|
||||
call void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8* %nwat, i64 8, i8* %nt) builtin
|
||||
%naat = call i8* @_ZnamSt11align_val_tRKSt9nothrow_t(i64 32, i64 8, i8* %nt) builtin
|
||||
call void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8* %naat, i64 8, i8* %nt) builtin
|
||||
%nwjat = call i8* @_ZnwjSt11align_val_tRKSt9nothrow_t(i32 32, i32 8, i8* %nt) builtin
|
||||
call void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8* %nwjat, i64 8, i8* %nt) builtin
|
||||
%najat = call i8* @_ZnajSt11align_val_tRKSt9nothrow_t(i32 32, i32 8, i8* %nt) builtin
|
||||
call void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8* %najat, i64 8, i8* %nt) builtin
|
||||
ret void
|
||||
}
|
||||
|
||||
|
@ -386,20 +386,32 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
|
||||
|
||||
"declare void @_ZdaPv(i8*)\n"
|
||||
"declare void @_ZdaPvRKSt9nothrow_t(i8*, %struct*)\n"
|
||||
"declare void @_ZdaPvSt11align_val_t(i8*, i64)\n"
|
||||
"declare void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8*, i64, %struct*)\n"
|
||||
"declare void @_ZdaPvj(i8*, i32)\n"
|
||||
"declare void @_ZdaPvm(i8*, i64)\n"
|
||||
"declare void @_ZdlPv(i8*)\n"
|
||||
"declare void @_ZdlPvRKSt9nothrow_t(i8*, %struct*)\n"
|
||||
"declare void @_ZdlPvSt11align_val_t(i8*, i64)\n"
|
||||
"declare void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8*, i64, %struct*)\n"
|
||||
"declare void @_ZdlPvj(i8*, i32)\n"
|
||||
"declare void @_ZdlPvm(i8*, i64)\n"
|
||||
"declare i8* @_Znaj(i32)\n"
|
||||
"declare i8* @_ZnajRKSt9nothrow_t(i32, %struct*)\n"
|
||||
"declare i8* @_ZnajSt11align_val_t(i32, i32)\n"
|
||||
"declare i8* @_ZnajSt11align_val_tRKSt9nothrow_t(i32, i32, %struct*)\n"
|
||||
"declare i8* @_Znam(i64)\n"
|
||||
"declare i8* @_ZnamRKSt9nothrow_t(i64, %struct*)\n"
|
||||
"declare i8* @_ZnamSt11align_val_t(i64, i64)\n"
|
||||
"declare i8* @_ZnamSt11align_val_tRKSt9nothrow_t(i64, i64, %struct*)\n"
|
||||
"declare i8* @_Znwj(i32)\n"
|
||||
"declare i8* @_ZnwjRKSt9nothrow_t(i32, %struct*)\n"
|
||||
"declare i8* @_ZnwjSt11align_val_t(i32, i32)\n"
|
||||
"declare i8* @_ZnwjSt11align_val_tRKSt9nothrow_t(i32, i32, %struct*)\n"
|
||||
"declare i8* @_Znwm(i64)\n"
|
||||
"declare i8* @_ZnwmRKSt9nothrow_t(i64, %struct*)\n"
|
||||
"declare i8* @_ZnwmSt11align_val_t(i64, i64)\n"
|
||||
"declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64, i64, %struct*)\n"
|
||||
|
||||
"declare void @\"??3@YAXPEAX@Z\"(i8*)\n"
|
||||
"declare void @\"??3@YAXPEAXAEBUnothrow_t@std@@@Z\"(i8*, %struct*)\n"
|
||||
|
Loading…
Reference in New Issue
Block a user