@@ -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" name  == " knm" 
1133+                 image_targets[t.base ].name  != " knl" 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