@img/sharp-libvips-dev-wasm32 1.3.0-rc.6 → 1.3.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (153) hide show
  1. package/README.md +23 -23
  2. package/include/aom/aom_codec.h +1 -1
  3. package/include/aom/aom_decoder.h +4 -0
  4. package/include/aom/aom_encoder.h +19 -8
  5. package/include/aom/aom_ext_ratectrl.h +664 -0
  6. package/include/aom/aom_image.h +93 -30
  7. package/include/aom/aom_tpl.h +99 -0
  8. package/include/aom/aomcx.h +89 -16
  9. package/include/aom/aomdx.h +12 -0
  10. package/include/expat.h +14 -2
  11. package/include/expat_config.h +6 -3
  12. package/include/expat_external.h +3 -2
  13. package/include/glib-2.0/gio/gdbusconnection.h +2 -8
  14. package/include/glib-2.0/gio/gio-visibility.h +34 -0
  15. package/include/glib-2.0/gio/gioenums.h +5 -4
  16. package/include/glib-2.0/glib/glib-visibility.h +34 -0
  17. package/include/glib-2.0/glib/gmacros.h +3 -3
  18. package/include/glib-2.0/glib/gmarkup.h +10 -0
  19. package/include/glib-2.0/glib/gmem.h +4 -4
  20. package/include/glib-2.0/glib/gmessages.h +6 -8
  21. package/include/glib-2.0/glib/gsequence.h +2 -2
  22. package/include/glib-2.0/glib/gstrfuncs.h +190 -0
  23. package/include/glib-2.0/glib/gutils.h +9 -0
  24. package/include/glib-2.0/glib/gvarianttype.h +16 -16
  25. package/include/glib-2.0/glib/gversionmacros.h +22 -0
  26. package/include/glib-2.0/gmodule/gmodule-visibility.h +34 -0
  27. package/include/glib-2.0/gobject/gobject-visibility.h +34 -0
  28. package/include/glib-2.0/gobject/gsignal.h +5 -5
  29. package/include/glib-2.0/gobject/gtype.h +14 -14
  30. package/include/hwy/aligned_allocator.h +44 -2
  31. package/include/hwy/auto_tune.h +22 -6
  32. package/include/hwy/base.h +60 -90
  33. package/include/hwy/bit_set.h +410 -0
  34. package/include/hwy/cache_control.h +3 -2
  35. package/include/hwy/detect_compiler_arch.h +134 -14
  36. package/include/hwy/detect_targets.h +82 -36
  37. package/include/hwy/highway.h +15 -0
  38. package/include/hwy/nanobenchmark.h +12 -3
  39. package/include/hwy/ops/arm_neon-inl.h +96 -25
  40. package/include/hwy/ops/arm_sve-inl.h +250 -95
  41. package/include/hwy/ops/emu128-inl.h +12 -7
  42. package/include/hwy/ops/generic_ops-inl.h +271 -131
  43. package/include/hwy/ops/loongarch_lasx-inl.h +31 -9
  44. package/include/hwy/ops/loongarch_lsx-inl.h +33 -12
  45. package/include/hwy/ops/ppc_vsx-inl.h +99 -19
  46. package/include/hwy/ops/rvv-inl.h +239 -130
  47. package/include/hwy/ops/scalar-inl.h +22 -7
  48. package/include/hwy/ops/set_macros-inl.h +163 -107
  49. package/include/hwy/ops/wasm_128-inl.h +13 -22
  50. package/include/hwy/ops/x86_128-inl.h +223 -120
  51. package/include/hwy/ops/x86_256-inl.h +70 -134
  52. package/include/hwy/ops/x86_512-inl.h +130 -134
  53. package/include/hwy/print-inl.h +2 -0
  54. package/include/hwy/profiler.h +355 -264
  55. package/include/hwy/robust_statistics.h +3 -1
  56. package/include/hwy/timer.h +44 -0
  57. package/include/lcms2.h +34 -4
  58. package/include/libexif/exif-utils.h +1 -1
  59. package/include/libheif/heif.h +2 -0
  60. package/include/libheif/heif_color.h +127 -11
  61. package/include/libheif/heif_components.h +264 -0
  62. package/include/libheif/heif_context.h +2 -1
  63. package/include/libheif/heif_cxx.h +10 -10
  64. package/include/libheif/heif_decoding.h +51 -7
  65. package/include/libheif/heif_encoding.h +15 -9
  66. package/include/libheif/heif_error.h +9 -2
  67. package/include/libheif/heif_export.h +48 -0
  68. package/include/libheif/heif_image.h +81 -66
  69. package/include/libheif/heif_image_handle.h +2 -2
  70. package/include/libheif/heif_items.h +1 -1
  71. package/include/libheif/heif_library.h +8 -16
  72. package/include/libheif/heif_omaf.h +104 -0
  73. package/include/libheif/heif_plugin.h +16 -9
  74. package/include/libheif/heif_properties.h +250 -12
  75. package/include/libheif/heif_security.h +16 -4
  76. package/include/libheif/heif_sequences.h +86 -4
  77. package/include/libheif/heif_tiling.h +2 -2
  78. package/include/libheif/heif_uncompressed.h +44 -324
  79. package/include/libheif/heif_version.h +2 -2
  80. package/include/libpng16/png.h +7 -7
  81. package/include/libpng16/pngconf.h +1 -1
  82. package/include/libpng16/pnglibconf.h +1 -1
  83. package/include/png.h +7 -7
  84. package/include/pngconf.h +1 -1
  85. package/include/pnglibconf.h +1 -1
  86. package/include/tiffconf.h +9 -10
  87. package/include/tiffio.h +10 -9
  88. package/include/tiffvers.h +1 -1
  89. package/include/ultrahdr_api.h +5 -11
  90. package/include/vips/version.h +4 -4
  91. package/lib/glib-2.0/include/glibconfig.h +1 -3
  92. package/lib/libaom.a +0 -0
  93. package/lib/libcgif.a +0 -0
  94. package/lib/libexif.a +0 -0
  95. package/lib/libexif.la +1 -1
  96. package/lib/libexpat.a +0 -0
  97. package/lib/libexpat.la +3 -3
  98. package/lib/libffi.a +0 -0
  99. package/lib/libgio-2.0.a +0 -0
  100. package/lib/libglib-2.0.a +0 -0
  101. package/lib/libgmodule-2.0.a +0 -0
  102. package/lib/libgobject-2.0.a +0 -0
  103. package/lib/libgthread-2.0.a +0 -0
  104. package/lib/libheif.a +0 -0
  105. package/lib/libhwy.a +0 -0
  106. package/lib/libimagequant.a +0 -0
  107. package/lib/libjpeg.a +0 -0
  108. package/lib/liblcms2.a +0 -0
  109. package/lib/libpng.a +0 -0
  110. package/lib/libpng.la +2 -2
  111. package/lib/libpng16.a +0 -0
  112. package/lib/libpng16.la +2 -2
  113. package/lib/libresvg.a +0 -0
  114. package/lib/libsharpyuv.a +0 -0
  115. package/lib/libtiff.a +0 -0
  116. package/lib/libuhdr.a +0 -0
  117. package/lib/libvips-cpp.a +0 -0
  118. package/lib/libvips.a +0 -0
  119. package/lib/libwebp.a +0 -0
  120. package/lib/libwebpdecoder.a +0 -0
  121. package/lib/libwebpdemux.a +0 -0
  122. package/lib/libwebpmux.a +0 -0
  123. package/lib/libz.a +0 -0
  124. package/lib/pkgconfig/aom.pc +2 -2
  125. package/lib/pkgconfig/expat.pc +1 -1
  126. package/lib/pkgconfig/gio-2.0.pc +1 -1
  127. package/lib/pkgconfig/glib-2.0.pc +1 -1
  128. package/lib/pkgconfig/gmodule-2.0.pc +1 -1
  129. package/lib/pkgconfig/gmodule-export-2.0.pc +1 -1
  130. package/lib/pkgconfig/gmodule-no-export-2.0.pc +1 -1
  131. package/lib/pkgconfig/gobject-2.0.pc +1 -1
  132. package/lib/pkgconfig/gthread-2.0.pc +1 -1
  133. package/lib/pkgconfig/lcms2.pc +1 -1
  134. package/lib/pkgconfig/libexif.pc +1 -1
  135. package/lib/pkgconfig/libheif.pc +2 -2
  136. package/lib/pkgconfig/libhwy.pc +3 -4
  137. package/lib/pkgconfig/libpng.pc +1 -1
  138. package/lib/pkgconfig/libpng16.pc +1 -1
  139. package/lib/pkgconfig/libsharpyuv.pc +1 -1
  140. package/lib/pkgconfig/libtiff-4.pc +2 -2
  141. package/lib/pkgconfig/libwebp.pc +1 -1
  142. package/lib/pkgconfig/libwebpdecoder.pc +11 -0
  143. package/lib/pkgconfig/libwebpmux.pc +1 -1
  144. package/lib/pkgconfig/vips-cpp.pc +1 -1
  145. package/lib/pkgconfig/vips.pc +1 -1
  146. package/package.json +1 -1
  147. package/versions.json +12 -12
  148. package/include/libheif/heif_uncompressed_types.h +0 -143
  149. package/lib/libsharpyuv.la +0 -41
  150. package/lib/libtiff.la +0 -41
  151. package/lib/libwebp.la +0 -41
  152. package/lib/libwebpdemux.la +0 -41
  153. package/lib/libwebpmux.la +0 -41
