/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 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 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 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 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 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 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 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 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 Line | Count | Source | 186 | 3.31M | static inline int clz(const unsigned int mask) { | 187 | 3.31M | return __builtin_clz(mask); | 188 | 3.31M | } |
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 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 */ |