@@ -910,6 +910,8 @@ static uint32_t pkgimg_init_cb(const void *id, jl_value_t **rejection_reason)
910910 return match.best_idx ;
911911}
912912
913+ // This function serves as a fallback during bootstrapping, at that point we don't have a sysimage with native code
914+ // so we won't call sysimg_init_cb, else this function shouldn't do anything.
913915static void ensure_jit_target (bool imaging)
914916{
915917 auto &cmdline = get_cmdline_targets ();
@@ -1102,13 +1104,82 @@ const std::pair<std::string,std::string> &jl_get_llvm_disasm_target(void)
11021104 {feature_masks, 0 }, {{}, 0 }, 0 });
11031105 return res;
11041106}
1105-
1107+ // This function parses the -C command line to figure out which targets to multiversion to.
1108+ #ifndef __clang_gcanalyzer__
11061109llvm::SmallVector<jl_target_spec_t , 0 > jl_get_llvm_clone_targets (void )
11071110{
1108- if (jit_targets.empty ())
1109- jl_error (" JIT targets not initialized" );
1111+ auto &cmdline = get_cmdline_targets ();
1112+ check_cmdline (cmdline, true );
1113+ llvm::SmallVector<TargetData<feature_sz>, 0 > image_targets;
1114+ for (auto &arg: cmdline) {
1115+ auto data = arg_target_data (arg, image_targets.empty ());
1116+ image_targets.push_back (std::move (data));
1117+ }
1118+
1119+ auto ntargets = image_targets.size ();
1120+ // Now decide the clone condition.
1121+ for (size_t i = 1 ; i < ntargets; i++) {
1122+ auto &t = image_targets[i];
1123+ if (t.en .flags & JL_TARGET_CLONE_ALL)
1124+ continue ;
1125+ // Always clone when code checks CPU features
1126+ t.en .flags |= JL_TARGET_CLONE_CPU;
1127+ // The most useful one in general...
1128+ t.en .flags |= JL_TARGET_CLONE_LOOP;
1129+ auto &features0 = image_targets[t.base ].en .features ;
1130+ // Special case for KNL/KNM since they're so different
1131+ if (!(t.dis .flags & JL_TARGET_CLONE_ALL)) {
1132+ if ((t.name == " knl" || t.name == " knm" ) &&
1133+ image_targets[t.base ].name != " knl" && image_targets[t.base ].name != " knm" ) {
1134+ t.en .flags |= JL_TARGET_CLONE_ALL;
1135+ break ;
1136+ }
1137+ }
1138+ static constexpr uint32_t clone_math[] = {Feature::fma, Feature::fma4};
1139+ static constexpr uint32_t clone_simd[] = {Feature::sse3, Feature::ssse3,
1140+ Feature::sse41, Feature::sse42,
1141+ Feature::avx, Feature::avx2,
1142+ Feature::vaes, Feature::vpclmulqdq,
1143+ Feature::sse4a, Feature::avx512f,
1144+ Feature::avx512dq, Feature::avx512ifma,
1145+ Feature::avx512pf, Feature::avx512er,
1146+ Feature::avx512cd, Feature::avx512bw,
1147+ Feature::avx512vl, Feature::avx512vbmi,
1148+ Feature::avx512vpopcntdq, Feature::avxvnni,
1149+ Feature::avx512vbmi2, Feature::avx512vnni,
1150+ Feature::avx512bitalg, Feature::avx512bf16,
1151+ Feature::avx512vp2intersect, Feature::avx512fp16};
1152+ for (auto fe: clone_math) {
1153+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1154+ t.en .flags |= JL_TARGET_CLONE_MATH;
1155+ break ;
1156+ }
1157+ }
1158+ for (auto fe: clone_simd) {
1159+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1160+ t.en .flags |= JL_TARGET_CLONE_SIMD;
1161+ break ;
1162+ }
1163+ }
1164+ static constexpr uint32_t clone_fp16[] = {Feature::avx512fp16};
1165+ for (auto fe: clone_fp16) {
1166+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1167+ t.en .flags |= JL_TARGET_CLONE_FLOAT16;
1168+ break ;
1169+ }
1170+ }
1171+ static constexpr uint32_t clone_bf16[] = {Feature::avx512bf16};
1172+ for (auto fe: clone_bf16) {
1173+ if (!test_nbit (features0, fe) && test_nbit (t.en .features , fe)) {
1174+ t.en .flags |= JL_TARGET_CLONE_BFLOAT16;
1175+ break ;
1176+ }
1177+ }
1178+ }
1179+ if (image_targets.empty ())
1180+ jl_error (" No targets specified" );
11101181 llvm::SmallVector<jl_target_spec_t , 0 > res;
1111- for (auto &target: jit_targets ) {
1182+ for (auto &target: image_targets ) {
11121183 auto features_en = target.en .features ;
11131184 auto features_dis = target.dis .features ;
11141185 for (auto &fename: feature_names) {
@@ -1128,6 +1199,7 @@ llvm::SmallVector<jl_target_spec_t, 0> jl_get_llvm_clone_targets(void)
11281199 }
11291200 return res;
11301201}
1202+ #endif
11311203
11321204extern " C" int jl_test_cpu_feature (jl_cpu_feature_t feature)
11331205{
0 commit comments