Clang Project

clang_source_code/test/CodeGenCXX/static-initializer-branch-weights.cpp
1// RUN: %clang_cc1 -emit-llvm -std=c++1z %s -o - -triple=x86_64-linux-gnu | FileCheck %s
2
3struct S { S(); ~S(); };
4
5// CHECK-LABEL: define {{.*}}global_var_init
6// CHECK-NOT: br
7// CHECK: call void @_ZN1SC1Ev({{.*}}* @global)
8S global;
9
10// CHECK-LABEL: define {{.*}}global_var_init
11// FIXME: Do we really need thread-safe initialization here? We don't run
12// global ctors on multiple threads. (If we were to do so, we'd need thread-safe
13// init for B<int>::member and B<int>::inline_member too.)
14// CHECK: load atomic i8, i8* bitcast (i64* @_ZGV13inline_global to i8*) acquire,
15// CHECK: icmp eq i8 {{.*}}, 0
16// CHECK: br i1
17// CHECK-NOT: !prof
18// CHECK: call void @_ZN1SC1Ev({{.*}}* @inline_global)
19inline S inline_global;
20
21// CHECK-LABEL: define {{.*}}global_var_init
22// CHECK-NOT: br
23// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_global)
24thread_local S thread_local_global;
25
26// CHECK-LABEL: define {{.*}}global_var_init
27// CHECK: load i8, i8* bitcast (i64* @_ZGV26thread_local_inline_global to i8*)
28// CHECK: icmp eq i8 {{.*}}, 0
29// CHECK: br i1
30// CHECK-NOT: !prof
31// CHECK: call void @_ZN1SC1Ev({{.*}}* @thread_local_inline_global)
32thread_local inline S thread_local_inline_global;
33
34struct A {
35  static S member;
36  static thread_local S thread_local_member;
37
38  // CHECK-LABEL: define {{.*}}global_var_init
39  // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVN1A13inline_memberE to i8*) acquire,
40  // CHECK: icmp eq i8 {{.*}}, 0
41  // CHECK: br i1
42  // CHECK-NOT: !prof
43  // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A13inline_memberE)
44  static inline S inline_member;
45
46  // CHECK-LABEL: define {{.*}}global_var_init
47  // CHECK: load i8, i8* bitcast (i64* @_ZGVN1A26thread_local_inline_memberE to i8*)
48  // CHECK: icmp eq i8 {{.*}}, 0
49  // CHECK: br i1
50  // CHECK-NOT: !prof
51  // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A26thread_local_inline_memberE)
52  static thread_local inline S thread_local_inline_member;
53};
54
55// CHECK-LABEL: define void @_Z1fv()
56void f() {
57  // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZ1fvE12static_local to i8*) acquire,
58  // CHECK: icmp eq i8 {{.*}}, 0
59  // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_LOCAL:[0-9]*]]
60  static S static_local;
61
62  // CHECK: load i8, i8* @_ZGVZ1fvE19static_thread_local,
63  // CHECK: icmp eq i8 {{.*}}, 0
64  // CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL:[0-9]*]]
65  static thread_local S static_thread_local;
66}
67
68// CHECK-LABEL: define {{.*}}global_var_init
69// CHECK-NOT: br
70// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A6memberE)
71S A::member;
72
73// CHECK-LABEL: define {{.*}}global_var_init
74// CHECK-NOT: br
75// CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1A19thread_local_memberE)
76thread_local S A::thread_local_member;
77
78template <typename T> struct B {
79  // CHECK-LABEL: define {{.*}}global_var_init
80  // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE6memberE to i8*)
81  // CHECK: icmp eq i8 {{.*}}, 0
82  // CHECK: br i1
83  // CHECK-NOT: !prof
84  // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE6memberE)
85  static S member;
86
87  // CHECK-LABEL: define {{.*}}global_var_init
88  // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE13inline_memberE to i8*)
89  // CHECK: icmp eq i8 {{.*}}, 0
90  // CHECK: br i1
91  // CHECK-NOT: !prof
92  // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE13inline_memberE)
93  static inline S inline_member;
94
95  // CHECK-LABEL: define {{.*}}global_var_init
96  // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE19thread_local_memberE to i8*)
97  // CHECK: icmp eq i8 {{.*}}, 0
98  // CHECK: br i1
99  // CHECK-NOT: !prof
100  // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE19thread_local_memberE)
101  static thread_local S thread_local_member;
102
103  // CHECK-LABEL: define {{.*}}global_var_init
104  // CHECK: load i8, i8* bitcast (i64* @_ZGVN1BIiE26thread_local_inline_memberE to i8*)
105  // CHECK: icmp eq i8 {{.*}}, 0
106  // CHECK: br i1
107  // CHECK-NOT: !prof
108  // CHECK: call void @_ZN1SC1Ev({{.*}}* @_ZN1BIiE26thread_local_inline_memberE)
109  static thread_local inline S thread_local_inline_member;
110};
111template<typename T> S B<T>::member;
112template<typename T> thread_local S B<T>::thread_local_member;
113
114template<typename ...T> void use(T &...);
115void use_b() {
116  use(B<int>::member, B<int>::inline_member, B<int>::thread_local_member,
117      B<int>::thread_local_inline_member);
118}
119
120// CHECK-LABEL: define {{.*}}tls_init()
121// CHECK: load i8, i8* @__tls_guard, align 1
122// CHECK: icmp eq i8 {{.*}}, 0
123// CHECK: br i1 {{.*}}, !prof ![[WEIGHTS_THREAD_LOCAL]]
124
125// CHECK-DAG: ![[WEIGHTS_THREAD_LOCAL]] = !{!"branch_weights", i32 1, i32 1023}
126// CHECK-DAG: ![[WEIGHTS_LOCAL]] = !{!"branch_weights", i32 1, i32 1048575}
127