1 | // REQUIRES: lld-available |
2 | |
3 | // Building the instrumented binary will fail because lld doesn't support |
4 | // big-endian ELF for PPC (aka ABI 1). |
5 | // ld.lld: error: /lib/../lib64/Scrt1.o: ABI version 1 is not supported |
6 | // UNSUPPORTED: ppc && host-byteorder-big-endian |
7 | |
8 | // RUN: %clangxx_pgogen -fuse-ld=lld -O2 -g -fprofile-generate=. -mllvm -enable-vtable-value-profiling %s -o %t-test |
9 | // RUN: env LLVM_PROFILE_FILE=%t-test.profraw %t-test |
10 | |
11 | // Show vtable profiles from raw profile. |
12 | // RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-test.profraw | FileCheck %s --check-prefixes=COMMON,RAW |
13 | |
14 | // Generate indexed profile from raw profile and show the data. |
15 | // RUN: llvm-profdata merge %t-test.profraw -o %t-test.profdata |
16 | // RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-test.profdata | FileCheck %s --check-prefixes=COMMON,INDEXED |
17 | |
18 | // Generate text profile from raw and indexed profiles respectively and show the data. |
19 | // RUN: llvm-profdata merge --text %t-test.profraw -o %t-raw.proftext |
20 | // RUN: llvm-profdata show --function=main --ic-targets --show-vtables --text %t-raw.proftext | FileCheck %s --check-prefix=ICTEXT |
21 | // RUN: llvm-profdata merge --text %t-test.profdata -o %t-indexed.proftext |
22 | // RUN: llvm-profdata show --function=main --ic-targets --show-vtables --text %t-indexed.proftext | FileCheck %s --check-prefix=ICTEXT |
23 | |
24 | // Generate indexed profile from text profiles and show the data |
25 | // RUN: llvm-profdata merge --binary %t-raw.proftext -o %t-text.profraw |
26 | // RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-text.profraw | FileCheck %s --check-prefixes=COMMON,INDEXED |
27 | // RUN: llvm-profdata merge --binary %t-indexed.proftext -o %t-text.profdata |
28 | // RUN: llvm-profdata show --function=main --ic-targets --show-vtables %t-text.profdata | FileCheck %s --check-prefixes=COMMON,INDEXED |
29 | |
30 | // COMMON: Counters: |
31 | // COMMON-NEXT: main: |
32 | // COMMON-NEXT: Hash: 0x0f9a16fe6d398548 |
33 | // COMMON-NEXT: Counters: 2 |
34 | // COMMON-NEXT: Indirect Call Site Count: 2 |
35 | // COMMON-NEXT: Number of instrumented vtables: 2 |
36 | // RAW: Indirect Target Results: |
37 | // RAW-NEXT: [ 0, _ZN8Derived15func1Eii, 250 ] (25.00%) |
38 | // RAW-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func1Eii, 750 ] (75.00%) |
39 | // RAW-NEXT: [ 1, _ZN8Derived15func2Eii, 250 ] (25.00%) |
40 | // RAW-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func2Eii, 750 ] (75.00%) |
41 | // RAW-NEXT: VTable Results: |
42 | // RAW-NEXT: [ 0, _ZTV8Derived1, 250 ] (25.00%) |
43 | // RAW-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%) |
44 | // RAW-NEXT: [ 1, _ZTV8Derived1, 250 ] (25.00%) |
45 | // RAW-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%) |
46 | // INDEXED: Indirect Target Results: |
47 | // INDEXED-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func1Eii, 750 ] (75.00%) |
48 | // INDEXED-NEXT: [ 0, _ZN8Derived15func1Eii, 250 ] (25.00%) |
49 | // INDEXED-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func2Eii, 750 ] (75.00%) |
50 | // INDEXED-NEXT: [ 1, _ZN8Derived15func2Eii, 250 ] (25.00%) |
51 | // INDEXED-NEXT: VTable Results: |
52 | // INDEXED-NEXT: [ 0, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%) |
53 | // INDEXED-NEXT: [ 0, _ZTV8Derived1, 250 ] (25.00%) |
54 | // INDEXED-NEXT: [ 1, {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E, 750 ] (75.00%) |
55 | // INDEXED-NEXT: [ 1, _ZTV8Derived1, 250 ] (25.00%) |
56 | // COMMON: Instrumentation level: IR entry_first = 0 |
57 | // COMMON-NEXT: Functions shown: 1 |
58 | // COMMON-NEXT: Total functions: 6 |
59 | // COMMON-NEXT: Maximum function count: 1000 |
60 | // COMMON-NEXT: Maximum internal block count: 250 |
61 | // COMMON-NEXT: Statistics for indirect call sites profile: |
62 | // COMMON-NEXT: Total number of sites: 2 |
63 | // COMMON-NEXT: Total number of sites with values: 2 |
64 | // COMMON-NEXT: Total number of profiled values: 4 |
65 | // COMMON-NEXT: Value sites histogram: |
66 | // COMMON-NEXT: NumTargets, SiteCount |
67 | // COMMON-NEXT: 2, 2 |
68 | // COMMON-NEXT: Statistics for vtable profile: |
69 | // COMMON-NEXT: Total number of sites: 2 |
70 | // COMMON-NEXT: Total number of sites with values: 2 |
71 | // COMMON-NEXT: Total number of profiled values: 4 |
72 | // COMMON-NEXT: Value sites histogram: |
73 | // COMMON-NEXT: NumTargets, SiteCount |
74 | // COMMON-NEXT: 2, 2 |
75 | |
76 | // ICTEXT: :ir |
77 | // ICTEXT: main |
78 | // ICTEXT: # Func Hash: |
79 | // ICTEXT: 1124236338992350536 |
80 | // ICTEXT: # Num Counters: |
81 | // ICTEXT: 2 |
82 | // ICTEXT: # Counter Values: |
83 | // ICTEXT: 1000 |
84 | // ICTEXT: 1 |
85 | // ICTEXT: # Num Value Kinds: |
86 | // ICTEXT: 2 |
87 | // ICTEXT: # ValueKind = IPVK_IndirectCallTarget: |
88 | // ICTEXT: 0 |
89 | // ICTEXT: # NumValueSites: |
90 | // ICTEXT: 2 |
91 | // ICTEXT: 2 |
92 | // ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func1Eii:750 |
93 | // ICTEXT: _ZN8Derived15func1Eii:250 |
94 | // ICTEXT: 2 |
95 | // ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZN12_GLOBAL__N_18Derived25func2Eii:750 |
96 | // ICTEXT: _ZN8Derived15func2Eii:250 |
97 | // ICTEXT: # ValueKind = IPVK_VTableTarget: |
98 | // ICTEXT: 2 |
99 | // ICTEXT: # NumValueSites: |
100 | // ICTEXT: 2 |
101 | // ICTEXT: 2 |
102 | // ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E:750 |
103 | // ICTEXT: _ZTV8Derived1:250 |
104 | // ICTEXT: 2 |
105 | // ICTEXT: {{.*}}instrprof-vtable-value-prof.cpp;_ZTVN12_GLOBAL__N_18Derived2E:750 |
106 | // ICTEXT: _ZTV8Derived1:250 |
107 | |
108 | #include <cstdio> |
109 | #include <cstdlib> |
110 | class Base { |
111 | public: |
112 | virtual int func1(int a, int b) = 0; |
113 | virtual int func2(int a, int b) = 0; |
114 | }; |
115 | class Derived1 : public Base { |
116 | public: |
117 | int func1(int a, int b) override { return a + b; } |
118 | |
119 | int func2(int a, int b) override { return a * b; } |
120 | }; |
121 | namespace { |
122 | class Derived2 : public Base { |
123 | public: |
124 | int func1(int a, int b) override { return a - b; } |
125 | |
126 | int func2(int a, int b) override { return a * (a - b); } |
127 | }; |
128 | } // namespace |
129 | __attribute__((noinline)) Base *createType(int a) { |
130 | Base *base = nullptr; |
131 | if (a % 4 == 0) |
132 | base = new Derived1(); |
133 | else |
134 | base = new Derived2(); |
135 | return base; |
136 | } |
137 | int main(int argc, char **argv) { |
138 | int sum = 0; |
139 | for (int i = 0; i < 1000; i++) { |
140 | int a = rand(); |
141 | int b = rand(); |
142 | Base *ptr = createType(a: i); |
143 | sum += ptr->func1(a, b) + ptr->func2(a: b, b: a); |
144 | } |
145 | printf("sum is %d\n" , sum); |
146 | return 0; |
147 | } |
148 | |