@@ -0,0 +1,410 @@
1
+ // Copyright 2024 Google LLC
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 (the "License");
5
+ // you may not use this file except in compliance with the License.
6
+ // You may obtain a copy of the License at
7
+ //
8
+ // http://www.apache.org/licenses/LICENSE-2.0
9
+ //
10
+ // Unless required by applicable law or agreed to in writing, software
11
+ // distributed under the License is distributed on an "AS IS" BASIS,
12
+ // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ // See the License for the specific language governing permissions and
14
+ // limitations under the License.
15
+
16
+ #ifndef HIGHWAY_HWY_BIT_SET_H_
17
+ #define HIGHWAY_HWY_BIT_SET_H_
18
+
19
+ // Various BitSet for 64, up to 4096, or any number of bits.
20
+
21
+ #include <stddef.h>
22
+
23
+ #include <atomic>
24
+
25
+ #include "hwy/base.h"
26
+
27
+ namespace hwy {
28
+
29
+ // 64-bit specialization of `std::bitset`, which lacks `Foreach`.
30
+ class BitSet64 {
31
+ public:
32
+ constexpr size_t MaxSize() const { return 64; }
33
+
34
+ // No harm if `i` is already set.
35
+ void Set(size_t i) {
36
+ HWY_DASSERT(i < 64);
37
+ bits_ |= (1ULL << i);
38
+ HWY_DASSERT(Get(i));
39
+ }
40
+
41
+ // Equivalent to Set(i) for i in [0, 64) where (bits >> i) & 1. This does
42
+ // not clear any existing bits.
43
+ void SetNonzeroBitsFrom64(uint64_t bits) { bits_ |= bits; }
44
+
45
+ void Clear(size_t i) {
46
+ HWY_DASSERT(i < 64);
47
+ bits_ &= ~(1ULL << i);
48
+ }
49
+
50
+ bool Get(size_t i) const {
51
+ HWY_DASSERT(i < 64);
52
+ return (bits_ & (1ULL << i)) != 0;
53
+ }
54
+
55
+ // Returns true if Get(i) would return true for any i in [0, 64).
56
+ bool Any() const { return bits_ != 0; }
57
+
58
+ // Returns true if Get(i) would return true for all i in [0, 64).
59
+ bool All() const { return bits_ == ~uint64_t{0}; }
60
+
61
+ // Returns lowest i such that `Get(i)`. Caller must first ensure `Any()`!
62
+ size_t First() const {
63
+ HWY_DASSERT(Any());
64
+ return Num0BitsBelowLS1Bit_Nonzero64(bits_);
65
+ }
66
+
67
+ // Returns lowest i such that `!Get(i)`. Caller must first ensure `!All()`!
68
+ size_t First0() const {
69
+ HWY_DASSERT(!All());
70
+ return Num0BitsBelowLS1Bit_Nonzero64(~bits_);
71
+ }
72
+
73
+ // Returns uint64_t(Get(i)) << i for i in [0, 64).
74
+ uint64_t Get64() const { return bits_; }
75
+
76
+ // Calls `func(i)` for each `i` in the set. It is safe for `func` to modify
77
+ // the set, but the current Foreach call is unaffected.
78
+ template <class Func>
79
+ void Foreach(const Func& func) const {
80
+ uint64_t remaining_bits = bits_;
81
+ while (remaining_bits != 0) {
82
+ const size_t i = Num0BitsBelowLS1Bit_Nonzero64(remaining_bits);
83
+ remaining_bits &= remaining_bits - 1; // clear LSB
84
+ func(i);
85
+ }
86
+ }
87
+
88
+ size_t Count() const { return PopCount(bits_); }
89
+
90
+ private:
91
+ uint64_t bits_ = 0;
92
+ };
93
+
94
+ // Any number of bits, flat array.
95
+ template <size_t kMaxSize>
96
+ class BitSet {
97
+ static_assert(kMaxSize != 0, "BitSet requires non-zero size");
98
+
99
+ public:
100
+ constexpr size_t MaxSize() const { return kMaxSize; }
101
+
102
+ // No harm if `i` is already set.
103
+ void Set(size_t i) {
104
+ HWY_DASSERT(i < kMaxSize);
105
+ const size_t idx = i / 64;
106
+ const size_t mod = i % 64;
107
+ bits_[idx].Set(mod);
108
+ }
109
+
110
+ void Clear(size_t i) {
111
+ HWY_DASSERT(i < kMaxSize);
112
+ const size_t idx = i / 64;
113
+ const size_t mod = i % 64;
114
+ bits_[idx].Clear(mod);
115
+ HWY_DASSERT(!Get(i));
116
+ }
117
+
118
+ bool Get(size_t i) const {
119
+ HWY_DASSERT(i < kMaxSize);
120
+ const size_t idx = i / 64;
121
+ const size_t mod = i % 64;
122
+ return bits_[idx].Get(mod);
123
+ }
124
+
125
+ // Returns true if Get(i) would return true for any i in [0, kMaxSize).
126
+ bool Any() const {
127
+ for (const BitSet64& bits : bits_) {
128
+ if (bits.Any()) return true;
129
+ }
130
+ return false;
131
+ }
132
+
133
+ // Returns true if Get(i) would return true for all i in [0, kMaxSize).
134
+ bool All() const {
135
+ for (size_t idx = 0; idx < kNum64 - 1; ++idx) {
136
+ if (!bits_[idx].All()) return false;
137
+ }
138
+
139
+ constexpr size_t kRemainder = kMaxSize % 64;
140
+ if (kRemainder == 0) {
141
+ return bits_[kNum64 - 1].All();
142
+ }
143
+ return bits_[kNum64 - 1].Count() == kRemainder;
144
+ }
145
+
146
+ // Returns lowest i such that `Get(i)`. Caller must first ensure `Any()`!
147
+ size_t First() const {
148
+ HWY_DASSERT(Any());
149
+ for (size_t idx = 0;; ++idx) {
150
+ HWY_DASSERT(idx < kNum64);
151
+ if (bits_[idx].Any()) return idx * 64 + bits_[idx].First();
152
+ }
153
+ }
154
+
155
+ // Returns lowest i such that `!Get(i)`. Caller must first ensure `All()`!
156
+ size_t First0() const {
157
+ HWY_DASSERT(!All());
158
+ for (size_t idx = 0;; ++idx) {
159
+ HWY_DASSERT(idx < kNum64);
160
+ if (!bits_[idx].All()) {
161
+ const size_t first0 = idx * 64 + bits_[idx].First0();
162
+ HWY_DASSERT(first0 < kMaxSize);
163
+ return first0;
164
+ }
165
+ }
166
+ }
167
+
168
+ // Calls `func(i)` for each `i` in the set. It is safe for `func` to modify
169
+ // the set, but the current Foreach call is only affected if changing one of
170
+ // the not yet visited BitSet64.
171
+ template <class Func>
172
+ void Foreach(const Func& func) const {
173
+ for (size_t idx = 0; idx < kNum64; ++idx) {
174
+ bits_[idx].Foreach([idx, &func](size_t mod) { func(idx * 64 + mod); });
175
+ }
176
+ }
177
+
178
+ size_t Count() const {
179
+ size_t total = 0;
180
+ for (const BitSet64& bits : bits_) {
181
+ total += bits.Count();
182
+ }
183
+ return total;
184
+ }
185
+
186
+ private:
187
+ static constexpr size_t kNum64 = DivCeil(kMaxSize, size_t{64});
188
+ BitSet64 bits_[kNum64];
189
+ };
190
+
191
+ // Any number of bits, flat array, atomic updates to the u64.
192
+ template <size_t kMaxSize>
193
+ class AtomicBitSet {
194
+ static_assert(kMaxSize != 0, "AtomicBitSet requires non-zero size");
195
+
196
+ // Bits may signal something to other threads, hence relaxed is insufficient.
197
+ // Acq/Rel ensures a happens-before relationship.
198
+ static constexpr auto kAcq = std::memory_order_acquire;
199
+ static constexpr auto kRel = std::memory_order_release;
200
+
201
+ public:
202
+ constexpr size_t MaxSize() const { return kMaxSize; }
203
+
204
+ // No harm if `i` is already set.
205
+ void Set(size_t i) {
206
+ HWY_DASSERT(i < kMaxSize);
207
+ const size_t idx = i / 64;
208
+ const size_t mod = i % 64;
209
+ bits_[idx].fetch_or(1ULL << mod, kRel);
210
+ }
211
+
212
+ void Clear(size_t i) {
213
+ HWY_DASSERT(i < kMaxSize);
214
+ const size_t idx = i / 64;
215
+ const size_t mod = i % 64;
216
+ bits_[idx].fetch_and(~(1ULL << mod), kRel);
217
+ HWY_DASSERT(!Get(i));
218
+ }
219
+
220
+ bool Get(size_t i) const {
221
+ HWY_DASSERT(i < kMaxSize);
222
+ const size_t idx = i / 64;
223
+ const size_t mod = i % 64;
224
+ return ((bits_[idx].load(kAcq) & (1ULL << mod))) != 0;
225
+ }
226
+
227
+ // Returns true if Get(i) would return true for any i in [0, kMaxSize).
228
+ bool Any() const {
229
+ for (const std::atomic<uint64_t>& bits : bits_) {
230
+ if (bits.load(kAcq)) return true;
231
+ }
232
+ return false;
233
+ }
234
+
235
+ // Returns true if Get(i) would return true for all i in [0, kMaxSize).
236
+ bool All() const {
237
+ for (size_t idx = 0; idx < kNum64 - 1; ++idx) {
238
+ if (bits_[idx].load(kAcq) != ~uint64_t{0}) return false;
239
+ }
240
+
241
+ constexpr size_t kRemainder = kMaxSize % 64;
242
+ const uint64_t last_bits = bits_[kNum64 - 1].load(kAcq);
243
+ if (kRemainder == 0) {
244
+ return last_bits == ~uint64_t{0};
245
+ }
246
+ return PopCount(last_bits) == kRemainder;
247
+ }
248
+
249
+ // Returns lowest i such that `Get(i)`. Caller must first ensure `Any()`!
250
+ size_t First() const {
251
+ HWY_DASSERT(Any());
252
+ for (size_t idx = 0;; ++idx) {
253
+ HWY_DASSERT(idx < kNum64);
254
+ const uint64_t bits = bits_[idx].load(kAcq);
255
+ if (bits != 0) {
256
+ return idx * 64 + Num0BitsBelowLS1Bit_Nonzero64(bits);
257
+ }
258
+ }
259
+ }
260
+
261
+ // Returns lowest i such that `!Get(i)`. Caller must first ensure `!All()`!
262
+ size_t First0() const {
263
+ HWY_DASSERT(!All());
264
+ for (size_t idx = 0;; ++idx) {
265
+ HWY_DASSERT(idx < kNum64);
266
+ const uint64_t inv_bits = ~bits_[idx].load(kAcq);
267
+ if (inv_bits != 0) {
268
+ const size_t first0 =
269
+ idx * 64 + Num0BitsBelowLS1Bit_Nonzero64(inv_bits);
270
+ HWY_DASSERT(first0 < kMaxSize);
271
+ return first0;
272
+ }
273
+ }
274
+ }
275
+
276
+ // Calls `func(i)` for each `i` in the set. It is safe for `func` to modify
277
+ // the set, but the current Foreach call is only affected if changing one of
278
+ // the not yet visited uint64_t.
279
+ template <class Func>
280
+ void Foreach(const Func& func) const {
281
+ for (size_t idx = 0; idx < kNum64; ++idx) {
282
+ uint64_t remaining_bits = bits_[idx].load(kAcq);
283
+ while (remaining_bits != 0) {
284
+ const size_t i = Num0BitsBelowLS1Bit_Nonzero64(remaining_bits);
285
+ remaining_bits &= remaining_bits - 1; // clear LSB
286
+ func(idx * 64 + i);
287
+ }
288
+ }
289
+ }
290
+
291
+ size_t Count() const {
292
+ size_t total = 0;
293
+ for (const std::atomic<uint64_t>& bits : bits_) {
294
+ total += PopCount(bits.load(kAcq));
295
+ }
296
+ return total;
297
+ }
298
+
299
+ private:
300
+ static constexpr size_t kNum64 = DivCeil(kMaxSize, size_t{64});
301
+ std::atomic<uint64_t> bits_[kNum64] = {};
302
+ };
303
+
304
+ // Two-level bitset for up to `kMaxSize` <= 4096 values. The iterators
305
+ // (`Any/First/Foreach/Count`) are more efficient than `BitSet` for sparse sets.
306
+ // This comes at the cost of slightly slower mutators (`Set/Clear`).
307
+ template <size_t kMaxSize = 4096>
308
+ class BitSet4096 {
309
+ static_assert(kMaxSize != 0, "BitSet4096 requires non-zero size");
310
+
311
+ public:
312
+ constexpr size_t MaxSize() const { return kMaxSize; }
313
+
314
+ // No harm if `i` is already set.
315
+ void Set(size_t i) {
316
+ HWY_DASSERT(i < kMaxSize);
317
+ const size_t idx = i / 64;
318
+ const size_t mod = i % 64;
319
+ bits_[idx].Set(mod);
320
+ nonzero_.Set(idx);
321
+ HWY_DASSERT(Get(i));
322
+ }
323
+
324
+ // Equivalent to Set(i) for i in [0, 64) where (bits >> i) & 1. This does
325
+ // not clear any existing bits.
326
+ void SetNonzeroBitsFrom64(uint64_t bits) {
327
+ bits_[0].SetNonzeroBitsFrom64(bits);
328
+ if (bits) nonzero_.Set(0);
329
+ }
330
+
331
+ void Clear(size_t i) {
332
+ HWY_DASSERT(i < kMaxSize);
333
+ const size_t idx = i / 64;
334
+ const size_t mod = i % 64;
335
+ bits_[idx].Clear(mod);
336
+ if (!bits_[idx].Any()) {
337
+ nonzero_.Clear(idx);
338
+ }
339
+ HWY_DASSERT(!Get(i));
340
+ }
341
+
342
+ bool Get(size_t i) const {
343
+ HWY_DASSERT(i < kMaxSize);
344
+ const size_t idx = i / 64;
345
+ const size_t mod = i % 64;
346
+ return bits_[idx].Get(mod);
347
+ }
348
+
349
+ // Returns true if `Get(i)` would return true for any i in [0, kMaxSize).
350
+ bool Any() const { return nonzero_.Any(); }
351
+
352
+ // Returns true if `Get(i)` would return true for all i in [0, kMaxSize).
353
+ bool All() const {
354
+ // Do not check `nonzero_.All()` - that only works if `kMaxSize` is 4096.
355
+ if (nonzero_.Count() != kNum64) return false;
356
+ return Count() == kMaxSize;
357
+ }
358
+
359
+ // Returns lowest i such that `Get(i)`. Caller must first ensure `Any()`!
360
+ size_t First() const {
361
+ HWY_DASSERT(Any());
362
+ const size_t idx = nonzero_.First();
363
+ return idx * 64 + bits_[idx].First();
364
+ }
365
+
366
+ // Returns lowest i such that `!Get(i)`. Caller must first ensure `!All()`!
367
+ size_t First0() const {
368
+ HWY_DASSERT(!All());
369
+ // It is likely not worthwhile to have a separate `BitSet64` for `not_all_`,
370
+ // hence iterate over all u64.
371
+ for (size_t idx = 0;; ++idx) {
372
+ HWY_DASSERT(idx < kNum64);
373
+ if (!bits_[idx].All()) {
374
+ const size_t first0 = idx * 64 + bits_[idx].First0();
375
+ HWY_DASSERT(first0 < kMaxSize);
376
+ return first0;
377
+ }
378
+ }
379
+ }
380
+
381
+ // Returns uint64_t(Get(i)) << i for i in [0, 64).
382
+ uint64_t Get64() const { return bits_[0].Get64(); }
383
+
384
+ // Calls `func(i)` for each `i` in the set. It is safe for `func` to modify
385
+ // the set, but the current Foreach call is only affected if changing one of
386
+ // the not yet visited BitSet64 for which Any() is true.
387
+ template <class Func>
388
+ void Foreach(const Func& func) const {
389
+ nonzero_.Foreach([&func, this](size_t idx) {
390
+ bits_[idx].Foreach([idx, &func](size_t mod) { func(idx * 64 + mod); });
391
+ });
392
+ }
393
+
394
+ size_t Count() const {
395
+ size_t total = 0;
396
+ nonzero_.Foreach(
397
+ [&total, this](size_t idx) { total += bits_[idx].Count(); });
398
+ return total;
399
+ }
400
+
401
+ private:
402
+ static_assert(kMaxSize <= 64 * 64, "One BitSet64 insufficient");
403
+ static constexpr size_t kNum64 = DivCeil(kMaxSize, size_t{64});
404
+ BitSet64 nonzero_;
405
+ BitSet64 bits_[kNum64];
406
+ };
407
+
408
+ } // namespace hwy
409
+
410
+ #endif // HIGHWAY_HWY_BIT_SET_H_
@@ -98,9 +98,10 @@ template <typename T>
98
98
  HWY_INLINE HWY_ATTR_CACHE void Prefetch(const T* p) {
99
99
  (void)p;
100
100
  #ifndef HWY_DISABLE_CACHE_CONTROL
101
- #if HWY_ARCH_X86
101
+ // Use _mm_prefetch on x86/x64, except when clang-cl is compiled with -mno-mmx.
102
+ #if HWY_ARCH_X86 && !(HWY_COMPILER_CLANGCL && !defined(__MMX__))
102
103
  _mm_prefetch(reinterpret_cast<const char*>(p), _MM_HINT_T0);
103
- #elif HWY_COMPILER_GCC // includes clang
104
+ #elif HWY_COMPILER_GCC || HWY_COMPILER_CLANGCL // includes clang
104
105
  // Hint=0 (NTA) behavior differs, but skipping outer caches is probably not
105
106
  // desirable, so use the default 3 (keep in caches).
106
107
  __builtin_prefetch(p, /*write=*/0, /*hint=*/3);
@@ -20,9 +20,14 @@
20
20
  // inclusion by foreach_target.h.
21
21
 
22
22
  // Add to #if conditions to prevent IDE from graying out code.
23
+ // Note for clangd users: There is no predefined macro in clangd, so you must
24
+ // manually add these two lines (without the preceding '// ') to your project's
25
+ // `.clangd` file:
26
+ // CompileFlags:
27
+ // Add: [-D__CLANGD__]
23
28
  #if (defined __CDT_PARSER__) || (defined __INTELLISENSE__) || \
24
29
  (defined Q_CREATOR_RUN) || (defined __CLANGD__) || \
25
- (defined GROK_ELLIPSIS_BUILD)
30
+ (defined GROK_ELLIPSIS_BUILD) || (defined __JETBRAINS_IDE__)
26
31
  #define HWY_IDE 1
27
32
  #else
28
33
  #define HWY_IDE 0
@@ -65,15 +70,23 @@
65
70
  #define HWY_COMPILER_GCC 0
66
71
  #endif
67
72
 
68
- // Clang or clang-cl, not GCC.
69
- #ifdef __clang__
73
+ #ifndef HWY_COMPILER_CLANG // Allow user override.
74
+ #ifdef __clang__ // Clang or clang-cl, not GCC.
70
75
  // In case of Apple LLVM (whose version number is unrelated to that of LLVM) or
71
76
  // an invalid version number, deduce it from the presence of warnings.
72
77
  // Originally based on
73
78
  // https://github.com/simd-everywhere/simde/blob/47d6e603de9d04ee05cdfbc57cf282a02be1bf2a/simde/simde-detect-clang.h#L59.
74
79
  // Please send updates below to them as well, thanks!
75
80
  #if defined(__apple_build_version__) || __clang_major__ >= 999
76
- #if __has_warning("-Woverriding-option")
81
+ #if __has_builtin(__builtin_elementwise_fshl)
82
+ #define HWY_COMPILER_CLANG 2201
83
+ #elif __has_builtin(__builtin_structured_binding_size)
84
+ #define HWY_COMPILER_CLANG 2101
85
+ #elif __has_builtin(__builtin_common_type)
86
+ #define HWY_COMPILER_CLANG 2001
87
+ #elif __has_warning("-Wreturn-mismatch")
88
+ #define HWY_COMPILER_CLANG 1901
89
+ #elif __has_warning("-Woverriding-option")
77
90
  #define HWY_COMPILER_CLANG 1801
78
91
  // No new warnings in 17.0, and Apple LLVM 15.3, which should be 1600, already
79
92
  // has the unsafe_buffer_usage attribute, so we instead check for new builtins.
@@ -108,7 +121,6 @@
108
121
  #else // Anything older than 7.0 is not recommended for Highway.
109
122
  #define HWY_COMPILER_CLANG 600
110
123
  #endif // __has_warning chain
111
- #define HWY_COMPILER3_CLANG (HWY_COMPILER_CLANG * 100)
112
124
  #else // use normal version
113
125
  #define HWY_COMPILER_CLANG (__clang_major__ * 100 + __clang_minor__)
114
126
  #define HWY_COMPILER3_CLANG \
@@ -117,6 +129,12 @@
117
129
  #else // Not clang
118
130
  #define HWY_COMPILER_CLANG 0
119
131
  #define HWY_COMPILER3_CLANG 0
132
+ #endif // __clang__
133
+ #endif // HWY_COMPILER_CLANG
134
+
135
+ // User-defined or deduced HWY_COMPILER_CLANG: derive HWY_COMPILER3_CLANG.
136
+ #ifndef HWY_COMPILER3_CLANG
137
+ #define HWY_COMPILER3_CLANG (HWY_COMPILER_CLANG * 100)
120
138
  #endif
121
139
 
122
140
  #if HWY_COMPILER_GCC && !HWY_COMPILER_CLANG && !HWY_COMPILER_ICC && \
@@ -174,19 +192,30 @@
174
192
  #define HWY_CXX_LANG __cplusplus
175
193
  #endif
176
194
 
177
- #if defined(__cpp_constexpr) && __cpp_constexpr >= 201603L
178
- #define HWY_CXX17_CONSTEXPR constexpr
179
- #else
180
- #define HWY_CXX17_CONSTEXPR
181
- #endif
182
-
195
+ // Use instead of constexpr to avoid compiler errors for older compilers. This
196
+ // macro is for when a constexpr function involves multiple statements and
197
+ // loops, which is allowed in C++14 but not before. If the compiler does not
198
+ // support C++14 constexpr, this evaluates to nothing.
183
199
  #if defined(__cpp_constexpr) && __cpp_constexpr >= 201304L
184
200
  #define HWY_CXX14_CONSTEXPR constexpr
185
201
  #else
186
202
  #define HWY_CXX14_CONSTEXPR
187
203
  #endif
188
204
 
189
- #if HWY_CXX_LANG >= 201703L
205
+ // Same as above, but for C++17 constexpr, which adds support for lambdas, the
206
+ // standard library, and capturing *this.
207
+ // Note that C++17 constexpr still disallows allocating and virtual functions,
208
+ // which are allowed in C++20, but we do not have a use case yet.
209
+ #if defined(__cpp_constexpr) && __cpp_constexpr >= 201603L
210
+ #define HWY_CXX17_CONSTEXPR constexpr
211
+ #else
212
+ #define HWY_CXX17_CONSTEXPR
213
+ #endif
214
+
215
+ // Use instead of `if constexpr` to avoid compiler errors for older compilers.
216
+ // When compilers lack C++17 support, this evaluates to a normal if statement.
217
+ #if HWY_CXX_LANG >= 201703L || \
218
+ (defined(__cpp_if_constexpr) && __cpp_if_constexpr >= 201606L)
190
219
  #define HWY_IF_CONSTEXPR if constexpr
191
220
  #else
192
221
  #define HWY_IF_CONSTEXPR if
@@ -204,6 +233,58 @@
204
233
  #endif
205
234
  #endif
206
235
 
236
+ //------------------------------------------------------------------------------
237
+ // Sanitizers
238
+
239
+ #if HWY_HAS_FEATURE(memory_sanitizer) || defined(MEMORY_SANITIZER) || \
240
+ defined(__SANITIZE_MEMORY__)
241
+ #define HWY_IS_MSAN 1
242
+ #else
243
+ #define HWY_IS_MSAN 0
244
+ #endif
245
+
246
+ #if HWY_HAS_FEATURE(address_sanitizer) || defined(ADDRESS_SANITIZER) || \
247
+ defined(__SANITIZE_ADDRESS__)
248
+ #define HWY_IS_ASAN 1
249
+ #else
250
+ #define HWY_IS_ASAN 0
251
+ #endif
252
+
253
+ #if HWY_HAS_FEATURE(hwaddress_sanitizer) || defined(HWADDRESS_SANITIZER) || \
254
+ defined(__SANITIZE_HWADDRESS__)
255
+ #define HWY_IS_HWASAN 1
256
+ #else
257
+ #define HWY_IS_HWASAN 0
258
+ #endif
259
+
260
+ #if HWY_HAS_FEATURE(thread_sanitizer) || defined(THREAD_SANITIZER) || \
261
+ defined(__SANITIZE_THREAD__)
262
+ #define HWY_IS_TSAN 1
263
+ #else
264
+ #define HWY_IS_TSAN 0
265
+ #endif
266
+
267
+ #if HWY_HAS_FEATURE(undefined_behavior_sanitizer) || \
268
+ defined(UNDEFINED_BEHAVIOR_SANITIZER)
269
+ #define HWY_IS_UBSAN 1
270
+ #else
271
+ #define HWY_IS_UBSAN 0
272
+ #endif
273
+
274
+ // MSAN may cause lengthy build times or false positives e.g. in AVX3 DemoteTo.
275
+ // You can disable MSAN by adding this attribute to the function that fails.
276
+ #if HWY_IS_MSAN
277
+ #define HWY_ATTR_NO_MSAN __attribute__((no_sanitize_memory))
278
+ #else
279
+ #define HWY_ATTR_NO_MSAN
280
+ #endif
281
+
282
+ #if HWY_IS_ASAN || HWY_IS_HWASAN || HWY_IS_MSAN || HWY_IS_TSAN || HWY_IS_UBSAN
283
+ #define HWY_IS_SANITIZER 1
284
+ #else
285
+ #define HWY_IS_SANITIZER 0
286
+ #endif
287
+
207
288
  //------------------------------------------------------------------------------
208
289
  // Architecture
209
290
 
@@ -334,13 +415,36 @@
334
415
  #define HWY_ARCH_LOONGARCH 0
335
416
  #endif
336
417
 
418
+ #if defined(__hexagon__) || defined(__HEXAGON_ARCH__)
419
+ #define HWY_ARCH_HEXAGON 1
420
+ #else
421
+ #define HWY_ARCH_HEXAGON 0
422
+ #endif
423
+
337
424
  // It is an error to detect multiple architectures at the same time, but OK to
338
425
  // detect none of the above.
339
- #if (HWY_ARCH_X86 + HWY_ARCH_PPC + HWY_ARCH_ARM + HWY_ARCH_ARM_OLD + \
340
- HWY_ARCH_WASM + HWY_ARCH_RISCV + HWY_ARCH_S390X + HWY_ARCH_LOONGARCH) > 1
426
+ #if (HWY_ARCH_X86 + HWY_ARCH_PPC + HWY_ARCH_ARM + HWY_ARCH_ARM_OLD + \
427
+ HWY_ARCH_WASM + HWY_ARCH_RISCV + HWY_ARCH_S390X + HWY_ARCH_LOONGARCH + \
428
+ HWY_ARCH_HEXAGON) > 1
341
429
  #error "Must not detect more than one architecture"
