Skip to content

Commit deffa0a

Browse files
committed
[SYCL][Driver][NFC] Split Device Santizer Libs link from getSYCLDeviceLibrary
Signed-off-by: jinge90 <[email protected]>
1 parent acbca47 commit deffa0a

File tree

1 file changed

+136
-136
lines changed

1 file changed

+136
-136
lines changed

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 136 additions & 136 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,141 @@ static bool checkPVCDevice(std::string SingleArg, std::string &DevArg) {
426426
return false;
427427
}
428428

429+
#if !defined(_WIN32)
430+
static void
431+
addSYCLDeviceSanitizerLibs(const Compilation &C, bool IsSpirvAOT,
432+
StringRef LibSuffix,
433+
SmallVector<std::string, 8> &LibraryList) {
434+
const llvm::opt::ArgList &Args = C.getArgs();
435+
enum { JIT = 0, AOT_CPU, AOT_DG2, AOT_PVC };
436+
auto addSingleLibrary = [&](StringRef DeviceLibName) {
437+
SmallString<128> LibName(DeviceLibName);
438+
llvm::sys::path::replace_extension(LibName, LibSuffix);
439+
LibraryList.push_back(Args.MakeArgString(LibName));
440+
};
441+
442+
// This function is used to check whether there is only one GPU device
443+
// (PVC or DG2) specified in AOT compilation mode. If yes, we can use
444+
// corresponding libsycl-asan-* to improve device sanitizer performance,
445+
// otherwise stick to fallback device sanitizer library used in JIT mode.
446+
auto getSpecificGPUTarget = [](const ArgStringList &CmdArgs) -> size_t {
447+
std::string DeviceArg = getDeviceArg(CmdArgs);
448+
if ((DeviceArg.empty()) || (DeviceArg.find(",") != std::string::npos))
449+
return JIT;
450+
451+
std::string Temp;
452+
if (checkPVCDevice(DeviceArg, Temp))
453+
return AOT_PVC;
454+
455+
if (DeviceArg == "dg2")
456+
return AOT_DG2;
457+
458+
return JIT;
459+
};
460+
461+
auto getSingleBuildTarget = [&]() -> size_t {
462+
if (!IsSpirvAOT)
463+
return JIT;
464+
465+
llvm::opt::Arg *SYCLTarget = Args.getLastArg(options::OPT_fsycl_targets_EQ);
466+
if (!SYCLTarget || (SYCLTarget->getValues().size() != 1))
467+
return JIT;
468+
469+
StringRef SYCLTargetStr = SYCLTarget->getValue();
470+
if (SYCLTargetStr.starts_with("spir64_x86_64"))
471+
return AOT_CPU;
472+
473+
if (SYCLTargetStr == "intel_gpu_pvc")
474+
return AOT_PVC;
475+
476+
if (SYCLTargetStr.starts_with("intel_gpu_dg2"))
477+
return AOT_DG2;
478+
479+
if (SYCLTargetStr.starts_with("spir64_gen")) {
480+
ArgStringList TargArgs;
481+
Args.AddAllArgValues(TargArgs, options::OPT_Xs, options::OPT_Xs_separate);
482+
Args.AddAllArgValues(TargArgs, options::OPT_Xsycl_backend);
483+
llvm::opt::Arg *A = nullptr;
484+
if ((A = Args.getLastArg(options::OPT_Xsycl_backend_EQ)) &&
485+
StringRef(A->getValue()).starts_with("spir64_gen"))
486+
TargArgs.push_back(A->getValue(1));
487+
488+
return getSpecificGPUTarget(TargArgs);
489+
}
490+
491+
return JIT;
492+
};
493+
494+
std::string SanitizeVal;
495+
size_t sanitizer_lib_idx = getSingleBuildTarget();
496+
if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ,
497+
options::OPT_fno_sanitize_EQ)) {
498+
if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
499+
A->getValues().size() == 1) {
500+
SanitizeVal = A->getValue();
501+
}
502+
} else {
503+
// User can pass -fsanitize=address to device compiler via
504+
// -Xsycl-target-frontend, sanitize device library must be
505+
// linked with user's device image if so.
506+
std::vector<std::string> EnabledDeviceSanitizers;
507+
508+
// NOTE: "-fsanitize=" applies to all device targets
509+
auto SyclFEArgVals = Args.getAllArgValues(options::OPT_Xsycl_frontend);
510+
auto SyclFEEQArgVals = Args.getAllArgValues(options::OPT_Xsycl_frontend_EQ);
511+
auto ArchDeviceVals = Args.getAllArgValues(options::OPT_Xarch_device);
512+
513+
std::vector<std::string> ArgVals(
514+
SyclFEArgVals.size() + SyclFEEQArgVals.size() + ArchDeviceVals.size());
515+
ArgVals.insert(ArgVals.end(), SyclFEArgVals.begin(), SyclFEArgVals.end());
516+
ArgVals.insert(ArgVals.end(), SyclFEEQArgVals.begin(),
517+
SyclFEEQArgVals.end());
518+
ArgVals.insert(ArgVals.end(), ArchDeviceVals.begin(), ArchDeviceVals.end());
519+
520+
// Driver will report error if more than one of address sanitizer, memory
521+
// sanitizer or thread sanitizer is enabled, so we only need to check first
522+
// one here.
523+
for (const std::string &Arg : ArgVals) {
524+
if (Arg.find("-fsanitize=address") != std::string::npos) {
525+
SanitizeVal = "address";
526+
break;
527+
}
528+
if (Arg.find("-fsanitize=memory") != std::string::npos) {
529+
SanitizeVal = "memory";
530+
break;
531+
}
532+
if (Arg.find("-fsanitize=thread") != std::string::npos) {
533+
SanitizeVal = "thread";
534+
break;
535+
}
536+
}
537+
}
538+
539+
const SmallVector<StringRef, 5> SYCLDeviceAsanLibs = {
540+
"libsycl-asan", "libsycl-asan-cpu", "libsycl-asan-dg2",
541+
"libsycl-asan-pvc"};
542+
const SmallVector<StringRef, 5> SYCLDeviceMsanLibs = {
543+
"libsycl-msan", "libsycl-msan-cpu",
544+
// Currently, we only provide aot msan libdevice for PVC and CPU.
545+
// For DG2, we just use libsycl-msan as placeholder.
546+
"libsycl-msan", "libsycl-msan-pvc"};
547+
const SmallVector<StringRef, 5> SYCLDeviceTsanLibs = {
548+
"libsycl-tsan", "libsycl-tsan-cpu",
549+
// Currently, we only provide aot tsan libdevice for PVC and CPU.
550+
// For DG2, we just use libsycl-tsan as placeholder.
551+
// TODO: replace "libsycl-tsan" with "libsycl-tsan-dg2" when DG2
552+
// AOT support is added.
553+
"libsycl-tsan", "libsycl-tsan-pvc"};
554+
555+
if (SanitizeVal == "address")
556+
addSingleLibrary(SYCLDeviceAsanLibs[sanitizer_lib_idx]);
557+
else if (SanitizeVal == "memory")
558+
addSingleLibrary(SYCLDeviceMsanLibs[sanitizer_lib_idx]);
559+
else if (SanitizeVal == "thread")
560+
addSingleLibrary(SYCLDeviceTsanLibs[sanitizer_lib_idx]);
561+
}
562+
#endif
563+
429564
SmallVector<std::string, 8>
430565
SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
431566
bool IsSpirvAOT) {
@@ -551,30 +686,6 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
551686
{"libsycl-itt-user-wrappers", "internal"},
552687
{"libsycl-itt-compiler-wrappers", "internal"},
553688
{"libsycl-itt-stubs", "internal"}};
554-
#if !defined(_WIN32)
555-
const SYCLDeviceLibsList SYCLDeviceAsanLibs = {
556-
{"libsycl-asan", "internal"},
557-
{"libsycl-asan-cpu", "internal"},
558-
{"libsycl-asan-dg2", "internal"},
559-
{"libsycl-asan-pvc", "internal"}};
560-
const SYCLDeviceLibsList SYCLDeviceMsanLibs = {
561-
{"libsycl-msan", "internal"},
562-
{"libsycl-msan-cpu", "internal"},
563-
// Currently, we only provide aot msan libdevice for PVC and CPU.
564-
// For DG2, we just use libsycl-msan as placeholder.
565-
{"libsycl-msan", "internal"},
566-
{"libsycl-msan-pvc", "internal"}};
567-
const SYCLDeviceLibsList SYCLDeviceTsanLibs = {
568-
{"libsycl-tsan", "internal"},
569-
{"libsycl-tsan-cpu", "internal"},
570-
// Currently, we only provide aot tsan libdevice for PVC and CPU.
571-
// For DG2, we just use libsycl-tsan as placeholder.
572-
// TODO: replace "libsycl-tsan" with "libsycl-tsan-dg2" when DG2
573-
// AOT support is added.
574-
{"libsycl-tsan", "internal"},
575-
{"libsycl-tsan-pvc", "internal"}};
576-
#endif
577-
578689
const SYCLDeviceLibsList SYCLNativeCpuDeviceLibs = {
579690
{"libsycl-nativecpu_utils", "internal"}};
580691

