Skip to content

Commit 96bbec7

Browse files
committedApr 4, 2018
[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
1 parent e03d45f commit 96bbec7

File tree

5 files changed

+133
-0
lines changed

5 files changed

+133
-0
lines changed
 

Diff for: ‎llvm/include/llvm/Analysis/TargetLibraryInfo.def

+36
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ TLI_DEFINE_STRING_INTERNAL("_ZdaPv")
119119
/// void operator delete[](void*, nothrow);
120120
TLI_DEFINE_ENUM_INTERNAL(ZdaPvRKSt9nothrow_t)
121121
TLI_DEFINE_STRING_INTERNAL("_ZdaPvRKSt9nothrow_t")
122+
/// void operator delete[](void*, align_val_t);
123+
TLI_DEFINE_ENUM_INTERNAL(ZdaPvSt11align_val_t)
124+
TLI_DEFINE_STRING_INTERNAL("_ZdaPvSt11align_val_t")
125+
/// void operator delete[](void*, align_val_t, nothrow)
126+
TLI_DEFINE_ENUM_INTERNAL(ZdaPvSt11align_val_tRKSt9nothrow_t)
127+
TLI_DEFINE_STRING_INTERNAL("_ZdaPvSt11align_val_tRKSt9nothrow_t")
122128
/// void operator delete[](void*, unsigned int);
123129
TLI_DEFINE_ENUM_INTERNAL(ZdaPvj)
124130
TLI_DEFINE_STRING_INTERNAL("_ZdaPvj")
@@ -131,6 +137,12 @@ TLI_DEFINE_STRING_INTERNAL("_ZdlPv")
131137
/// void operator delete(void*, nothrow);
132138
TLI_DEFINE_ENUM_INTERNAL(ZdlPvRKSt9nothrow_t)
133139
TLI_DEFINE_STRING_INTERNAL("_ZdlPvRKSt9nothrow_t")
140+
/// void operator delete(void*, align_val_t)
141+
TLI_DEFINE_ENUM_INTERNAL(ZdlPvSt11align_val_t)
142+
TLI_DEFINE_STRING_INTERNAL("_ZdlPvSt11align_val_t")
143+
/// void operator delete(void*, align_val_t, nothrow)
144+
TLI_DEFINE_ENUM_INTERNAL(ZdlPvSt11align_val_tRKSt9nothrow_t)
145+
TLI_DEFINE_STRING_INTERNAL("_ZdlPvSt11align_val_tRKSt9nothrow_t")
134146
/// void operator delete(void*, unsigned int);
135147
TLI_DEFINE_ENUM_INTERNAL(ZdlPvj)
136148
TLI_DEFINE_STRING_INTERNAL("_ZdlPvj")
@@ -143,24 +155,48 @@ TLI_DEFINE_STRING_INTERNAL("_Znaj")
143155
/// void *new[](unsigned int, nothrow);
144156
TLI_DEFINE_ENUM_INTERNAL(ZnajRKSt9nothrow_t)
145157
TLI_DEFINE_STRING_INTERNAL("_ZnajRKSt9nothrow_t")
158+
/// void *new[](unsigned int, align_val_t)
159+
TLI_DEFINE_ENUM_INTERNAL(ZnajSt11align_val_t)
160+
TLI_DEFINE_STRING_INTERNAL("_ZnajSt11align_val_t")
161+
/// void *new[](unsigned int, align_val_t, nothrow)
162+
TLI_DEFINE_ENUM_INTERNAL(ZnajSt11align_val_tRKSt9nothrow_t)
163+
TLI_DEFINE_STRING_INTERNAL("_ZnajSt11align_val_tRKSt9nothrow_t")
146164
/// void *new[](unsigned long);
147165
TLI_DEFINE_ENUM_INTERNAL(Znam)
148166
TLI_DEFINE_STRING_INTERNAL("_Znam")
149167
/// void *new[](unsigned long, nothrow);
150168
TLI_DEFINE_ENUM_INTERNAL(ZnamRKSt9nothrow_t)
151169
TLI_DEFINE_STRING_INTERNAL("_ZnamRKSt9nothrow_t")
170+
/// void *new[](unsigned long, align_val_t)
171+
TLI_DEFINE_ENUM_INTERNAL(ZnamSt11align_val_t)
172+
TLI_DEFINE_STRING_INTERNAL("_ZnamSt11align_val_t")
173+
/// void *new[](unsigned long, align_val_t, nothrow)
174+
TLI_DEFINE_ENUM_INTERNAL(ZnamSt11align_val_tRKSt9nothrow_t)
175+
TLI_DEFINE_STRING_INTERNAL("_ZnamSt11align_val_tRKSt9nothrow_t")
152176
/// void *new(unsigned int);
153177
TLI_DEFINE_ENUM_INTERNAL(Znwj)
154178
TLI_DEFINE_STRING_INTERNAL("_Znwj")
155179
/// void *new(unsigned int, nothrow);
156180
TLI_DEFINE_ENUM_INTERNAL(ZnwjRKSt9nothrow_t)
157181
TLI_DEFINE_STRING_INTERNAL("_ZnwjRKSt9nothrow_t")
182+
/// void *new(unsigned int, align_val_t)
183+
TLI_DEFINE_ENUM_INTERNAL(ZnwjSt11align_val_t)
184+
TLI_DEFINE_STRING_INTERNAL("_ZnwjSt11align_val_t")
185+
/// void *new(unsigned int, align_val_t, nothrow)
186+
TLI_DEFINE_ENUM_INTERNAL(ZnwjSt11align_val_tRKSt9nothrow_t)
187+
TLI_DEFINE_STRING_INTERNAL("_ZnwjSt11align_val_tRKSt9nothrow_t")
158188
/// void *new(unsigned long);
159189
TLI_DEFINE_ENUM_INTERNAL(Znwm)
160190
TLI_DEFINE_STRING_INTERNAL("_Znwm")
161191
/// void *new(unsigned long, nothrow);
162192
TLI_DEFINE_ENUM_INTERNAL(ZnwmRKSt9nothrow_t)
163193
TLI_DEFINE_STRING_INTERNAL("_ZnwmRKSt9nothrow_t")
194+
/// void *new(unsigned long, align_val_t)
195+
TLI_DEFINE_ENUM_INTERNAL(ZnwmSt11align_val_t)
196+
TLI_DEFINE_STRING_INTERNAL("_ZnwmSt11align_val_t")
197+
/// void *new(unsigned long, align_val_t, nothrow)
198+
TLI_DEFINE_ENUM_INTERNAL(ZnwmSt11align_val_tRKSt9nothrow_t)
199+
TLI_DEFINE_STRING_INTERNAL("_ZnwmSt11align_val_tRKSt9nothrow_t")
164200
/// double __acos_finite(double x);
165201
TLI_DEFINE_ENUM_INTERNAL(acos_finite)
166202
TLI_DEFINE_STRING_INTERNAL("__acos_finite")

Diff for: ‎llvm/lib/Analysis/MemoryBuiltins.cpp

+17
Original file line numberDiff line numberDiff line change
@@ -75,12 +75,24 @@ static const std::pair<LibFunc, AllocFnsTy> AllocationFnData[] = {
7575
{LibFunc_valloc, {MallocLike, 1, 0, -1}},
7676
{LibFunc_Znwj, {OpNewLike, 1, 0, -1}}, // new(unsigned int)
7777
{LibFunc_ZnwjRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow)
78+
{LibFunc_ZnwjSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new(unsigned int, align_val_t)
79+
{LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t, // new(unsigned int, align_val_t, nothrow)
80+
{MallocLike, 3, 0, -1}},
7881
{LibFunc_Znwm, {OpNewLike, 1, 0, -1}}, // new(unsigned long)
7982
{LibFunc_ZnwmRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new(unsigned long, nothrow)
83+
{LibFunc_ZnwmSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new(unsigned long, align_val_t)
84+
{LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t, // new(unsigned long, align_val_t, nothrow)
85+
{MallocLike, 3, 0, -1}},
8086
{LibFunc_Znaj, {OpNewLike, 1, 0, -1}}, // new[](unsigned int)
8187
{LibFunc_ZnajRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned int, nothrow)
88+
{LibFunc_ZnajSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new[](unsigned int, align_val_t)
89+
{LibFunc_ZnajSt11align_val_tRKSt9nothrow_t, // new[](unsigned int, align_val_t, nothrow)
90+
{MallocLike, 3, 0, -1}},
8291
{LibFunc_Znam, {OpNewLike, 1, 0, -1}}, // new[](unsigned long)
8392
{LibFunc_ZnamRKSt9nothrow_t, {MallocLike, 2, 0, -1}}, // new[](unsigned long, nothrow)
93+
{LibFunc_ZnamSt11align_val_t, {OpNewLike, 2, 0, -1}}, // new[](unsigned long, align_val_t)
94+
{LibFunc_ZnamSt11align_val_tRKSt9nothrow_t, // new[](unsigned long, align_val_t, nothrow)
95+
{MallocLike, 3, 0, -1}},
8496
{LibFunc_msvc_new_int, {OpNewLike, 1, 0, -1}}, // new(unsigned int)
8597
{LibFunc_msvc_new_int_nothrow, {MallocLike, 2, 0, -1}}, // new(unsigned int, nothrow)
8698
{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) {
372384
else if (TLIFn == LibFunc_ZdlPvj || // delete(void*, uint)
373385
TLIFn == LibFunc_ZdlPvm || // delete(void*, ulong)
374386
TLIFn == LibFunc_ZdlPvRKSt9nothrow_t || // delete(void*, nothrow)
387+
TLIFn == LibFunc_ZdlPvSt11align_val_t || // delete(void*, align_val_t)
375388
TLIFn == LibFunc_ZdaPvj || // delete[](void*, uint)
376389
TLIFn == LibFunc_ZdaPvm || // delete[](void*, ulong)
377390
TLIFn == LibFunc_ZdaPvRKSt9nothrow_t || // delete[](void*, nothrow)
391+
TLIFn == LibFunc_ZdaPvSt11align_val_t || // delete[](void*, align_val_t)
378392
TLIFn == LibFunc_msvc_delete_ptr32_int || // delete(void*, uint)
379393
TLIFn == LibFunc_msvc_delete_ptr64_longlong || // delete(void*, ulonglong)
380394
TLIFn == LibFunc_msvc_delete_ptr32_nothrow || // delete(void*, nothrow)
@@ -384,6 +398,9 @@ const CallInst *llvm::isFreeCall(const Value *I, const TargetLibraryInfo *TLI) {
384398
TLIFn == LibFunc_msvc_delete_array_ptr32_nothrow || // delete[](void*, nothrow)
385399
TLIFn == LibFunc_msvc_delete_array_ptr64_nothrow) // delete[](void*, nothrow)
386400
ExpectedNumParams = 2;
401+
else if (TLIFn == LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t || // delete(void*, align_val_t, nothrow)
402+
TLIFn == LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t) // delete[](void*, align_val_t, nothrow)
403+
ExpectedNumParams = 3;
387404
else
388405
return nullptr;
389406

Diff for: ‎llvm/lib/Analysis/TargetLibraryInfo.cpp

+28
Original file line numberDiff line numberDiff line change
@@ -992,8 +992,26 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
992992
case LibFunc_msvc_new_array_int_nothrow:
993993
// new[](unsigned long long, nothrow);
994994
case LibFunc_msvc_new_array_longlong_nothrow:
995+
// new(unsigned int, align_val_t)
996+
case LibFunc_ZnwjSt11align_val_t:
997+
// new(unsigned long, align_val_t)
998+
case LibFunc_ZnwmSt11align_val_t:
999+
// new[](unsigned int, align_val_t)
1000+
case LibFunc_ZnajSt11align_val_t:
1001+
// new[](unsigned long, align_val_t)
1002+
case LibFunc_ZnamSt11align_val_t:
9951003
return (NumParams == 2 && FTy.getReturnType()->isPointerTy());
9961004

1005+
// new(unsigned int, align_val_t, nothrow)
1006+
case LibFunc_ZnwjSt11align_val_tRKSt9nothrow_t:
1007+
// new(unsigned long, align_val_t, nothrow)
1008+
case LibFunc_ZnwmSt11align_val_tRKSt9nothrow_t:
1009+
// new[](unsigned int, align_val_t, nothrow)
1010+
case LibFunc_ZnajSt11align_val_tRKSt9nothrow_t:
1011+
// new[](unsigned long, align_val_t, nothrow)
1012+
case LibFunc_ZnamSt11align_val_tRKSt9nothrow_t:
1013+
return (NumParams == 3 && FTy.getReturnType()->isPointerTy());
1014+
9971015
// void operator delete[](void*);
9981016
case LibFunc_ZdaPv:
9991017
// void operator delete(void*);
@@ -1020,6 +1038,10 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
10201038
case LibFunc_ZdlPvj:
10211039
// void operator delete(void*, unsigned long);
10221040
case LibFunc_ZdlPvm:
1041+
// void operator delete(void*, align_val_t)
1042+
case LibFunc_ZdlPvSt11align_val_t:
1043+
// void operator delete[](void*, align_val_t)
1044+
case LibFunc_ZdaPvSt11align_val_t:
10231045
// void operator delete[](void*, unsigned int);
10241046
case LibFunc_msvc_delete_array_ptr32_int:
10251047
// void operator delete[](void*, nothrow);
@@ -1038,6 +1060,12 @@ bool TargetLibraryInfoImpl::isValidProtoForLibFunc(const FunctionType &FTy,
10381060
case LibFunc_msvc_delete_ptr64_nothrow:
10391061
return (NumParams == 2 && FTy.getParamType(0)->isPointerTy());
10401062

1063+
// void operator delete(void*, align_val_t, nothrow)
1064+
case LibFunc_ZdlPvSt11align_val_tRKSt9nothrow_t:
1065+
// void operator delete[](void*, align_val_t, nothrow)
1066+
case LibFunc_ZdaPvSt11align_val_tRKSt9nothrow_t:
1067+
return (NumParams == 3 && FTy.getParamType(0)->isPointerTy());
1068+
10411069
case LibFunc_memset_pattern16:
10421070
return (!FTy.isVarArg() && NumParams == 3 &&
10431071
FTy.getParamType(0)->isPointerTy() &&

Diff for: ‎llvm/test/Transforms/InstCombine/malloc-free-delete.ll

+40
Original file line numberDiff line numberDiff line change
@@ -173,9 +173,33 @@ define linkonce void @_ZdaPvj(i8* %p, i32) nobuiltin {
173173
ret void
174174
}
175175

176+
177+
; new(size_t, align_val_t)
178+
declare i8* @_ZnwmSt11align_val_t(i64, i64) nobuiltin
179+
declare i8* @_ZnwjSt11align_val_t(i32, i32) nobuiltin
180+
; new[](size_t, align_val_t)
181+
declare i8* @_ZnamSt11align_val_t(i64, i64) nobuiltin
182+
declare i8* @_ZnajSt11align_val_t(i32, i32) nobuiltin
183+
; new(size_t, align_val_t, nothrow)
184+
declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64, i64, i8*) nobuiltin
185+
declare i8* @_ZnwjSt11align_val_tRKSt9nothrow_t(i32, i32, i8*) nobuiltin
186+
; new[](size_t, align_val_t, nothrow)
187+
declare i8* @_ZnamSt11align_val_tRKSt9nothrow_t(i64, i64, i8*) nobuiltin
188+
declare i8* @_ZnajSt11align_val_tRKSt9nothrow_t(i32, i32, i8*) nobuiltin
189+
; delete(void*, align_val_t)
190+
declare void @_ZdlPvSt11align_val_t(i8*, i64) nobuiltin
191+
; delete[](void*, align_val_t)
192+
declare void @_ZdaPvSt11align_val_t(i8*, i64) nobuiltin
193+
; delete(void*, align_val_t, nothrow)
194+
declare void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8*, i64, i8*) nobuiltin
195+
; delete[](void*, align_val_t, nothrow)
196+
declare void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8*, i64, i8*) nobuiltin
197+
198+
176199
; CHECK-LABEL: @test8(
177200
define void @test8() {
178201
; CHECK-NOT: call
202+
%nt = alloca i8
179203
%nw = call i8* @_Znwm(i64 32) builtin
180204
call void @_ZdlPv(i8* %nw) builtin
181205
%na = call i8* @_Znam(i64 32) builtin
@@ -188,6 +212,22 @@ define void @test8() {
188212
call void @_ZdaPvm(i8* %nam, i64 32) builtin
189213
%naj = call i8* @_Znaj(i32 32) builtin
190214
call void @_ZdaPvj(i8* %naj, i32 32) builtin
215+
%nwa = call i8* @_ZnwmSt11align_val_t(i64 32, i64 8) builtin
216+
call void @_ZdlPvSt11align_val_t(i8* %nwa, i64 8) builtin
217+
%naa = call i8* @_ZnamSt11align_val_t(i64 32, i64 8) builtin
218+
call void @_ZdaPvSt11align_val_t(i8* %naa, i64 8) builtin
219+
%nwja = call i8* @_ZnwjSt11align_val_t(i32 32, i32 8) builtin
220+
call void @_ZdlPvSt11align_val_t(i8* %nwja, i64 8) builtin
221+
%naja = call i8* @_ZnajSt11align_val_t(i32 32, i32 8) builtin
222+
call void @_ZdaPvSt11align_val_t(i8* %naja, i64 8) builtin
223+
%nwat = call i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64 32, i64 8, i8* %nt) builtin
224+
call void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8* %nwat, i64 8, i8* %nt) builtin
225+
%naat = call i8* @_ZnamSt11align_val_tRKSt9nothrow_t(i64 32, i64 8, i8* %nt) builtin
226+
call void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8* %naat, i64 8, i8* %nt) builtin
227+
%nwjat = call i8* @_ZnwjSt11align_val_tRKSt9nothrow_t(i32 32, i32 8, i8* %nt) builtin
228+
call void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8* %nwjat, i64 8, i8* %nt) builtin
229+
%najat = call i8* @_ZnajSt11align_val_tRKSt9nothrow_t(i32 32, i32 8, i8* %nt) builtin
230+
call void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8* %najat, i64 8, i8* %nt) builtin
191231
ret void
192232
}
193233

Diff for: ‎llvm/unittests/Analysis/TargetLibraryInfoTest.cpp

+12
Original file line numberDiff line numberDiff line change
@@ -386,20 +386,32 @@ TEST_F(TargetLibraryInfoTest, ValidProto) {
386386

387387
"declare void @_ZdaPv(i8*)\n"
388388
"declare void @_ZdaPvRKSt9nothrow_t(i8*, %struct*)\n"
389+
"declare void @_ZdaPvSt11align_val_t(i8*, i64)\n"
390+
"declare void @_ZdaPvSt11align_val_tRKSt9nothrow_t(i8*, i64, %struct*)\n"
389391
"declare void @_ZdaPvj(i8*, i32)\n"
390392
"declare void @_ZdaPvm(i8*, i64)\n"
391393
"declare void @_ZdlPv(i8*)\n"
392394
"declare void @_ZdlPvRKSt9nothrow_t(i8*, %struct*)\n"
395+
"declare void @_ZdlPvSt11align_val_t(i8*, i64)\n"
396+
"declare void @_ZdlPvSt11align_val_tRKSt9nothrow_t(i8*, i64, %struct*)\n"
393397
"declare void @_ZdlPvj(i8*, i32)\n"
394398
"declare void @_ZdlPvm(i8*, i64)\n"
395399
"declare i8* @_Znaj(i32)\n"
396400
"declare i8* @_ZnajRKSt9nothrow_t(i32, %struct*)\n"
401+
"declare i8* @_ZnajSt11align_val_t(i32, i32)\n"
402+
"declare i8* @_ZnajSt11align_val_tRKSt9nothrow_t(i32, i32, %struct*)\n"
397403
"declare i8* @_Znam(i64)\n"
398404
"declare i8* @_ZnamRKSt9nothrow_t(i64, %struct*)\n"
405+
"declare i8* @_ZnamSt11align_val_t(i64, i64)\n"
406+
"declare i8* @_ZnamSt11align_val_tRKSt9nothrow_t(i64, i64, %struct*)\n"
399407
"declare i8* @_Znwj(i32)\n"
400408
"declare i8* @_ZnwjRKSt9nothrow_t(i32, %struct*)\n"
409+
"declare i8* @_ZnwjSt11align_val_t(i32, i32)\n"
410+
"declare i8* @_ZnwjSt11align_val_tRKSt9nothrow_t(i32, i32, %struct*)\n"
401411
"declare i8* @_Znwm(i64)\n"
402412
"declare i8* @_ZnwmRKSt9nothrow_t(i64, %struct*)\n"
413+
"declare i8* @_ZnwmSt11align_val_t(i64, i64)\n"
414+
"declare i8* @_ZnwmSt11align_val_tRKSt9nothrow_t(i64, i64, %struct*)\n"
403415

404416
"declare void @\"??3@YAXPEAX@Z\"(i8*)\n"
405417
"declare void @\"??3@YAXPEAXAEBUnothrow_t@std@@@Z\"(i8*, %struct*)\n"

0 commit comments

Comments
 (0)
Please sign in to comment.