342
430
  #endif
343
431
 
432
+ #if HWY_ARCH_RISCV
433
+ #define HWY_ARCH_MAX_BYTES 65536
434
+ #elif HWY_ARCH_ARM_A64
435
+ #define HWY_ARCH_MAX_BYTES 256
436
+ #elif HWY_ARCH_HEXAGON
437
+ #define HWY_ARCH_MAX_BYTES 128
438
+ #elif HWY_ARCH_X86
439
+ #define HWY_ARCH_MAX_BYTES 64
440
+ #elif HWY_ARCH_WASM || HWY_ARCH_LOONGARCH
441
+ #define HWY_ARCH_MAX_BYTES 32
442
+ #elif HWY_ARCH_PPC || HWY_ARCH_S390X || HWY_ARCH_ARM_V7 || HWY_ARCH_ARM_OLD
443
+ #define HWY_ARCH_MAX_BYTES 16
444
+ #else
445
+ #error "Missing case for HWY_ARCH_*"
446
+ #endif
447
+
344
448
  //------------------------------------------------------------------------------
345
449
  // Operating system
346
450
 
@@ -404,4 +508,20 @@
404
508
  #error "Must only detect one byte order"
405
509
  #endif
406
510
 
511
+ //------------------------------------------------------------------------------
512
+ // Features checked in set_macros-inl.h
513
+
514
+ // Compiler supports ACLE __bf16, not necessarily with operators.
515
+ //
516
+ // Disable the __bf16 type on AArch64 with GCC 13 or earlier as there is a bug
517
+ // in GCC 13 and earlier that sometimes causes BF16 constant values to be
518
+ // incorrectly loaded on AArch64, and this GCC bug on AArch64 is
519
+ // described at https://gcc.gnu.org/bugzilla/show_bug.cgi?id=111867.
520
+ #if HWY_ARCH_ARM_A64 && \
521
+ (HWY_COMPILER_CLANG >= 1700 || HWY_COMPILER_GCC_ACTUAL >= 1400)
522
+ #define HWY_ARM_HAVE_SCALAR_BF16_TYPE 1
523
+ #else
524
+ #define HWY_ARM_HAVE_SCALAR_BF16_TYPE 0
525
+ #endif
526
+
407
527
  #endif // HIGHWAY_HWY_DETECT_COMPILER_ARCH_H_