1 // Copyright 2020 Google LLC 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #ifndef HIGHWAY_HWY_FOREACH_TARGET_H_ 16 #define HIGHWAY_HWY_FOREACH_TARGET_H_ 17 18 // Re-includes the translation unit zero or more times to compile for any 19 // targets except HWY_STATIC_TARGET. Defines unique HWY_TARGET each time so that 20 // highway.h defines the corresponding macro/namespace. 21 22 #include "hwy/detect_targets.h" 23 24 // *_inl.h may include other headers, which requires include guards to prevent 25 // repeated inclusion. The guards must be reset after compiling each target, so 26 // the header is again visible. This is done by flipping HWY_TARGET_TOGGLE, 27 // defining it if undefined and vice versa. This macro is initially undefined 28 // so that IDEs don't gray out the contents of each header. 29 #ifdef HWY_TARGET_TOGGLE 30 #error "This macro must not be defined outside foreach_target.h" 31 #endif 32 33 #ifdef HWY_HIGHWAY_INCLUDED // highway.h include guard 34 // Trigger fixup at the bottom of this header. 35 #define HWY_ALREADY_INCLUDED 36 37 // The next highway.h must re-include set_macros-inl.h because the first 38 // highway.h chose the static target instead of what we will set below. 39 #undef HWY_SET_MACROS_PER_TARGET 40 #endif 41 42 // Disable HWY_EXPORT in user code until we have generated all targets. Note 43 // that a subsequent highway.h will not override this definition. 44 #undef HWY_ONCE 45 #define HWY_ONCE (0 || HWY_IDE) 46 47 // Avoid warnings on #include HWY_TARGET_INCLUDE by hiding them from the IDE; 48 // also skip if only 1 target defined (no re-inclusion will be necessary). 49 #if !HWY_IDE && (HWY_TARGETS != HWY_STATIC_TARGET) 50 51 #if !defined(HWY_TARGET_INCLUDE) 52 #error ">1 target enabled => define HWY_TARGET_INCLUDE before foreach_target.h" 53 #endif 54 55 #if (HWY_TARGETS & HWY_SCALAR) && (HWY_STATIC_TARGET != HWY_SCALAR) 56 #undef HWY_TARGET 57 #define HWY_TARGET HWY_SCALAR 58 #include HWY_TARGET_INCLUDE 59 #ifdef HWY_TARGET_TOGGLE 60 #undef HWY_TARGET_TOGGLE 61 #else 62 #define HWY_TARGET_TOGGLE 63 #endif 64 #endif 65 66 #if (HWY_TARGETS & HWY_NEON) && (HWY_STATIC_TARGET != HWY_NEON) 67 #undef HWY_TARGET 68 #define HWY_TARGET HWY_NEON 69 #include HWY_TARGET_INCLUDE 70 #ifdef HWY_TARGET_TOGGLE 71 #undef HWY_TARGET_TOGGLE 72 #else 73 #define HWY_TARGET_TOGGLE 74 #endif 75 #endif 76 77 #if (HWY_TARGETS & HWY_SVE) && (HWY_STATIC_TARGET != HWY_SVE) 78 #undef HWY_TARGET 79 #define HWY_TARGET HWY_SVE 80 #include HWY_TARGET_INCLUDE 81 #ifdef HWY_TARGET_TOGGLE 82 #undef HWY_TARGET_TOGGLE 83 #else 84 #define HWY_TARGET_TOGGLE 85 #endif 86 #endif 87 88 #if (HWY_TARGETS & HWY_SVE2) && (HWY_STATIC_TARGET != HWY_SVE2) 89 #undef HWY_TARGET 90 #define HWY_TARGET HWY_SVE2 91 #include HWY_TARGET_INCLUDE 92 #ifdef HWY_TARGET_TOGGLE 93 #undef HWY_TARGET_TOGGLE 94 #else 95 #define HWY_TARGET_TOGGLE 96 #endif 97 #endif 98 99 #if (HWY_TARGETS & HWY_SSSE3) && (HWY_STATIC_TARGET != HWY_SSSE3) 100 #undef HWY_TARGET 101 #define HWY_TARGET HWY_SSSE3 102 #include HWY_TARGET_INCLUDE 103 #ifdef HWY_TARGET_TOGGLE 104 #undef HWY_TARGET_TOGGLE 105 #else 106 #define HWY_TARGET_TOGGLE 107 #endif 108 #endif 109 110 #if (HWY_TARGETS & HWY_SSE4) && (HWY_STATIC_TARGET != HWY_SSE4) 111 #undef HWY_TARGET 112 #define HWY_TARGET HWY_SSE4 113 #include HWY_TARGET_INCLUDE 114 #ifdef HWY_TARGET_TOGGLE 115 #undef HWY_TARGET_TOGGLE 116 #else 117 #define HWY_TARGET_TOGGLE 118 #endif 119 #endif 120 121 #if (HWY_TARGETS & HWY_AVX2) && (HWY_STATIC_TARGET != HWY_AVX2) 122 #undef HWY_TARGET 123 #define HWY_TARGET HWY_AVX2 124 #include HWY_TARGET_INCLUDE 125 #ifdef HWY_TARGET_TOGGLE 126 #undef HWY_TARGET_TOGGLE 127 #else 128 #define HWY_TARGET_TOGGLE 129 #endif 130 #endif 131 132 #if (HWY_TARGETS & HWY_AVX3) && (HWY_STATIC_TARGET != HWY_AVX3) 133 #undef HWY_TARGET 134 #define HWY_TARGET HWY_AVX3 135 #include HWY_TARGET_INCLUDE 136 #ifdef HWY_TARGET_TOGGLE 137 #undef HWY_TARGET_TOGGLE 138 #else 139 #define HWY_TARGET_TOGGLE 140 #endif 141 #endif 142 143 #if (HWY_TARGETS & HWY_AVX3_DL) && (HWY_STATIC_TARGET != HWY_AVX3_DL) 144 #undef HWY_TARGET 145 #define HWY_TARGET HWY_AVX3_DL 146 #include HWY_TARGET_INCLUDE 147 #ifdef HWY_TARGET_TOGGLE 148 #undef HWY_TARGET_TOGGLE 149 #else 150 #define HWY_TARGET_TOGGLE 151 #endif 152 #endif 153 154 #if (HWY_TARGETS & HWY_WASM2) && (HWY_STATIC_TARGET != HWY_WASM2) 155 #undef HWY_TARGET 156 #define HWY_TARGET HWY_WASM2 157 #include HWY_TARGET_INCLUDE 158 #ifdef HWY_TARGET_TOGGLE 159 #undef HWY_TARGET_TOGGLE 160 #else 161 #define HWY_TARGET_TOGGLE 162 #endif 163 #endif 164 165 #if (HWY_TARGETS & HWY_WASM) && (HWY_STATIC_TARGET != HWY_WASM) 166 #undef HWY_TARGET 167 #define HWY_TARGET HWY_WASM 168 #include HWY_TARGET_INCLUDE 169 #ifdef HWY_TARGET_TOGGLE 170 #undef HWY_TARGET_TOGGLE 171 #else 172 #define HWY_TARGET_TOGGLE 173 #endif 174 #endif 175 176 #if (HWY_TARGETS & HWY_PPC8) && (HWY_STATIC_TARGET != HWY_PPC8) 177 #undef HWY_TARGET 178 #define HWY_TARGET HWY_PPC8 179 #include HWY_TARGET_INCLUDE 180 #ifdef HWY_TARGET_TOGGLE 181 #undef HWY_TARGET_TOGGLE 182 #else 183 #define HWY_TARGET_TOGGLE 184 #endif 185 #endif 186 187 #endif // !HWY_IDE && (HWY_TARGETS != HWY_STATIC_TARGET) 188 189 // Now that all but the static target have been generated, re-enable HWY_EXPORT. 190 #undef HWY_ONCE 191 #define HWY_ONCE 1 192 193 // If we re-include once per enabled target, the translation unit's 194 // implementation would have to be skipped via #if to avoid redefining symbols. 195 // We instead skip the re-include for HWY_STATIC_TARGET, and generate its 196 // implementation when resuming compilation of the translation unit. 197 #undef HWY_TARGET 198 #define HWY_TARGET HWY_STATIC_TARGET 199 200 #ifdef HWY_ALREADY_INCLUDED 201 // Revert the previous toggle to prevent redefinitions for the static target. 202 #ifdef HWY_TARGET_TOGGLE 203 #undef HWY_TARGET_TOGGLE 204 #else 205 #define HWY_TARGET_TOGGLE 206 #endif 207 208 // Force re-inclusion of set_macros-inl.h now that HWY_TARGET is restored. 209 #ifdef HWY_SET_MACROS_PER_TARGET 210 #undef HWY_SET_MACROS_PER_TARGET 211 #else 212 #define HWY_SET_MACROS_PER_TARGET 213 #endif 214 #endif 215 216 #endif // HIGHWAY_HWY_FOREACH_TARGET_H_ 217