Coverage Report

Created: 2025-07-11 06:22

/src/dav1d/include/common/attributes.h
Line
Count
Source
1
/*
2
 * Copyright © 2018, VideoLAN and dav1d authors
3
 * Copyright © 2018, Two Orioles, LLC
4
 * All rights reserved.
5
 *
6
 * Redistribution and use in source and binary forms, with or without
7
 * modification, are permitted provided that the following conditions are met:
8
 *
9
 * 1. Redistributions of source code must retain the above copyright notice, this
10
 *    list of conditions and the following disclaimer.
11
 *
12
 * 2. Redistributions in binary form must reproduce the above copyright notice,
13
 *    this list of conditions and the following disclaimer in the documentation
14
 *    and/or other materials provided with the distribution.
15
 *
16
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
20
 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 */
27
28
#ifndef DAV1D_COMMON_ATTRIBUTES_H
29
#define DAV1D_COMMON_ATTRIBUTES_H
30
31
#include "config.h"
32
33
#include <stddef.h>
34
#include <assert.h>
35
36
#ifndef __has_attribute
37
#define __has_attribute(x) 0
38
#endif
39
40
#ifndef __has_feature
41
#define __has_feature(x) 0
42
#endif
43
44
#ifdef __GNUC__
45
#define ATTR_ALIAS __attribute__((may_alias))
46
#if defined(__MINGW32__) && !defined(__clang__)
47
#define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__gnu_printf__, fmt, attr)))
48
#else
49
#define ATTR_FORMAT_PRINTF(fmt, attr) __attribute__((__format__(__printf__, fmt, attr)))
50
#endif
51
#define COLD __attribute__((cold))
52
#else
53
#define ATTR_ALIAS
54
#define ATTR_FORMAT_PRINTF(fmt, attr)
55
#define COLD
56
#endif
57
58
#if ARCH_X86_64
59
/* x86-64 needs 32- and 64-byte alignment for AVX2 and AVX-512. */
60
#define ALIGN_64_VAL 64
61
#define ALIGN_32_VAL 32
62
#define ALIGN_16_VAL 16
63
#elif ARCH_AARCH64 || ARCH_ARM || ARCH_LOONGARCH || ARCH_PPC64LE || ARCH_X86_32
64
/* ARM doesn't benefit from anything more than 16-byte alignment. */
65
#define ALIGN_64_VAL 16
66
#define ALIGN_32_VAL 16
67
#define ALIGN_16_VAL 16
68
#else
69
/* No need for extra alignment on platforms without assembly. */
70
#define ALIGN_64_VAL 8
71
#define ALIGN_32_VAL 8
72
#define ALIGN_16_VAL 8
73
#endif
74
75
/*
76
 * API for variables, struct members (ALIGN()) like:
77
 * uint8_t var[1][2][3][4]
78
 * becomes:
79
 * ALIGN(uint8_t var[1][2][3][4], alignment).
80
 */
81
#ifdef _MSC_VER
82
#define ALIGN(ll, a) \
83
    __declspec(align(a)) ll
84
#else
85
#define ALIGN(line, align) \
86
16.2M
    line __attribute__((aligned(align)))
87
#endif
88
89
/*
90
 * API for stack alignment (ALIGN_STK_$align()) of variables like:
91
 * uint8_t var[1][2][3][4]
92
 * becomes:
93
 * ALIGN_STK_$align(uint8_t, var, 1, [2][3][4])
94
 */
95
#define ALIGN_STK_64(type, var, sz1d, sznd) \
96
1.40k
    ALIGN(type var[sz1d]sznd, ALIGN_64_VAL)
97
#define ALIGN_STK_32(type, var, sz1d, sznd) \
98
    ALIGN(type var[sz1d]sznd, ALIGN_32_VAL)
99
#define ALIGN_STK_16(type, var, sz1d, sznd) \
100
16.2M
    ALIGN(type var[sz1d]sznd, ALIGN_16_VAL)
101
102
/*
103
 * Forbid inlining of a function:
104
 * static NOINLINE void func() {}
105
 */
