summaryrefslogtreecommitdiff
path: root/test/suites/profiling.bash
blob: 3bd45bcd0d58fd51927f0dded4d09325a90117f3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
# Remove header, including a volatile timestamp, from a .gcno file.
normalize_gcno_file() {
    local from="$1"
    local to="$2"
    tail -c +13 "${from}" >"${to}"
}


SUITE_profiling_PROBE() {
    echo 'int main(void) { return 0; }' >test.c
    if ! $COMPILER -fprofile-generate -c test.c 2>/dev/null; then
        echo "compiler does not support profiling"
    fi
    if ! $COMPILER -fprofile-generate test.o -o test 2>/dev/null; then
        echo "compiler cannot link with profiling"
    fi
    if ! $COMPILER -fprofile-generate=data -c test.c 2>/dev/null; then
        echo "compiler does not support -fprofile-generate=path"
    fi
    if $COMPILER_TYPE_CLANG && ! command -v llvm-profdata$CLANG_VERSION_SUFFIX >/dev/null; then
        echo "llvm-profdata$CLANG_VERSION_SUFFIX tool not found"
    fi
}

SUITE_profiling_SETUP() {
    echo 'int main(void) { return 0; }' >test.c
    unset CCACHE_NODIRECT
}

SUITE_profiling() {
    # -------------------------------------------------------------------------
    TEST "-fprofile-use, missing file"

    $CCACHE_COMPILE -fprofile-use -c test.c 2>/dev/null
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 0
    expect_stat no_input_file 1

    # -------------------------------------------------------------------------
    TEST "-fbranch-probabilities, missing file"

    $CCACHE_COMPILE -fbranch-probabilities -c test.c 2>/dev/null
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 0
    expect_stat no_input_file 1

    # -------------------------------------------------------------------------
    TEST "-fprofile-use=file, missing file"

    $CCACHE_COMPILE -fprofile-use=data.gcda -c test.c 2>/dev/null
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 0
    expect_stat no_input_file 1

    # -------------------------------------------------------------------------
if $RUN_WIN_XFAIL; then
    TEST "-fprofile-use"

    $CCACHE_COMPILE -fprofile-generate -c test.c
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 1

    $COMPILER -fprofile-generate test.o -o test

    ./test
    merge_profiling_data .

    $CCACHE_COMPILE -fprofile-use -c test.c
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 2

    $CCACHE_COMPILE -fprofile-use -c test.c
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 2

    ./test
    merge_profiling_data .

    $CCACHE_COMPILE -fprofile-use -c test.c
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 3
fi

    # -------------------------------------------------------------------------
if $RUN_WIN_XFAIL; then
    TEST "-fprofile-use=dir"

    mkdir data

    $CCACHE_COMPILE -fprofile-generate=data -c test.c
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 1

    $COMPILER -fprofile-generate test.o -o test

    ./test
    merge_profiling_data data

    $CCACHE_COMPILE -fprofile-use=data -c test.c
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 2

    $CCACHE_COMPILE -fprofile-use=data -c test.c
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 2

    ./test
    merge_profiling_data data

    $CCACHE_COMPILE -fprofile-use=data -c test.c
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 3
fi
    # -------------------------------------------------------------------------
if $RUN_WIN_XFAIL; then
    TEST "-fprofile-generate=dir in different directories"

    mkdir -p dir1/data dir2/data

    cd dir1

    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
        || test_failed "compilation error"
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 1

    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
        || test_failed "compilation error"
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 1

    $COMPILER -Werror -fprofile-generate test.o -o test \
        || test_failed "compilation error"

    ./test || test_failed "execution error"
    merge_profiling_data data

    $CCACHE_COMPILE -Werror -fprofile-use=data -c ../test.c \
        || test_failed "compilation error"
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 2

    cd ../dir2

    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
        || test_failed "compilation error"
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 3

    $CCACHE_COMPILE -Werror -fprofile-generate=data -c ../test.c \
        || test_failed "compilation error"
    expect_stat direct_cache_hit 2
    expect_stat cache_miss 3

    $COMPILER -Werror -fprofile-generate test.o -o test \
        || test_failed "compilation error"

    ./test || test_failed "execution error"
    merge_profiling_data data

    $CCACHE_COMPILE -Werror -fprofile-use=data -c ../test.c \
        || test_failed "compilation error"
    # Note: No expect_stat here since GCC and Clang behave differently – just
    # check that the compiler doesn't warn about not finding the profile data.
fi
    # -------------------------------------------------------------------------
    if $COMPILER_TYPE_GCC; then
        # GCC 9 and newer creates a mangled .gcno filename (still in the current
        # working directory) if -fprofile-dir is given.
        for flag in "" -fprofile-dir=dir; do
            for dir in . subdir; do
                TEST "-ftest-coverage with -fprofile-dir=$flag, dir=$dir"
                $CCACHE -z >/dev/null

                mkdir -p "$dir"
                touch "$dir/test.c"
                find -name '*.gcno' -delete

                $COMPILER $flag -ftest-coverage -c $dir/test.c -o $dir/test.o
                gcno_name=$(find -name '*.gcno')
                rm "$gcno_name"

                $CCACHE_COMPILE $flag -ftest-coverage -c $dir/test.c -o $dir/test.o
                expect_stat direct_cache_hit 0
                expect_stat cache_miss 1
                expect_exists "$gcno_name"
                rm "$gcno_name"

                $CCACHE_COMPILE $flag -ftest-coverage -c $dir/test.c -o $dir/test.o
                expect_stat direct_cache_hit 1
                expect_stat cache_miss 1
                expect_exists "$gcno_name"
                rm "$gcno_name"
            done
        done
    fi

    # -------------------------------------------------------------------------
    TEST "-fprofile-arcs for different object file paths"

    mkdir obj1 obj2

    $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj1/test.o
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 1

    $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj1/test.o
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 1

    $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj2/test.o
    expect_different_content obj1/test.o obj2/test.o # different paths to .gcda file
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 2

    $CCACHE_COMPILE -fprofile-arcs -c test.c -o obj2/test.o
    expect_different_content obj1/test.o obj2/test.o # different paths to .gcda file
    expect_stat direct_cache_hit 2
    expect_stat cache_miss 2

    # -------------------------------------------------------------------------
    TEST "-ftest-coverage, different directories"

    mkdir obj1 obj2

    cd obj1
    $COMPILER -ftest-coverage -c "$(pwd)/../test.c"
    normalize_gcno_file test.gcno test.gcno.reference

    $CCACHE_COMPILE -ftest-coverage -c "$(pwd)/../test.c"
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 1
    normalize_gcno_file test.gcno test.gcno.ccache-miss
    expect_equal_content test.gcno.reference test.gcno.ccache-miss

    $CCACHE_COMPILE -ftest-coverage -c "$(pwd)/../test.c"
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 1
    normalize_gcno_file test.gcno test.gcno.ccache-hit
    expect_equal_content test.gcno.reference test.gcno.ccache-hit

    cd ../obj2
    $COMPILER -ftest-coverage -c "$(pwd)/../test.c"
    normalize_gcno_file test.gcno test.gcno.reference

    $CCACHE_COMPILE -ftest-coverage -c "$(pwd)/../test.c"
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 2
    normalize_gcno_file test.gcno test.gcno.ccache-miss
    expect_equal_content test.gcno.reference test.gcno.ccache-miss

    $CCACHE_COMPILE -ftest-coverage -c "$(pwd)/../test.c"
    expect_stat direct_cache_hit 2
    expect_stat cache_miss 2
    normalize_gcno_file test.gcno test.gcno.ccache-hit
    expect_equal_content test.gcno.reference test.gcno.ccache-hit

    # -------------------------------------------------------------------------
    TEST "-ftest-coverage, different directories, basedir, sloppy gcno_cwd"

    export CCACHE_SLOPPINESS="$CCACHE_SLOPPINESS gcno_cwd"
    export CCACHE_BASEDIR="$(pwd)"

    mkdir obj1 obj2

    cd obj1

    $CCACHE_COMPILE -ftest-coverage -c "$(pwd)/../test.c"
    expect_stat direct_cache_hit 0
    expect_stat cache_miss 1

    $CCACHE_COMPILE -ftest-coverage -c "$(pwd)/../test.c"
    expect_stat direct_cache_hit 1
    expect_stat cache_miss 1

    cd ../obj2

    $CCACHE_COMPILE -ftest-coverage -c "$(pwd)/../test.c"
    expect_stat direct_cache_hit 2
    expect_stat cache_miss 1
}

merge_profiling_data() {
    local dir=$1
    if $COMPILER_TYPE_CLANG; then
        llvm-profdata$CLANG_VERSION_SUFFIX merge -output $dir/default.profdata $dir/*.profraw
    fi
}