@@ -345,6 +345,84 @@ static bool selectBfloatLibs(const llvm::Triple &Triple, const Compilation &C,
345
345
return NeedLibs;
346
346
}
347
347
348
+ struct OclocInfo {
349
+ const char *DeviceName;
350
+ const char *PackageName;
351
+ const char *Version;
352
+ SmallVector<int , 8 > HexValues;
353
+ };
354
+
355
+ // The PVCDevices data structure is organized by device name, with the
356
+ // corresponding ocloc split release, version and possible Hex representations
357
+ // of various PVC devices. This information is gathered from the following:
358
+ // https://github.com/intel/compute-runtime/blob/master/shared/source/dll/devices/devices_base.inl
359
+ // https://github.com/intel/compute-runtime/blob/master/shared/source/dll/devices/devices_additional.inl
360
+ static OclocInfo PVCDevices[] = {
361
+ {" pvc-sdv" , " gen12+" , " 12.60.1" , {}},
362
+ {" pvc" ,
363
+ " gen12+" ,
364
+ " 12.60.7" ,
365
+ {0x0BD0 , 0x0BD5 , 0x0BD6 , 0x0BD7 , 0x0BD8 , 0x0BD9 , 0x0BDA , 0x0BDB }}};
366
+
367
+ static std::string getDeviceArg (const ArgStringList &CmdArgs) {
368
+ bool DeviceSeen = false ;
369
+ std::string DeviceArg;
370
+ for (StringRef Arg : CmdArgs) {
371
+ // -device <arg> comes in as a single arg, split up all potential space
372
+ // separated values.
373
+ SmallVector<StringRef> SplitArgs;
374
+ Arg.split (SplitArgs, ' ' );
375
+ for (StringRef SplitArg : SplitArgs) {
376
+ if (DeviceSeen) {
377
+ DeviceArg = SplitArg.str ();
378
+ break ;
379
+ }
380
+ if (SplitArg == " -device" )
381
+ DeviceSeen = true ;
382
+ }
383
+ if (DeviceSeen)
384
+ break ;
385
+ }
386
+
387
+ return DeviceArg;
388
+ }
389
+
390
+ static bool checkPVCDevice (std::string SingleArg, std::string &DevArg) {
391
+ // Handle shortened versions.
392
+ bool CheckShortVersion = true ;
393
+ for (auto Char : SingleArg) {
394
+ if (!std::isdigit (Char) && Char != ' .' ) {
395
+ CheckShortVersion = false ;
396
+ break ;
397
+ }
398
+ }
399
+ // Check for device, version or hex (literal values)
400
+ for (unsigned int I = 0 ; I < std::size (PVCDevices); I++) {
401
+ if (StringRef (SingleArg).equals_insensitive (PVCDevices[I].DeviceName ) ||
402
+ StringRef (SingleArg).equals_insensitive (PVCDevices[I].Version )) {
403
+ DevArg = SingleArg;
404
+ return true ;
405
+ }
406
+
407
+ for (int HexVal : PVCDevices[I].HexValues ) {
408
+ int Value = 0 ;
409
+ if (!StringRef (SingleArg).getAsInteger (0 , Value) && Value == HexVal) {
410
+ // TODO: Pass back the hex string to use for -device_options when
411
+ // IGC is updated to allow. Currently -device_options only accepts
412
+ // the device ID (i.e. pvc) or the version (12.60.7).
413
+ return true ;
414
+ }
415
+ }
416
+ if (CheckShortVersion &&
417
+ StringRef (PVCDevices[I].Version ).starts_with (SingleArg)) {
418
+ DevArg = SingleArg;
419
+ return true ;
420
+ }
421
+ }
422
+
423
+ return false ;
424
+ }
425
+
348
426
SmallVector<std::string, 8 >
349
427
SYCL::getDeviceLibraries (const Compilation &C, const llvm::Triple &TargetTriple,
350
428
bool IsSpirvAOT) {
@@ -360,6 +438,8 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
360
438
StringRef DeviceLibOption;
361
439
};
362
440
441
+ enum { JIT = 0 , AOT_CPU, AOT_DG2, AOT_PVC };
442
+
363
443
// Currently, all SYCL device libraries will be linked by default.
364
444
llvm::StringMap<bool > DeviceLibLinkInfo = {
365
445
{" libc" , true }, {" libm-fp32" , true }, {" libm-fp64" , true },
@@ -460,8 +540,11 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
460
540
{" libsycl-itt-compiler-wrappers" , " internal" },
461
541
{" libsycl-itt-stubs" , " internal" }};
462
542
#if !defined(_WIN32)
463
- const SYCLDeviceLibsList SYCLDeviceSanitizerLibs = {
464
- {" libsycl-sanitizer" , " internal" }};
543
+ const SYCLDeviceLibsList SYCLDeviceAsanLibs = {
544
+ {" libsycl-asan" , " internal" },
545
+ {" libsycl-asan-cpu" , " internal" },
546
+ {" libsycl-asan-dg2" , " internal" },
547
+ {" libsycl-asan-pvc" , " internal" }};
465
548
#endif
466
549
467
550
const SYCLDeviceLibsList SYCLNativeCpuDeviceLibs = {
@@ -493,6 +576,66 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
493
576
}
494
577
};
495
578
579
+ auto addSingleLibrary = [&](const DeviceLibOptInfo &Lib) {
580
+ if (!DeviceLibLinkInfo[Lib.DeviceLibOption ])
581
+ return ;
582
+ SmallString<128 > LibName (Lib.DeviceLibName );
583
+ llvm::sys::path::replace_extension (LibName, LibSuffix);
584
+ LibraryList.push_back (Args.MakeArgString (LibName));
585
+ };
586
+
587
+ // This function is used to check whether there is only one GPU device
588
+ // (PVC or DG2) specified in AOT compilation mode. If yes, we can use
589
+ // corresponding libsycl-asan-* to improve device sanitizer performance,
590
+ // otherwise stick to fallback device sanitizer library used in JIT mode.
591
+ auto getSpecificGPUTarget = [](const ArgStringList &CmdArgs) -> size_t {
592
+ std::string DeviceArg = getDeviceArg (CmdArgs);
593
+ if ((DeviceArg.empty ()) || (DeviceArg.find (" ," ) != std::string::npos))
594
+ return JIT;
595
+
596
+ std::string Temp;
597
+ if (checkPVCDevice (DeviceArg, Temp))
598
+ return AOT_PVC;
599
+
600
+ if (DeviceArg == " dg2" )
601
+ return AOT_DG2;
602
+
603
+ return JIT;
604
+ };
605
+
606
+ auto getSingleBuildTarget = [&]() -> size_t {
607
+ if (!IsSpirvAOT)
608
+ return JIT;
609
+
610
+ llvm::opt::Arg *SYCLTarget = Args.getLastArg (options::OPT_fsycl_targets_EQ);
611
+ if (!SYCLTarget || (SYCLTarget->getValues ().size () != 1 ))
612
+ return JIT;
613
+
614
+ StringRef SYCLTargetStr = SYCLTarget->getValue ();
615
+ if (SYCLTargetStr.starts_with (" spir64_x86_64" ))
616
+ return AOT_CPU;
617
+
618
+ if (SYCLTargetStr == " intel_gpu_pvc" )
619
+ return AOT_PVC;
620
+
621
+ if (SYCLTargetStr.starts_with (" intel_gpu_dg2" ))
622
+ return AOT_DG2;
623
+
624
+ if (SYCLTargetStr.starts_with (" spir64_gen" )) {
625
+ ArgStringList TargArgs;
626
+ Args.AddAllArgValues (TargArgs, options::OPT_Xs, options::OPT_Xs_separate);
627
+ Args.AddAllArgValues (TargArgs, options::OPT_Xsycl_backend);
628
+ llvm::opt::Arg *A = nullptr ;
629
+ if ((A = Args.getLastArg (options::OPT_Xsycl_backend_EQ)) &&
630
+ StringRef (A->getValue ()).starts_with (" spir64_gen" ))
631
+ TargArgs.push_back (A->getValue (1 ));
632
+
633
+ return getSpecificGPUTarget (TargArgs);
634
+ }
635
+
636
+ return JIT;
637
+ };
638
+
496
639
addLibraries (SYCLDeviceWrapperLibs);
497
640
if (IsSpirvAOT)
498
641
addLibraries (SYCLDeviceFallbackLibs);
@@ -512,13 +655,14 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
512
655
addLibraries (SYCLDeviceAnnotationLibs);
513
656
514
657
#if !defined(_WIN32)
658
+ size_t sanitizer_lib_idx = getSingleBuildTarget ();
515
659
if (Arg *A = Args.getLastArg (options::OPT_fsanitize_EQ,
516
660
options::OPT_fno_sanitize_EQ)) {
517
661
if (A->getOption ().matches (options::OPT_fsanitize_EQ) &&
518
662
A->getValues ().size () == 1 ) {
519
663
std::string SanitizeVal = A->getValue ();
520
664
if (SanitizeVal == " address" )
521
- addLibraries (SYCLDeviceSanitizerLibs );
665
+ addSingleLibrary (SYCLDeviceAsanLibs[sanitizer_lib_idx] );
522
666
}
523
667
} else {
524
668
// User can pass -fsanitize=address to device compiler via
@@ -546,7 +690,7 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
546
690
}
547
691
548
692
if (IsDeviceAsanEnabled)
549
- addLibraries (SYCLDeviceSanitizerLibs );
693
+ addSingleLibrary (SYCLDeviceAsanLibs[sanitizer_lib_idx] );
550
694
}
551
695
#endif
552
696
@@ -663,7 +807,10 @@ static llvm::SmallVector<StringRef, 16> SYCLDeviceLibList{
663
807
#if defined(_WIN32)
664
808
" msvc-math" ,
665
809
#else
666
- " sanitizer" ,
810
+ " asan" ,
811
+ " asan-pvc" ,
812
+ " asan-cpu" ,
813
+ " asan-dg2" ,
667
814
#endif
668
815
" imf" ,
669
816
" imf-fp64" ,
@@ -1131,87 +1278,23 @@ void SYCL::fpga::BackendCompiler::ConstructJob(
1131
1278
C.addCommand (std::move (Cmd));
1132
1279
}
1133
1280
1134
- struct OclocInfo {
1135
- const char *DeviceName;
1136
- const char *PackageName;
1137
- const char *Version;
1138
- SmallVector<int , 8 > HexValues;
1139
- };
1140
-
1141
- // The PVCDevices data structure is organized by device name, with the
1142
- // corresponding ocloc split release, version and possible Hex representations
1143
- // of various PVC devices. This information is gathered from the following:
1144
- // https://github.com/intel/compute-runtime/blob/master/shared/source/dll/devices/devices_base.inl
1145
- // https://github.com/intel/compute-runtime/blob/master/shared/source/dll/devices/devices_additional.inl
1146
- static OclocInfo PVCDevices[] = {
1147
- {" pvc-sdv" , " gen12+" , " 12.60.1" , {}},
1148
- {" pvc" ,
1149
- " gen12+" ,
1150
- " 12.60.7" ,
1151
- {0x0BD0 , 0x0BD5 , 0x0BD6 , 0x0BD7 , 0x0BD8 , 0x0BD9 , 0x0BDA , 0x0BDB }}};
1152
-
1153
1281
// Determine if any of the given arguments contain any PVC based values for
1154
1282
// the -device option.
1155
1283
static bool hasPVCDevice (const ArgStringList &CmdArgs, std::string &DevArg) {
1156
- bool DeviceSeen = false ;
1157
- StringRef DeviceArg;
1158
- for (StringRef Arg : CmdArgs) {
1159
- // -device <arg> comes in as a single arg, split up all potential space
1160
- // separated values.
1161
- SmallVector<StringRef> SplitArgs;
1162
- Arg.split (SplitArgs, ' ' );
1163
- for (StringRef SplitArg : SplitArgs) {
1164
- if (DeviceSeen) {
1165
- DeviceArg = SplitArg;
1166
- break ;
1167
- }
1168
- if (SplitArg == " -device" )
1169
- DeviceSeen = true ;
1170
- }
1171
- if (DeviceSeen)
1172
- break ;
1173
- }
1174
- if (DeviceArg.empty ())
1284
+ std::string Res = getDeviceArg (CmdArgs);
1285
+ if (Res.empty ())
1175
1286
return false ;
1176
-
1177
1287
// Go through all of the arguments to '-device' and determine if any of these
1178
1288
// are pvc based. We only match literal values and will not find a match
1179
1289
// when ranges or wildcards are used.
1180
1290
// Here we parse the targets, tokenizing via ','
1291
+ StringRef DeviceArg (Res.c_str ());
1181
1292
SmallVector<StringRef> SplitArgs;
1182
1293
DeviceArg.split (SplitArgs, " ," );
1183
1294
for (const auto &SingleArg : SplitArgs) {
1184
- StringRef OclocTarget;
1185
- // Handle shortened versions.
1186
- bool CheckShortVersion = true ;
1187
- for (auto Char : SingleArg.str ()) {
1188
- if (!std::isdigit (Char) && Char != ' .' ) {
1189
- CheckShortVersion = false ;
1190
- break ;
1191
- }
1192
- }
1193
- // Check for device, version or hex (literal values)
1194
- for (unsigned int I = 0 ; I < std::size (PVCDevices); I++) {
1195
- if (SingleArg.equals_insensitive (PVCDevices[I].DeviceName ) ||
1196
- SingleArg.equals_insensitive (PVCDevices[I].Version )) {
1197
- DevArg = SingleArg.str ();
1198
- return true ;
1199
- }
1200
- for (int HexVal : PVCDevices[I].HexValues ) {
1201
- int Value = 0 ;
1202
- if (!SingleArg.getAsInteger (0 , Value) && Value == HexVal) {
1203
- // TODO: Pass back the hex string to use for -device_options when
1204
- // IGC is updated to allow. Currently -device_options only accepts
1205
- // the device ID (i.e. pvc) or the version (12.60.7).
1206
- return true ;
1207
- }
1208
- }
1209
- if (CheckShortVersion &&
1210
- StringRef (PVCDevices[I].Version ).starts_with (SingleArg)) {
1211
- DevArg = SingleArg.str ();
1212
- return true ;
1213
- }
1214
- }
1295
+ bool IsPVC = checkPVCDevice (SingleArg.str (), DevArg);
1296
+ if (IsPVC)
1297
+ return true ;
1215
1298
}
1216
1299
return false ;
1217
1300
}
0 commit comments