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/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_SSE4) && (HWY_STATIC_TARGET != HWY_SSE4) 78 #undef HWY_TARGET 79 #define HWY_TARGET HWY_SSE4 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_AVX2) && (HWY_STATIC_TARGET != HWY_AVX2) 89 #undef HWY_TARGET 90 #define HWY_TARGET HWY_AVX2 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_AVX3) && (HWY_STATIC_TARGET != HWY_AVX3) 100 #undef HWY_TARGET 101 #define HWY_TARGET HWY_AVX3 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_WASM) && (HWY_STATIC_TARGET != HWY_WASM) 111 #undef HWY_TARGET 112 #define HWY_TARGET HWY_WASM 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_PPC8) && (HWY_STATIC_TARGET != HWY_PPC8) 122 #undef HWY_TARGET 123 #define HWY_TARGET HWY_PPC8 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 #endif // !HWY_IDE && (HWY_TARGETS != HWY_STATIC_TARGET) 133 134 // Now that all but the static target have been generated, re-enable HWY_EXPORT. 135 #undef HWY_ONCE 136 #define HWY_ONCE 1 137 138 // If we re-include once per enabled target, the translation unit's 139 // implementation would have to be skipped via #if to avoid redefining symbols. 140 // We instead skip the re-include for HWY_STATIC_TARGET, and generate its 141 // implementation when resuming compilation of the translation unit. 142 #undef HWY_TARGET 143 #define HWY_TARGET HWY_STATIC_TARGET 144 145 #ifdef HWY_ALREADY_INCLUDED 146 // Revert the previous toggle to prevent redefinitions for the static target. 147 #ifdef HWY_TARGET_TOGGLE 148 #undef HWY_TARGET_TOGGLE 149 #else 150 #define HWY_TARGET_TOGGLE 151 #endif 152 153 // Force re-inclusion of set_macros-inl.h now that HWY_TARGET is restored. 154 #ifdef HWY_SET_MACROS_PER_TARGET 155 #undef HWY_SET_MACROS_PER_TARGET 156 #else 157 #define HWY_SET_MACROS_PER_TARGET 158 #endif 159 #endif 160 161 #endif // HIGHWAY_HWY_FOREACH_TARGET_H_ 162