Skip to content

Commit dd3c846

Browse files
author
iclsrc
committed
Merge from 'sycl' to 'sycl-web'
2 parents ea77a04 + 628424a commit dd3c846

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+1180
-669
lines changed

clang/include/clang/Driver/Options.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3580,6 +3580,15 @@ def fsycl_dead_args_optimization : Flag<["-"], "fsycl-dead-args-optimization">,
35803580
def fno_sycl_dead_args_optimization : Flag<["-"], "fno-sycl-dead-args-optimization">,
35813581
Group<sycl_Group>, Flags<[NoArgumentUnused, CoreOption]>, HelpText<"Disables "
35823582
"elimination of DPC++ dead kernel arguments">;
3583+
def fsycl_device_lib_EQ : CommaJoined<["-"], "fsycl-device-lib=">, Group<sycl_Group>, Flags<[DriverOption, CoreOption]>,
3584+
Values<"libc, libm-fp32, libm-fp64, all">, HelpText<"Control inclusion of "
3585+
"device libraries into device binary linkage. Valid arguments "
3586+
"are libc, libm-fp32, libm-fp64, all">;
3587+
def fno_sycl_device_lib_EQ : CommaJoined<["-"], "fno-sycl-device-lib=">, Group<sycl_Group>, Flags<[DriverOption, CoreOption]>,
3588+
Values<"libc, libm-fp32, libm-fp64, all">, HelpText<"Control exclusion of "
3589+
"device libraries from device binary linkage. Valid arguments "
3590+
"are libc, libm-fp32, libm-fp64, all">;
3591+
35833592
//===----------------------------------------------------------------------===//
35843593
// CC1 Options
35853594
//===----------------------------------------------------------------------===//

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 57 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2264,6 +2264,30 @@ void CodeGenModule::EmitDeferred() {
22642264
CurDeclsToEmit.swap(DeferredDeclsToEmit);
22652265

22662266
for (GlobalDecl &D : CurDeclsToEmit) {
2267+
const ValueDecl *VD = cast<ValueDecl>(D.getDecl());
2268+
// If emitting for SYCL device, emit the deferred alias
2269+
// as well as what it aliases.
2270+
if (LangOpts.SYCLIsDevice) {
2271+
if (AliasAttr *Attr = VD->getAttr<AliasAttr>()) {
2272+
StringRef AliaseeName = Attr->getAliasee();
2273+
auto DDI = DeferredDecls.find(AliaseeName);
2274+
// Emit what is aliased first.
2275+
if (DDI != DeferredDecls.end()) {
2276+
llvm::GlobalValue *AliaseeGV = dyn_cast<llvm::GlobalValue>(
2277+
GetAddrOfGlobal(DDI->second, ForDefinition));
2278+
if (!AliaseeGV)
2279+
AliaseeGV = GetGlobalValue(getMangledName(DDI->second));
2280+
assert(AliaseeGV);
2281+
EmitGlobalDefinition(DDI->second, AliaseeGV);
2282+
// Remove the entry just added to the DeferredDeclsToEmit
2283+
// since we have emitted it.
2284+
DeferredDeclsToEmit.pop_back();
2285+
}
2286+
// Now emit the alias itself.
2287+
EmitAliasDefinition(D);
2288+
continue;
2289+
}
2290+
}
22672291
// We should call GetAddrOfGlobal with IsForDefinition set to true in order
22682292
// to get GlobalValue with exactly the type we need, not something that
22692293
// might had been created for another decl with the same mangled name but
@@ -2296,6 +2320,20 @@ void CodeGenModule::EmitDeferred() {
22962320
// Otherwise, emit the definition and move on to the next one.
22972321
EmitGlobalDefinition(D, GV);
22982322

2323+
if (LangOpts.SYCLIsDevice) {
2324+
// If there are any aliases deferred for this, emit those now.
2325+
for (auto It = DeferredAliases.begin(); It != DeferredAliases.end();
2326+
/*no increment*/) {
2327+
const ValueDecl *Global = cast<ValueDecl>(It->second.getDecl());
2328+
if (It->first == getMangledName(D)) {
2329+
EmitAliasDefinition(Global);
2330+
It = DeferredAliases.erase(It);
2331+
} else {
2332+
++It;
2333+
}
2334+
}
2335+
}
2336+
22992337
// If we found out that we need to emit more decls, do that recursively.
23002338
// This has the advantage that the decls are emitted in a DFS and related
23012339
// ones are close together, which is convenient for testing.
@@ -2619,9 +2657,19 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
26192657
return;
26202658

26212659
// If this is an alias definition (which otherwise looks like a declaration)
2622-
// emit it now.
2623-
if (Global->hasAttr<AliasAttr>())
2624-
return EmitAliasDefinition(GD);
2660+
// handle it now.
2661+
if (AliasAttr *Attr = Global->getAttr<AliasAttr>()) {
2662+
// Emit the alias here if it is not SYCL device compilation.
2663+
if (!LangOpts.SYCLIsDevice)
2664+
return EmitAliasDefinition(GD);
2665+
// Defer for SYCL devices, until either the alias or what it aliases
2666+
// is used.
2667+
StringRef MangledName = getMangledName(GD);
2668+
DeferredDecls[MangledName] = GD;
2669+
StringRef AliaseeName = Attr->getAliasee();
2670+
DeferredAliases[AliaseeName] = GD;
2671+
return;
2672+
}
26252673

26262674
// IFunc like an alias whose value is resolved at runtime by calling resolver.
26272675
if (Global->hasAttr<IFuncAttr>())
@@ -4836,20 +4884,21 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
48364884
// if a deferred decl.
48374885
llvm::Constant *Aliasee;
48384886
llvm::GlobalValue::LinkageTypes LT;
4887+
unsigned AS;
48394888
if (isa<llvm::FunctionType>(DeclTy)) {
48404889
Aliasee = GetOrCreateLLVMFunction(AA->getAliasee(), DeclTy, GD,
48414890
/*ForVTable=*/false);
48424891
LT = getFunctionLinkage(GD);
4892+
AS = Aliasee->getType()->getPointerAddressSpace();
48434893
} else {
4844-
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(),
4845-
llvm::PointerType::getUnqual(DeclTy),
4894+
AS = ArgInfoAddressSpace(GetGlobalVarAddressSpace(/*D=*/nullptr));
4895+
Aliasee = GetOrCreateLLVMGlobal(AA->getAliasee(), DeclTy->getPointerTo(AS),
48464896
/*D=*/nullptr);
48474897
LT = getLLVMLinkageVarDefinition(cast<VarDecl>(GD.getDecl()),
48484898
D->getType().isConstQualified());
48494899
}
48504900

48514901
// Create the new alias itself, but don't set a name yet.
4852-
unsigned AS = Aliasee->getType()->getPointerAddressSpace();
48534902
auto *GA =
48544903
llvm::GlobalAlias::create(DeclTy, AS, LT, "", Aliasee, &getModule());
48554904

@@ -4870,8 +4919,8 @@ void CodeGenModule::EmitAliasDefinition(GlobalDecl GD) {
48704919
// Remove it and replace uses of it with the alias.
48714920
GA->takeName(Entry);
48724921

4873-
Entry->replaceAllUsesWith(llvm::ConstantExpr::getBitCast(GA,
4874-
Entry->getType()));
4922+
Entry->replaceAllUsesWith(
4923+
llvm::ConstantExpr::getBitCast(GA, Entry->getType()));
48754924
Entry->eraseFromParent();
48764925
} else {
48774926
GA->setName(MangledName);

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,11 @@ class CodeGenModule : public CodeGenTypeCache {
345345
/// yet.
346346
std::map<StringRef, GlobalDecl> DeferredDecls;
347347

348+
/// This contains all the aliases that are deferred for emission until
349+
/// they or what they alias are actually used. Note that the StringRef
350+
/// associated in this map is that of the aliasee.
351+
std::map<StringRef, GlobalDecl> DeferredAliases;
352+
348353
/// This is a list of deferred decls which we have seen that *are* actually
349354
/// referenced. These get code generated when the module is done.
350355
std::vector<GlobalDecl> DeferredDeclsToEmit;

clang/lib/Driver/Driver.cpp

Lines changed: 117 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
66
//
77
//===----------------------------------------------------------------------===//
8-
98
#include "clang/Driver/Driver.h"
109
#include "InputInfo.h"
1110
#include "ToolChains/AIX.h"
@@ -2727,6 +2726,16 @@ static SmallVector<const char *, 16> getLinkerArgs(Compilation &C,
27272726
return LibArgs;
27282727
}
27292728

2729+
static bool IsSYCLDeviceLibObj(std::string ObjFilePath, bool isMSVCEnv) {
2730+
StringRef ObjFileName = llvm::sys::path::filename(ObjFilePath);
2731+
StringRef ObjSuffix = isMSVCEnv ? ".obj" : ".o";
2732+
bool Ret =
2733+
(ObjFileName.startswith("libsycl-") && ObjFileName.endswith(ObjSuffix))
2734+
? true
2735+
: false;
2736+
return Ret;
2737+
}
2738+
27302739
// Goes through all of the arguments, including inputs expected for the
27312740
// linker directly, to determine if we need to perform additional work for
27322741
// static offload libraries.
@@ -3805,7 +3814,13 @@ class OffloadingActionBuilder final {
38053814
if (IA->getType() == types::TY_Object) {
38063815
if (!isObjectFile(FileName))
38073816
return ABRT_Inactive;
3808-
if (Args.hasArg(options::OPT_fintelfpga))
3817+
// For SYCL device libraries, don't need to add them to
3818+
// FPGAObjectInputs as there is no FPGA dep files inside.
3819+
3820+
if (Args.hasArg(options::OPT_fintelfpga) &&
3821+
!IsSYCLDeviceLibObj(FileName, C.getDefaultToolChain()
3822+
.getTriple()
3823+
.isWindowsMSVCEnvironment()))
38093824
FPGAObjectInputs.push_back(IA);
38103825
}
38113826
// When creating FPGA device fat objects, all host objects are
@@ -3869,6 +3884,92 @@ class OffloadingActionBuilder final {
38693884
SYCLDeviceActions.clear();
38703885
}
38713886

3887+
void addSYCLDeviceLibs(const ToolChain *TC, ActionList &DeviceLinkObjects,
3888+
bool isSpirvAOT, bool isMSVCEnv) {
3889+
enum SYCLDeviceLibType {
3890+
sycl_devicelib_wrapper,
3891+
sycl_devicelib_fallback
3892+
};
3893+
struct DeviceLibOptInfo {
3894+
StringRef devicelib_name;
3895+
StringRef devicelib_option;
3896+
};
3897+
3898+
bool NoDeviceLibs = false;
3899+
// Currently, libc, libm-fp32 will be linked in by default. In order
3900+
// to use libm-fp64, -fsycl-device-lib=libm-fp64/all should be used.
3901+
llvm::StringMap<bool> devicelib_link_info = {
3902+
{"libc", true}, {"libm-fp32", true}, {"libm-fp64", false}};
3903+
if (Arg *A = Args.getLastArg(options::OPT_fsycl_device_lib_EQ,
3904+
options::OPT_fno_sycl_device_lib_EQ)) {
3905+
if (A->getValues().size() == 0)
3906+
C.getDriver().Diag(diag::warn_drv_empty_joined_argument)
3907+
<< A->getAsString(Args);
3908+
else {
3909+
if (A->getOption().matches(options::OPT_fno_sycl_device_lib_EQ))
3910+
NoDeviceLibs = true;
3911+
3912+
for (StringRef Val : A->getValues()) {
3913+
if (Val == "all") {
3914+
for (auto &K : devicelib_link_info.keys())
3915+
devicelib_link_info[K] = true && !NoDeviceLibs;
3916+
break;
3917+
}
3918+
auto LinkInfoIter = devicelib_link_info.find(Val);
3919+
if (LinkInfoIter == devicelib_link_info.end()) {
3920+
C.getDriver().Diag(diag::err_drv_unsupported_option_argument)
3921+
<< A->getOption().getName() << Val;
3922+
}
3923+
devicelib_link_info[Val] = true && !NoDeviceLibs;
3924+
}
3925+
}
3926+
}
3927+
3928+
SmallString<128> LibLoc(TC->getDriver().Dir);
3929+
llvm::sys::path::append(LibLoc, "/../lib");
3930+
StringRef LibSuffix = isMSVCEnv ? ".obj" : ".o";
3931+
SmallVector<DeviceLibOptInfo, 5> sycl_device_wrapper_libs = {
3932+
{"libsycl-crt", "libc"},
3933+
{"libsycl-complex", "libm-fp32"},
3934+
{"libsycl-complex-fp64", "libm-fp64"},
3935+
{"libsycl-cmath", "libm-fp32"},
3936+
{"libsycl-cmath-fp64", "libm-fp64"}};
3937+
// For AOT compilation, we need to link sycl_device_fallback_libs as
3938+
// default too.
3939+
SmallVector<DeviceLibOptInfo, 5> sycl_device_fallback_libs = {
3940+
{"libsycl-fallback-cassert", "libc"},
3941+
{"libsycl-fallback-complex", "libm-fp32"},
3942+
{"libsycl-fallback-complex-fp64", "libm-fp64"},
3943+
{"libsycl-fallback-cmath", "libm-fp32"},
3944+
{"libsycl-fallback-cmath-fp64", "libm-fp64"}};
3945+
auto addInputs = [&](SYCLDeviceLibType t) {
3946+
auto sycl_libs = (t == sycl_devicelib_wrapper)
3947+
? sycl_device_wrapper_libs
3948+
: sycl_device_fallback_libs;
3949+
for (const DeviceLibOptInfo &Lib : sycl_libs) {
3950+
if (!devicelib_link_info[Lib.devicelib_option])
3951+
continue;
3952+
SmallString<128> LibName(LibLoc);
3953+
llvm::sys::path::append(LibName, Lib.devicelib_name);
3954+
llvm::sys::path::replace_extension(LibName, LibSuffix);
3955+
if (llvm::sys::fs::exists(LibName)) {
3956+
Arg *InputArg = MakeInputArg(Args, C.getDriver().getOpts(),
3957+
Args.MakeArgString(LibName));
3958+
auto *SYCLDeviceLibsInputAction =
3959+
C.MakeAction<InputAction>(*InputArg, types::TY_Object);
3960+
auto *SYCLDeviceLibsUnbundleAction =
3961+
C.MakeAction<OffloadUnbundlingJobAction>(
3962+
SYCLDeviceLibsInputAction);
3963+
addDeviceDepences(SYCLDeviceLibsUnbundleAction);
3964+
DeviceLinkObjects.push_back(SYCLDeviceLibsUnbundleAction);
3965+
}
3966+
}
3967+
};
3968+
addInputs(sycl_devicelib_wrapper);
3969+
if (isSpirvAOT)
3970+
addInputs(sycl_devicelib_fallback);
3971+
}
3972+
38723973
void appendLinkDependences(OffloadAction::DeviceDependences &DA) override {
38733974
assert(ToolChains.size() == DeviceLinkerInputs.size() &&
38743975
"Toolchains and linker inputs sizes do not match.");
@@ -3948,13 +4049,27 @@ class OffloadingActionBuilder final {
39484049
}
39494050
ActionList DeviceLibObjects;
39504051
ActionList LinkObjects;
4052+
auto TT = SYCLTripleList[I];
4053+
auto isNVPTX = (*TC)->getTriple().isNVPTX();
4054+
bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
4055+
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
4056+
TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
39514057
for (const auto &Input : LI) {
39524058
// FPGA aoco does not go through the link, everything else does.
39534059
if (Input->getType() == types::TY_FPGA_AOCO)
39544060
DeviceLibObjects.push_back(Input);
39554061
else
39564062
LinkObjects.push_back(Input);
39574063
}
4064+
// FIXME: Link all wrapper and fallback device libraries as default,
4065+
// When spv online link is supported by all backends, the fallback
4066+
// device libraries are only needed when current toolchain is using
4067+
// AOT compilation.
4068+
if (!isNVPTX) {
4069+
addSYCLDeviceLibs(
4070+
*TC, LinkObjects, true,
4071+
C.getDefaultToolChain().getTriple().isWindowsMSVCEnvironment());
4072+
}
39584073
// The linkage actions subgraph leading to the offload wrapper.
39594074
// [cond] Means incoming/outgoing dependence is created only when cond
39604075
// is true. A function of:
@@ -4009,7 +4124,6 @@ class OffloadingActionBuilder final {
40094124
Action *DeviceLinkAction =
40104125
C.MakeAction<LinkJobAction>(LinkObjects, types::TY_LLVM_BC);
40114126
// setup some flags upfront
4012-
auto isNVPTX = (*TC)->getTriple().isNVPTX();
40134127

40144128
if (isNVPTX && DeviceCodeSplit) {
40154129
// TODO Temporary limitation, need to support code splitting for PTX
@@ -4021,10 +4135,6 @@ class OffloadingActionBuilder final {
40214135
D.Diag(diag::err_drv_unsupported_opt_for_target)
40224136
<< OptName << (*TC)->getTriple().str();
40234137
}
4024-
auto TT = SYCLTripleList[I];
4025-
bool isSpirvAOT = TT.getSubArch() == llvm::Triple::SPIRSubArch_fpga ||
4026-
TT.getSubArch() == llvm::Triple::SPIRSubArch_gen ||
4027-
TT.getSubArch() == llvm::Triple::SPIRSubArch_x86_64;
40284138
// reflects whether current target is ahead-of-time and can't support
40294139
// runtime setting of specialization constants
40304140
bool isAOT = isNVPTX || isSpirvAOT;

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6824,6 +6824,16 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
68246824
// users want. The /Za flag to cl.exe turns this off, but it's not
68256825
// implemented in clang.
68266826
CmdArgs.push_back("--dependent-lib=oldnames");
6827+
6828+
// Add SYCL dependent library
6829+
if (Args.hasArg(options::OPT_fsycl) &&
6830+
!Args.hasArg(options::OPT_nolibsycl)) {
6831+
if (RTOptionID == options::OPT__SLASH_MDd ||
6832+
RTOptionID == options::OPT__SLASH_MTd)
6833+
CmdArgs.push_back("--dependent-lib=sycld");
6834+
else
6835+
CmdArgs.push_back("--dependent-lib=sycl");
6836+
}
68276837
}
68286838

68296839
if (Arg *ShowIncludes =

clang/lib/Driver/ToolChains/MSVC.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -373,8 +373,8 @@ void visualstudio::Linker::ConstructJob(Compilation &C, const JobAction &JA,
373373
!C.getDriver().IsCLMode())
374374
CmdArgs.push_back("-defaultlib:libcmt");
375375

376-
if (!Args.hasArg(options::OPT_nostdlib) && Args.hasArg(options::OPT_fsycl) &&
377-
!Args.hasArg(options::OPT_nolibsycl)) {
376+
if (!C.getDriver().IsCLMode() && !Args.hasArg(options::OPT_nostdlib) &&
377+
Args.hasArg(options::OPT_fsycl) && !Args.hasArg(options::OPT_nolibsycl)) {
378378
if (Args.hasArg(options::OPT__SLASH_MDd) ||
379379
Args.hasArg(options::OPT__SLASH_MTd))
380380
CmdArgs.push_back("-defaultlib:sycld.lib");

clang/lib/Driver/ToolChains/SYCL.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,8 @@ void SYCL::Linker::ConstructJob(Compilation &C, const JobAction &JA,
207207

208208
static const char *makeExeName(Compilation &C, StringRef Name) {
209209
llvm::SmallString<8> ExeName(Name);
210-
if (C.getDriver().IsCLMode())
210+
const ToolChain *HostTC = C.getSingleOffloadToolChain<Action::OFK_Host>();
211+
if (HostTC->getTriple().isWindowsMSVCEnvironment())
211212
ExeName.append(".exe");
212213
return C.getArgs().MakeArgString(ExeName);
213214
}

clang/lib/Frontend/CompilerInvocation.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -823,14 +823,10 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
823823
Args.getLastArg(OPT_emit_llvm_uselists, OPT_no_emit_llvm_uselists))
824824
Opts.EmitLLVMUseLists = A->getOption().getID() == OPT_emit_llvm_uselists;
825825

826-
// ESIMD GPU Back-end requires optimized IR
827-
bool IsSyclESIMD = Args.hasFlag(options::OPT_fsycl_esimd,
828-
options::OPT_fno_sycl_esimd, false);
829-
830826
Opts.DisableLLVMPasses =
831827
Args.hasArg(OPT_disable_llvm_passes) ||
832828
(Args.hasArg(OPT_fsycl_is_device) && Triple.isSPIR() &&
833-
Args.hasArg(OPT_fno_sycl_early_optimizations) && !IsSyclESIMD);
829+
Args.hasArg(OPT_fno_sycl_early_optimizations));
834830
Opts.DisableLifetimeMarkers = Args.hasArg(OPT_disable_lifetimemarkers);
835831

836832
const llvm::Triple::ArchType DebugEntryValueArchs[] = {
@@ -2614,6 +2610,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
26142610
Opts.SYCLValueFitInMaxInt =
26152611
Args.hasFlag(options::OPT_fsycl_id_queries_fit_in_int,
26162612
options::OPT_fno_sycl_id_queries_fit_in_int, false);
2613+
Opts.SYCLIntHeader =
2614+
std::string(Args.getLastArgValue(OPT_fsycl_int_header));
26172615
}
26182616

26192617
Opts.IncludeDefaultHeader = Args.hasArg(OPT_finclude_default_header);
@@ -2674,8 +2672,6 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
26742672
Diags.Report(diag::warn_ignored_hip_only_option)
26752673
<< Args.getLastArg(OPT_gpu_max_threads_per_block_EQ)->getAsString(Args);
26762674

2677-
Opts.SYCLIntHeader = std::string(Args.getLastArgValue(OPT_fsycl_int_header));
2678-
26792675
if (Opts.ObjC) {
26802676
if (Arg *arg = Args.getLastArg(OPT_fobjc_runtime_EQ)) {
26812677
StringRef value = arg->getValue();

0 commit comments

Comments
 (0)