106
#ifdef _MSC_VER
107
#define NOINLINE __declspec(noinline)
108
#elif __has_attribute(noclone)
109
#define NOINLINE __attribute__((noinline, noclone))
110
#else
111
#define NOINLINE __attribute__((noinline))
112
#endif
113
114
#ifdef _MSC_VER
115
#define ALWAYS_INLINE __forceinline
116
#else
117
#define ALWAYS_INLINE __attribute__((always_inline)) inline
118
#endif
119
120
#if (defined(__ELF__) || defined(__MACH__) || (defined(_WIN32) && defined(__clang__))) && __has_attribute(visibility)
121
#define EXTERN extern __attribute__((visibility("hidden")))
122
#else
123
#define EXTERN extern
124
#endif
125
126
#if ARCH_X86_64 && __has_attribute(model)
127
#define ATTR_MCMODEL_SMALL __attribute__((model("small")))
128
#else
129
#define ATTR_MCMODEL_SMALL
130
#endif
131
132
#ifdef __clang__
133
#define NO_SANITIZE(x) __attribute__((no_sanitize(x)))
134
#else
135
#define NO_SANITIZE(x)
136
#endif
137
138
#if defined(NDEBUG) && (defined(__GNUC__) || defined(__clang__))
139
#undef assert
140
#define assert(x) do { if (!(x)) __builtin_unreachable(); } while (0)
141
#elif defined(NDEBUG) && defined(_MSC_VER)
142
#undef assert
143
#define assert __assume
144
#endif
145
146
#if defined(__GNUC__) && !defined(__INTEL_COMPILER) && !defined(__clang__)
147
#    define dav1d_uninit(x) x=x
148
#else
149
#    define dav1d_uninit(x) x
150
#endif
151
152
#if defined(_MSC_VER) && !defined(__clang__)
153
#include <intrin.h>
154
155
static inline int ctz(const unsigned int mask) {
156
    unsigned long idx;
157
    _BitScanForward(&idx, mask);
158
    return idx;
159
}
160
161
static inline int clz(const unsigned int mask) {
162
    unsigned long leading_zero = 0;
163
    _BitScanReverse(&leading_zero, mask);
164
    return (31 - leading_zero);
165
}
166
167
#ifdef _WIN64
168
static inline int clzll(const unsigned long long mask) {
169
    unsigned long leading_zero = 0;
170
    _BitScanReverse64(&leading_zero, mask);
171
    return (63 - leading_zero);
172
}
173
#else /* _WIN64 */
174
static inline int clzll(const unsigned long long mask) {
175
    if (mask >> 32)
176
        return clz((unsigned)(mask >> 32));
177
    else
178
        return clz((unsigned)mask) + 32;
179
}
180
#endif /* _WIN64 */
181
#else /* !_MSC_VER */
182
1.55M
static inline int ctz(const unsigned int mask) {
183
1.55M
    return __builtin_ctz(mask);
184
1.55M
}
Unexecuted instantiation: dav1d_fuzzer.c:ctz
Unexecuted instantiation: cpu.c:ctz
Unexecuted instantiation: lib.c:ctz
Unexecuted instantiation: mem.c:ctz
Unexecuted instantiation: obu.c:ctz
Unexecuted instantiation: pal.c:ctz
Unexecuted instantiation: picture.c:ctz
Unexecuted instantiation: qm.c:ctz
Unexecuted instantiation: ref.c:ctz
Unexecuted instantiation: refmvs.c:ctz
Unexecuted instantiation: tables.c:ctz
thread_task.c:ctz
Line
Count
Source
182
1.22M
static inline int ctz(const unsigned int mask) {
183
1.22M
    return __builtin_ctz(mask);
184
1.22M
}
Unexecuted instantiation: wedge.c:ctz
Unexecuted instantiation: fg_apply_tmpl.c:ctz
Unexecuted instantiation: cdf.c:ctz
Unexecuted instantiation: data.c:ctz
decode.c:ctz
Line
Count
Source
182
325k
static inline int ctz(const unsigned int mask) {
183
325k
    return __builtin_ctz(mask);
184
325k
}
Unexecuted instantiation: dequant_tables.c:ctz
Unexecuted instantiation: getbits.c:ctz
Unexecuted instantiation: intra_edge.c:ctz
Unexecuted instantiation: lf_mask.c:ctz
Unexecuted instantiation: msac.c:ctz
Unexecuted instantiation: warpmv.c:ctz
Unexecuted instantiation: cdef_tmpl.c:ctz
Unexecuted instantiation: filmgrain_tmpl.c:ctz
Unexecuted instantiation: ipred_tmpl.c:ctz
Unexecuted instantiation: itx_tmpl.c:ctz
Unexecuted instantiation: loopfilter_tmpl.c:ctz
Unexecuted instantiation: looprestoration_tmpl.c:ctz
Unexecuted instantiation: mc_tmpl.c:ctz
Unexecuted instantiation: recon_tmpl.c:ctz
Unexecuted instantiation: ctx.c:ctz
Unexecuted instantiation: itx_1d.c:ctz
Unexecuted instantiation: scan.c:ctz
Unexecuted instantiation: cdef_apply_tmpl.c:ctz
Unexecuted instantiation: ipred_prepare_tmpl.c:ctz
Unexecuted instantiation: lf_apply_tmpl.c:ctz
Unexecuted instantiation: lr_apply_tmpl.c:ctz
185
186
160M
static inline int clz(const unsigned int mask) {
187
160M
    return __builtin_clz(mask);
188
160M
}
Unexecuted instantiation: dav1d_fuzzer.c:clz
Unexecuted instantiation: cpu.c:clz
Unexecuted instantiation: lib.c:clz
Unexecuted instantiation: mem.c:clz
obu.c:clz
Line
Count
Source
186
13.0k
static inline int clz(const unsigned int mask) {
187
13.0k
    return __builtin_clz(mask);
188
13.0k
}
Unexecuted instantiation: pal.c:clz
Unexecuted instantiation: picture.c:clz
Unexecuted instantiation: qm.c:clz
Unexecuted instantiation: ref.c:clz
Unexecuted instantiation: refmvs.c:clz
Unexecuted instantiation: tables.c:clz
Unexecuted instantiation: thread_task.c:clz
Unexecuted instantiation: wedge.c:clz
Unexecuted instantiation: fg_apply_tmpl.c:clz
Unexecuted instantiation: cdf.c:clz
Unexecuted instantiation: data.c:clz
decode.c:clz
Line
Count
Source
186
30.1M
static inline int clz(const unsigned int mask) {
187
30.1M
    return __builtin_clz(mask);
188
30.1M
}
Unexecuted instantiation: dequant_tables.c:clz
getbits.c:clz
Line
Count
Source
186
275k
static inline int clz(const unsigned int mask) {
187
275k
    return __builtin_clz(mask);
188
275k
}
Unexecuted instantiation: intra_edge.c:clz
lf_mask.c:clz
Line
Count
Source
186
8.32M
static inline int clz(const unsigned int mask) {
187
8.32M
    return __builtin_clz(mask);
188
8.32M
}
Unexecuted instantiation: msac.c:clz
warpmv.c:clz
Line
Count
Source
186
424k
static inline int clz(const unsigned int mask) {
187
424k
    return __builtin_clz(mask);
188
424k
}
Unexecuted instantiation: cdef_tmpl.c:clz
Unexecuted instantiation: filmgrain_tmpl.c:clz
Unexecuted instantiation: ipred_tmpl.c:clz
Unexecuted instantiation: itx_tmpl.c:clz
Unexecuted instantiation: loopfilter_tmpl.c:clz
looprestoration_tmpl.c:clz
Line
Count
Source
186
1.33M
static inline int clz(const unsigned int mask) {
187
1.33M
    return __builtin_clz(mask);
188
1.33M
}
Unexecuted instantiation: mc_tmpl.c:clz
recon_tmpl.c:clz
Line
Count
Source
186
96.9M
static inline int clz(const unsigned int mask) {
187
96.9M
    return __builtin_clz(mask);
188
96.9M
}
Unexecuted instantiation: ctx.c:clz
Unexecuted instantiation: itx_1d.c:clz
Unexecuted instantiation: scan.c:clz
cdef_apply_tmpl.c:clz
Line
Count
Source
186
3.31M
static inline int clz(const unsigned int mask) {
187
3.31M
    return __builtin_clz(mask);
188
3.31M
}
ipred_prepare_tmpl.c:clz
Line
Count
Source
186
19.9M
static inline int clz(const unsigned int mask) {
187
19.9M
    return __builtin_clz(mask);
188
19.9M
}
Unexecuted instantiation: lf_apply_tmpl.c:clz
Unexecuted instantiation: lr_apply_tmpl.c:clz
189
190
240k
static inline int clzll(const unsigned long long mask) {
191
240k
    return __builtin_clzll(mask);
192
240k
}
Unexecuted instantiation: dav1d_fuzzer.c:clzll
Unexecuted instantiation: cpu.c:clzll
Unexecuted instantiation: lib.c:clzll
Unexecuted instantiation: mem.c:clzll
Unexecuted instantiation: obu.c:clzll
Unexecuted instantiation: pal.c:clzll
Unexecuted instantiation: picture.c:clzll
Unexecuted instantiation: qm.c:clzll
Unexecuted instantiation: ref.c:clzll
Unexecuted instantiation: refmvs.c:clzll
Unexecuted instantiation: tables.c:clzll
Unexecuted instantiation: thread_task.c:clzll
Unexecuted instantiation: wedge.c:clzll
Unexecuted instantiation: fg_apply_tmpl.c:clzll
Unexecuted instantiation: cdf.c:clzll
Unexecuted instantiation: data.c:clzll
Unexecuted instantiation: decode.c:clzll
Unexecuted instantiation: dequant_tables.c:clzll
Unexecuted instantiation: getbits.c:clzll
Unexecuted instantiation: intra_edge.c:clzll
Unexecuted instantiation: lf_mask.c:clzll
Unexecuted instantiation: msac.c:clzll
warpmv.c:clzll
Line
Count
Source
190
240k
static inline int clzll(const unsigned long long mask) {
191
240k
    return __builtin_clzll(mask);
192
240k
}
Unexecuted instantiation: cdef_tmpl.c:clzll
Unexecuted instantiation: filmgrain_tmpl.c:clzll
Unexecuted instantiation: ipred_tmpl.c:clzll
Unexecuted instantiation: itx_tmpl.c:clzll
Unexecuted instantiation: loopfilter_tmpl.c:clzll
Unexecuted instantiation: looprestoration_tmpl.c:clzll
Unexecuted instantiation: mc_tmpl.c:clzll
Unexecuted instantiation: recon_tmpl.c:clzll
Unexecuted instantiation: ctx.c:clzll
Unexecuted instantiation: itx_1d.c:clzll
Unexecuted instantiation: scan.c:clzll
Unexecuted instantiation: cdef_apply_tmpl.c:clzll
Unexecuted instantiation: ipred_prepare_tmpl.c:clzll
Unexecuted instantiation: lf_apply_tmpl.c:clzll
Unexecuted instantiation: lr_apply_tmpl.c:clzll
193
#endif /* !_MSC_VER */
194
195
#ifndef static_assert
196
#define CHECK_OFFSET(type, field, name) \
197
    struct check_##type##_##field { int x[(name == offsetof(type, field)) ? 1 : -1]; }
198
#define CHECK_SIZE(type, size) \
199
    struct check_##type##_size { int x[(size == sizeof(type)) ? 1 : -1]; }
200
#else
201
#define CHECK_OFFSET(type, field, name) \
202
    static_assert(name == offsetof(type, field), #field)
203
#define CHECK_SIZE(type, size) \
204
    static_assert(size == sizeof(type), #type)
205
#endif
206
207
#ifdef _MSC_VER
208
#define PACKED(...) __pragma(pack(push, 1)) __VA_ARGS__ __pragma(pack(pop))
209
#else
210
#define PACKED(...) __VA_ARGS__ __attribute__((__packed__))
211
#endif
212
213
#endif /* DAV1D_COMMON_ATTRIBUTES_H */