@@ -345,6 +345,84 @@ static bool selectBfloatLibs(const llvm::Triple &Triple, const Compilation &C,
345345 return NeedLibs;
346346}
347347
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+
348426SmallVector<std::string, 8 >
349427SYCL::getDeviceLibraries (const Compilation &C, const llvm::Triple &TargetTriple,
350428 bool IsSpirvAOT) {
@@ -360,6 +438,8 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
360438 StringRef DeviceLibOption;
361439 };
362440
441+ enum { JIT = 0 , AOT_CPU, AOT_DG2, AOT_PVC };
442+
363443 // Currently, all SYCL device libraries will be linked by default.
364444 llvm::StringMap<bool > DeviceLibLinkInfo = {
365445 {" libc" , true }, {" libm-fp32" , true }, {" libm-fp64" , true },
@@ -460,8 +540,11 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
460540 {" libsycl-itt-compiler-wrappers" , " internal" },
461541 {" libsycl-itt-stubs" , " internal" }};
462542#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" }};
465548#endif
466549
467550 const SYCLDeviceLibsList SYCLNativeCpuDeviceLibs = {
@@ -493,6 +576,66 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
493576 }
494577 };
495578
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+
496639 addLibraries (SYCLDeviceWrapperLibs);
497640 if (IsSpirvAOT)
498641 addLibraries (SYCLDeviceFallbackLibs);
@@ -512,13 +655,14 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
512655 addLibraries (SYCLDeviceAnnotationLibs);
513656
514657#if !defined(_WIN32)
658+ size_t sanitizer_lib_idx = getSingleBuildTarget ();
515659 if (Arg *A = Args.getLastArg (options::OPT_fsanitize_EQ,
516660 options::OPT_fno_sanitize_EQ)) {
517661 if (A->getOption ().matches (options::OPT_fsanitize_EQ) &&
518662 A->getValues ().size () == 1 ) {
519663 std::string SanitizeVal = A->getValue ();
520664 if (SanitizeVal == " address" )
521- addLibraries (SYCLDeviceSanitizerLibs );
665+ addSingleLibrary (SYCLDeviceAsanLibs[sanitizer_lib_idx] );
522666 }
523667 } else {
524668 // User can pass -fsanitize=address to device compiler via
@@ -546,7 +690,7 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
546690 }
547691
548692 if (IsDeviceAsanEnabled)
549- addLibraries (SYCLDeviceSanitizerLibs );
693+ addSingleLibrary (SYCLDeviceAsanLibs[sanitizer_lib_idx] );
550694 }
551695#endif
552696
@@ -663,7 +807,10 @@ static llvm::SmallVector<StringRef, 16> SYCLDeviceLibList{
663807#if defined(_WIN32)
664808 " msvc-math" ,
665809#else
666- " sanitizer" ,
810+ " asan" ,
811+ " asan-pvc" ,
812+ " asan-cpu" ,
813+ " asan-dg2" ,
667814#endif
668815 " imf" ,
669816 " imf-fp64" ,
@@ -1131,87 +1278,23 @@ void SYCL::fpga::BackendCompiler::ConstructJob(
11311278 C.addCommand (std::move (Cmd));
11321279}
11331280
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-
11531281// Determine if any of the given arguments contain any PVC based values for
11541282// the -device option.
11551283static 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 ())
11751286 return false ;
1176-
11771287 // Go through all of the arguments to '-device' and determine if any of these
11781288 // are pvc based. We only match literal values and will not find a match
11791289 // when ranges or wildcards are used.
11801290 // Here we parse the targets, tokenizing via ','
1291+ StringRef DeviceArg (Res.c_str ());
11811292 SmallVector<StringRef> SplitArgs;
11821293 DeviceArg.split (SplitArgs, " ," );
11831294 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 ;
12151298 }
12161299 return false ;
12171300}
0 commit comments