diff options
author | Akira Hatanaka <ahatanaka@apple.com> | 2018-08-10 15:09:24 +0000 |
---|---|---|
committer | Akira Hatanaka <ahatanaka@apple.com> | 2018-08-10 15:09:24 +0000 |
commit | 9978da3615f9d29d1f59858a0d53fedb70570095 (patch) | |
tree | 395a03bcdc2bb84c41514d34476a62c8c5218537 /clang/test/CodeGenCXX/block-byref-cxx-objc.cpp | |
parent | 70fcafc09644c8f9ea39edebe5fa2c63a47b6ee4 (diff) | |
download | bcm5719-llvm-9978da3615f9d29d1f59858a0d53fedb70570095.tar.gz bcm5719-llvm-9978da3615f9d29d1f59858a0d53fedb70570095.zip |
[CodeGen] Merge equivalent block copy/helper functions.
Clang generates copy and dispose helper functions for each block literal
on the stack. Often these functions are equivalent for different blocks.
This commit makes changes to merge equivalent copy and dispose helper
functions and reduce code size.
To enable merging equivalent copy/dispose functions, the captured object
infomation is encoded into the helper function name. This allows IRGen
to check whether an equivalent helper function has already been emitted
and reuse the function instead of generating a new helper function
whenever a block is defined. In addition, the helper functions are
marked as linkonce_odr to enable merging helper functions that have the
same name across translation units and marked as unnamed_addr to enable
the linker's deduplication pass to merge functions that have different
names but the same content.
rdar://problem/42640608
Differential Revision: https://reviews.llvm.org/D50152
llvm-svn: 339438
Diffstat (limited to 'clang/test/CodeGenCXX/block-byref-cxx-objc.cpp')
-rw-r--r-- | clang/test/CodeGenCXX/block-byref-cxx-objc.cpp | 48 |
1 files changed, 38 insertions, 10 deletions
diff --git a/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp b/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp index ce1ebd615ef..208a5c51601 100644 --- a/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp +++ b/clang/test/CodeGenCXX/block-byref-cxx-objc.cpp @@ -1,17 +1,23 @@ -// RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - -fblocks | FileCheck %s +// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -triple %itanium_abi_triple -o - -fblocks -fexceptions | FileCheck %s // rdar://8594790 struct A { int x; A(const A &); A(); - ~A(); + ~A() noexcept(false); }; -int main() -{ - __block A BYREF_VAR; - ^{ BYREF_VAR.x = 1234; }; +struct B { + int x; + B(const B &); + B(); + ~B(); +}; + +int testA() { + __block A a0, a1; + ^{ a0.x = 1234; a1.x = 5678; }; return 0; } @@ -19,10 +25,32 @@ int main() // CHECK: call {{.*}} @_ZN1AC1ERKS_ // CHECK-LABEL: define internal void @__Block_byref_object_dispose_ // CHECK: call {{.*}} @_ZN1AD1Ev -// CHECK-LABEL: define internal void @__copy_helper_block_ -// CHECK: call {{.*}}void @_Block_object_assign -// CHECK-LABEL: define internal void @__destroy_helper_block_ -// CHECK: call {{.*}}void @_Block_object_dispose + +// CHECK-LABEL: define linkonce_odr hidden void @__copy_helper_block_e8_32rc40rc( +// CHECK: call void @_Block_object_assign( +// CHECK: invoke void @_Block_object_assign( +// CHECK: call void @_Block_object_dispose({{.*}}) #[[NOUNWIND_ATTR:[0-9]+]] + +// CHECK-LABEL: define linkonce_odr hidden void @__destroy_helper_block_e8_32rd40rd( +// CHECK: invoke void @_Block_object_dispose( +// CHECK: call void @_Block_object_dispose( +// CHECK: invoke void @_Block_object_dispose( + +int testB() { + __block B b0, b1; + ^{ b0.x = 1234; b1.x = 5678; }; + return 0; +} + +// CHECK-LABEL: define internal void @__Block_byref_object_copy_ +// CHECK: call {{.*}} @_ZN1BC1ERKS_ +// CHECK-LABEL: define internal void @__Block_byref_object_dispose_ +// CHECK: call {{.*}} @_ZN1BD1Ev + +// CHECK-NOT: define{{.*}}@__copy_helper_block +// CHECK: define linkonce_odr hidden void @__destroy_helper_block_e8_32r40r( + +// CHECK: attributes #[[NOUNWIND_ATTR]] = {{{.*}}nounwind{{.*}}} // rdar://problem/11135650 namespace test1 { |