summaryrefslogtreecommitdiff
path: root/test/CodeGenObjC
diff options
context:
space:
mode:
authorAkira Hatanaka <ahatanaka@apple.com>2017-09-20 06:22:51 +0000
committerAkira Hatanaka <ahatanaka@apple.com>2017-09-20 06:22:51 +0000
commite077cfd4f9ada87940c24f0feb197492787e40f6 (patch)
tree96c3afc54ecd82000558a3017b242d752d34439c /test/CodeGenObjC
parentcb0d01de81d97f744ef81029b8e013a770b46936 (diff)
Add support for attribute 'noescape'.
The attribute informs the compiler that the annotated pointer parameter of a function cannot escape and enables IRGen to attach attribute 'nocapture' to parameters that are annotated with the attribute. That is the only optimization that currently takes advantage of 'noescape', but there are other optimizations that will be added later that improves IRGen for ObjC blocks. rdar://problem/19886775 Differential Revision: https://reviews.llvm.org/D32520 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@313720 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'test/CodeGenObjC')
-rw-r--r--test/CodeGenObjC/noescape.m71
1 files changed, 71 insertions, 0 deletions
diff --git a/test/CodeGenObjC/noescape.m b/test/CodeGenObjC/noescape.m
new file mode 100644
index 0000000000..8ea2aa94e0
--- /dev/null
+++ b/test/CodeGenObjC/noescape.m
@@ -0,0 +1,71 @@
+// RUN: %clang_cc1 -fblocks -emit-llvm -o - %s | FileCheck %s
+
+typedef void (^BlockTy)(void);
+
+union U {
+ int *i;
+ long long *ll;
+} __attribute__((transparent_union));
+
+void noescapeFunc0(id, __attribute__((noescape)) BlockTy);
+void noescapeFunc1(__attribute__((noescape)) int *);
+void noescapeFunc2(__attribute__((noescape)) id);
+void noescapeFunc3(__attribute__((noescape)) union U);
+
+// CHECK-LABEL: define void @test0(
+// CHECK: call void @noescapeFunc0({{.*}}, {{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc0(i8*, {{.*}} nocapture)
+void test0(BlockTy b) {
+ noescapeFunc0(0, b);
+}
+
+// CHECK-LABEL: define void @test1(
+// CHECK: call void @noescapeFunc1({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc1({{.*}} nocapture)
+void test1(int *i) {
+ noescapeFunc1(i);
+}
+
+// CHECK-LABEL: define void @test2(
+// CHECK: call void @noescapeFunc2({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc2({{.*}} nocapture)
+void test2(id i) {
+ noescapeFunc2(i);
+}
+
+// CHECK-LABEL: define void @test3(
+// CHECK: call void @noescapeFunc3({{.*}} nocapture {{.*}})
+// CHECK: declare void @noescapeFunc3({{.*}} nocapture)
+void test3(union U u) {
+ noescapeFunc3(u);
+}
+
+// CHECK: define internal void @"\01-[C0 m0:]"({{.*}}, {{.*}}, {{.*}} nocapture {{.*}})
+
+// CHECK-LABEL: define void @test4(
+// CHECK: call void bitcast (i8* (i8*, i8*, ...)* @objc_msgSend to void (i8*, i8*, i32*)*)(i8* {{.*}}, i8* {{.*}}, i32* nocapture {{.*}})
+
+@interface C0
+-(void) m0:(int*)__attribute__((noescape)) p0;
+@end
+
+@implementation C0
+-(void) m0:(int*)__attribute__((noescape)) p0 {
+}
+@end
+
+void test4(C0 *c0, int *p) {
+ [c0 m0:p];
+}
+
+// CHECK-LABEL: define void @test5(
+// CHECK: call void {{.*}}(i8* bitcast ({ i8**, i32, i32, i8*, {{.*}} }* @{{.*}} to i8*), i32* nocapture {{.*}})
+// CHECK: call void {{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
+// CHECK: define internal void @{{.*}}(i8* {{.*}}, i32* nocapture {{.*}})
+
+typedef void (^BlockTy2)(__attribute__((noescape)) int *);
+
+void test5(BlockTy2 b, int *p) {
+ ^(int *__attribute__((noescape)) p0){}(p);
+ b(p);
+}