@@ -1095,13 +1095,81 @@ extern "C" JL_DLLEXPORT const std::pair<std::string,std::string> &jl_get_llvm_di
1095
1095
{feature_masks, 0 }, {{}, 0 }, 0 });
1096
1096
return res;
1097
1097
}
1098
-
1098
+ # ifndef __clang_gcanalyzer__
1099
1099
extern " C" JL_DLLEXPORT std::vector<jl_target_spec_t > jl_get_llvm_clone_targets (void )
1100
1100
{
1101
- if (jit_targets.empty ())
1102
- jl_error (" JIT targets not initialized" );
1101
+ auto &cmdline = get_cmdline_targets ();
1102
+ check_cmdline (cmdline, true );
1103
+ llvm::SmallVector<TargetData<feature_sz>, 0 > image_targets;
1104
+ for (auto &arg: cmdline) {
1105
+ auto data = arg_target_data (arg, image_targets.empty ());
1106
+ image_targets.push_back (std::move (data));
1107
+ }
1108
+
1109
+ auto ntargets = image_targets.size ();
1110
+ // Now decide the clone condition.
1111
+ for (size_t i = 1 ; i < ntargets; i++) {
1112
+ auto &t = image_targets[i];
1113
+ if (t.en .flags & JL_TARGET_CLONE_ALL)
1114
+ continue ;
1115
+ // Always clone when code checks CPU features
1116
+ t.en .flags |= JL_TARGET_CLONE_CPU;
1117
+ // The most useful one in general...
1118
+ t.en .flags |= JL_TARGET_CLONE_LOOP;
1119
+ auto &features0 = image_targets[t.base ].en .features ;
1120
+ // Special case for KNL/KNM since they're so different
1121
+ if (!(t.dis .flags & JL_TARGET_CLONE_ALL)) {
1122
+ if ((t.name == " knl" || t.name == " knm" ) &&
1123
+ image_targets[t.base ].name != " knl" && image_targets[t.base ].name != " knm" ) {
1124
+ t.en .flags |= JL_TARGET_CLONE_ALL;
1125
+ break ;
1126
+ }
1127
+ }
1128
+ static constexpr uint32_t clone_math[] = {Feature::fma, Feature::fma4};
1129
+ static constexpr uint32_t clone_simd[] = {Feature::sse3, Feature::ssse3,
1130
+ Feature::sse41, Feature::sse42,
1131
+ Feature::avx, Feature::avx2,
1132
+ Feature::vaes, Feature::vpclmulqdq,
1133
+ Feature::sse4a, Feature::avx512f,
1134
+ Feature::avx512dq, Feature::avx512ifma,
1135
+ Feature::avx512pf, Feature::avx512er,
1136
+ Feature::avx512cd, Feature::avx512bw,
1137
+ Feature::avx512vl, Feature::avx512vbmi,
1138
+ Feature::avx512vpopcntdq, Feature::avxvnni,
1139
+ Feature::avx512vbmi2, Feature::avx512vnni,
1140
+ Feature::avx512bitalg, Feature::avx512bf16,
1141
+ Feature::avx512vp2intersect, Feature::avx512fp16};
1142
+ for (auto fe: clone_math) {
1143
+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1144
+ t.en .flags |= JL_TARGET_CLONE_MATH;
1145
+ break ;
1146
+ }
1147
+ }
1148
+ for (auto fe: clone_simd) {
1149
+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1150
+ t.en .flags |= JL_TARGET_CLONE_SIMD;
1151
+ break ;
1152
+ }
1153
+ }
1154
+ static constexpr uint32_t clone_fp16[] = {Feature::avx512fp16};
1155
+ for (auto fe: clone_fp16) {
1156
+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1157
+ t.en .flags |= JL_TARGET_CLONE_FLOAT16;
1158
+ break ;
1159
+ }
1160
+ }
1161
+ static constexpr uint32_t clone_bf16[] = {Feature::avx512bf16};
1162
+ for (auto fe: clone_bf16) {
1163
+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1164
+ t.en .flags |= JL_TARGET_CLONE_BFLOAT16;
1165
+ break ;
1166
+ }
1167
+ }
1168
+ }
1169
+ if (image_targets.empty ())
1170
+ jl_error (" No targets specified" );
1103
1171
std::vector<jl_target_spec_t > res;
1104
- for (auto &target: jit_targets ) {
1172
+ for (auto &target: image_targets ) {
1105
1173
auto features_en = target.en .features ;
1106
1174
auto features_dis = target.dis .features ;
1107
1175
for (auto &fename: feature_names) {
@@ -1121,6 +1189,7 @@ extern "C" JL_DLLEXPORT std::vector<jl_target_spec_t> jl_get_llvm_clone_targets(
1121
1189
}
1122
1190
return res;
1123
1191
}
1192
+ #endif
1124
1193
1125
1194
extern " C" int jl_test_cpu_feature (jl_cpu_feature_t feature)
1126
1195
{
0 commit comments