@@ -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