Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / bolt / test / runtime / instrumentation-indirect-2.c
blob7d19db14b77f0a97381a1e1b98aa8652e116eb68
1 // Check that indirect call hash tables properly register multiple calls,
2 // and that calls from different processes don't get mixed up when using
3 // --instrumentation-file-append-pid.
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <unistd.h>
9 __attribute__((noinline)) void funcA(int pid) { printf("funcA %d\n", pid); }
10 __attribute__((noinline)) void funcB(int pid) { printf("funcB %d\n", pid); }
11 __attribute__((noinline)) void funcC(int pid) { printf("funcC %d\n", pid); }
12 __attribute__((noinline)) void funcD(int pid) { printf("funcD %d\n", pid); }
13 __attribute__((noinline)) void funcE(int pid) { printf("funcE %d\n", pid); }
14 __attribute__((noinline)) void funcF(int pid) { printf("funcF %d\n", pid); }
15 __attribute__((noinline)) void funcG(int pid) { printf("funcG %d\n", pid); }
16 __attribute__((noinline)) void funcH(int pid) { printf("funcH %d\n", pid); }
17 __attribute__((noinline)) void funcI(int pid) { printf("funcI %d\n", pid); }
18 __attribute__((noinline)) void funcJ(int pid) { printf("funcJ %d\n", pid); }
19 __attribute__((noinline)) void funcK(int pid) { printf("funcK %d\n", pid); }
20 __attribute__((noinline)) void funcL(int pid) { printf("funcL %d\n", pid); }
21 __attribute__((noinline)) void funcM(int pid) { printf("funcM %d\n", pid); }
22 __attribute__((noinline)) void funcN(int pid) { printf("funcN %d\n", pid); }
23 __attribute__((noinline)) void funcO(int pid) { printf("funcO %d\n", pid); }
24 __attribute__((noinline)) void funcP(int pid) { printf("funcP %d\n", pid); }
26 int main() {
28 void (*funcs[])(int) = {funcA, funcB, funcC, funcD, funcE, funcF,
29 funcG, funcH, funcI, funcJ, funcK, funcL,
30 funcM, funcN, funcO, funcP};
31 int i;
33 switch (fork()) {
34 case -1:
35 printf("Failed to fork!\n");
36 exit(-1);
37 break;
38 case 0:
39 i = 0;
40 break;
41 default:
42 i = 1;
43 break;
45 int pid = getpid();
46 for (; i < sizeof(funcs) / sizeof(void *); i += 2) {
47 funcs[i](pid);
50 return 0;
53 REQUIRES: system-linux,shell,fuser
55 RUN: %clang %cflags %s -o %t.exe -Wl,-q -pie -fpie
57 RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t.fdata \
58 RUN: --conservative-instrumentation -o %t.instrumented_conservative \
59 RUN: --instrumentation-sleep-time=1 --instrumentation-no-counters-clear \
60 RUN: --instrumentation-wait-forks
62 # Instrumented program needs to finish returning zero
63 # Both output and profile must contain all 16 functions
64 RUN: %t.instrumented_conservative > %t.output
65 # Wait for profile and output to be fully written
66 RUN: bash %S/wait_file.sh %t.output
67 RUN: bash %S/wait_file.sh %t.fdata
68 RUN: cat %t.output | FileCheck %s --check-prefix=CHECK-OUTPUT
69 RUN: cat %t.fdata | FileCheck %s --check-prefix=CHECK-COMMON-PROF
71 CHECK-OUTPUT-DAG: funcA
72 CHECK-OUTPUT-DAG: funcB
73 CHECK-OUTPUT-DAG: funcC
74 CHECK-OUTPUT-DAG: funcD
75 CHECK-OUTPUT-DAG: funcE
76 CHECK-OUTPUT-DAG: funcF
77 CHECK-OUTPUT-DAG: funcG
78 CHECK-OUTPUT-DAG: funcH
79 CHECK-OUTPUT-DAG: funcI
80 CHECK-OUTPUT-DAG: funcJ
81 CHECK-OUTPUT-DAG: funcK
82 CHECK-OUTPUT-DAG: funcL
83 CHECK-OUTPUT-DAG: funcM
84 CHECK-OUTPUT-DAG: funcN
85 CHECK-OUTPUT-DAG: funcO
86 CHECK-OUTPUT-DAG: funcP
88 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcA 0 0 1
89 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcB 0 0 1
90 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcC 0 0 1
91 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcD 0 0 1
92 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcE 0 0 1
93 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcF 0 0 1
94 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcG 0 0 1
95 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcH 0 0 1
96 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcI 0 0 1
97 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcJ 0 0 1
98 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcK 0 0 1
99 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcL 0 0 1
100 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcM 0 0 1
101 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcN 0 0 1
102 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcO 0 0 1
103 CHECK-COMMON-PROF-DAG: 1 main {{[0-9a-f]+}} 1 funcP 0 0 1
105 RUN: llvm-bolt %t.exe --instrument --instrumentation-file=%t \
106 RUN: --instrumentation-file-append-pid \
107 RUN: -o %t.instrumented
109 RUN: %t.instrumented > %t.output
110 # Wait till output is fully written in case child outlives parent
111 RUN: bash %S/wait_file.sh %t.output
112 # Make sure all functions were called
113 RUN: cat %t.output | FileCheck %s --check-prefix=CHECK-OUTPUT
115 RUN: child_pid=$(cat %t.output | grep funcA | awk '{print $2;}')
116 RUN: par_pid=$(cat %t.output | grep funcB | awk '{print $2;}')
118 RUN: bash %S/wait_file.sh %t.$child_pid.fdata
119 RUN: bash %S/wait_file.sh %t.$par_pid.fdata
121 RUN: mv %t.$child_pid.fdata %t.child.fdata
122 RUN: mv %t.$par_pid.fdata %t.parent.fdata
124 # Instrumented binary must produce two profiles with only local calls
125 # recorded. Functions called only in child should not appear in parent's
126 # process and vice versa.
127 RUN: cat %t.child.fdata | FileCheck %s --check-prefix=CHECK-CHILD
128 RUN: cat %t.child.fdata | FileCheck %s --check-prefix=CHECK-NOCHILD
129 RUN: cat %t.parent.fdata | FileCheck %s --check-prefix=CHECK-PARENT
130 RUN: cat %t.parent.fdata | FileCheck %s --check-prefix=CHECK-NOPARENT
132 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcA 0 0 1
133 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcC 0 0 1
134 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcE 0 0 1
135 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcG 0 0 1
136 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcI 0 0 1
137 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcK 0 0 1
138 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcM 0 0 1
139 CHECK-CHILD-DAG: 1 main {{[0-9a-f]+}} 1 funcO 0 0 1
141 CHECK-NOCHILD-NOT: funcB
142 CHECK-NOCHILD-NOT: funcD
143 CHECK-NOCHILD-NOT: funcF
144 CHECK-NOCHILD-NOT: funcH
145 CHECK-NOCHILD-NOT: funcJ
146 CHECK-NOCHILD-NOT: funcL
147 CHECK-NOCHILD-NOT: funcN
148 CHECK-NOCHILD-NOT: funcP
150 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcB 0 0 1
151 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcD 0 0 1
152 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcF 0 0 1
153 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcH 0 0 1
154 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcJ 0 0 1
155 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcL 0 0 1
156 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcN 0 0 1
157 CHECK-PARENT-DAG: 1 main {{[0-9a-f]+}} 1 funcP 0 0 1
159 CHECK-NOPARENT-NOT: funcA
160 CHECK-NOPARENT-NOT: funcC
161 CHECK-NOPARENT-NOT: funcE
162 CHECK-NOPARENT-NOT: funcG
163 CHECK-NOPARENT-NOT: funcI
164 CHECK-NOPARENT-NOT: funcK
165 CHECK-NOPARENT-NOT: funcM
166 CHECK-NOPARENT-NOT: funcO