@@ -617,118 +728,7 @@ SYCL::getDeviceLibraries(const Compilation &C, const llvm::Triple &TargetTriple,
617728
addLibraries(SYCLDeviceAnnotationLibs);
618729

619730
#if !defined(_WIN32)
620-
621-
auto addSingleLibrary = [&](const DeviceLibOptInfo &Lib) {
622-
if (!DeviceLibLinkInfo[Lib.DeviceLibOption])
623-
return;
624-
SmallString<128> LibName(Lib.DeviceLibName);
625-
llvm::sys::path::replace_extension(LibName, LibSuffix);
626-
LibraryList.push_back(Args.MakeArgString(LibName));
627-
};
628-
629-
// This function is used to check whether there is only one GPU device
630-
// (PVC or DG2) specified in AOT compilation mode. If yes, we can use
631-
// corresponding libsycl-asan-* to improve device sanitizer performance,
632-
// otherwise stick to fallback device sanitizer library used in JIT mode.
633-
auto getSpecificGPUTarget = [](const ArgStringList &CmdArgs) -> size_t {
634-
std::string DeviceArg = getDeviceArg(CmdArgs);
635-
if ((DeviceArg.empty()) || (DeviceArg.find(",") != std::string::npos))
636-
return JIT;
637-
638-
std::string Temp;
639-
if (checkPVCDevice(DeviceArg, Temp))
640-
return AOT_PVC;
641-
642-
if (DeviceArg == "dg2")
643-
return AOT_DG2;
644-
645-
return JIT;
646-
};
647-
648-
auto getSingleBuildTarget = [&]() -> size_t {
649-
if (!IsSpirvAOT)
650-
return JIT;
651-
652-
llvm::opt::Arg *SYCLTarget = Args.getLastArg(options::OPT_fsycl_targets_EQ);
653-
if (!SYCLTarget || (SYCLTarget->getValues().size() != 1))
654-
return JIT;
655-
656-
StringRef SYCLTargetStr = SYCLTarget->getValue();
657-
if (SYCLTargetStr.starts_with("spir64_x86_64"))
658-
return AOT_CPU;
659-
660-
if (SYCLTargetStr == "intel_gpu_pvc")
661-
return AOT_PVC;
662-
663-
if (SYCLTargetStr.starts_with("intel_gpu_dg2"))
664-
return AOT_DG2;
665-
666-
if (SYCLTargetStr.starts_with("spir64_gen")) {
667-
ArgStringList TargArgs;
668-
Args.AddAllArgValues(TargArgs, options::OPT_Xs, options::OPT_Xs_separate);
669-
Args.AddAllArgValues(TargArgs, options::OPT_Xsycl_backend);
670-
llvm::opt::Arg *A = nullptr;
671-
if ((A = Args.getLastArg(options::OPT_Xsycl_backend_EQ)) &&
672-
StringRef(A->getValue()).starts_with("spir64_gen"))
673-
TargArgs.push_back(A->getValue(1));
674-
675-
return getSpecificGPUTarget(TargArgs);
676-
}
677-
678-
return JIT;
679-
};
680-
681-
std::string SanitizeVal;
682-
size_t sanitizer_lib_idx = getSingleBuildTarget();
683-
if (Arg *A = Args.getLastArg(options::OPT_fsanitize_EQ,
684-
options::OPT_fno_sanitize_EQ)) {
685-
if (A->getOption().matches(options::OPT_fsanitize_EQ) &&
686-
A->getValues().size() == 1) {
687-
SanitizeVal = A->getValue();
688-
}
689-
} else {
690-
// User can pass -fsanitize=address to device compiler via
691-
// -Xsycl-target-frontend, sanitize device library must be
692-
// linked with user's device image if so.
693-
std::vector<std::string> EnabledDeviceSanitizers;
694-
695-
// NOTE: "-fsanitize=" applies to all device targets
696-
auto SyclFEArgVals = Args.getAllArgValues(options::OPT_Xsycl_frontend);
697-
auto SyclFEEQArgVals = Args.getAllArgValues(options::OPT_Xsycl_frontend_EQ);
698-
auto ArchDeviceVals = Args.getAllArgValues(options::OPT_Xarch_device);
699-
700-
std::vector<std::string> ArgVals(
701-
SyclFEArgVals.size() + SyclFEEQArgVals.size() + ArchDeviceVals.size());
702-
ArgVals.insert(ArgVals.end(), SyclFEArgVals.begin(), SyclFEArgVals.end());
703-
ArgVals.insert(ArgVals.end(), SyclFEEQArgVals.begin(),
704-
SyclFEEQArgVals.end());
705-
ArgVals.insert(ArgVals.end(), ArchDeviceVals.begin(), ArchDeviceVals.end());
706-
707-
// Driver will report error if more than one of address sanitizer, memory
708-
// sanitizer or thread sanitizer is enabled, so we only need to check first
709-
// one here.
710-
for (const std::string &Arg : ArgVals) {
711-
if (Arg.find("-fsanitize=address") != std::string::npos) {
712-
SanitizeVal = "address";
713-
break;
714-
}
715-
if (Arg.find("-fsanitize=memory") != std::string::npos) {
716-
SanitizeVal = "memory";
717-
break;
718-
}
719-
if (Arg.find("-fsanitize=thread") != std::string::npos) {
720-
SanitizeVal = "thread";
721-
break;
722-
}
723-
}
724-
}
725-
726-
if (SanitizeVal == "address")
727-
addSingleLibrary(SYCLDeviceAsanLibs[sanitizer_lib_idx]);
728-
else if (SanitizeVal == "memory")
729-
addSingleLibrary(SYCLDeviceMsanLibs[sanitizer_lib_idx]);
730-
else if (SanitizeVal == "thread")
731-
addSingleLibrary(SYCLDeviceTsanLibs[sanitizer_lib_idx]);
731+
addSYCLDeviceSanitizerLibs(C, IsSpirvAOT, LibSuffix, LibraryList);
732732
#endif
733733

734734
if (TargetTriple.isNativeCPU())

0 commit comments

Comments
 (0)