Skip to content

Commit b87ad39

Browse files
author
iclsrc
committed
Merge from 'sycl' to 'sycl-web'
2 parents b05ef6d + 31c23dd commit b87ad39

File tree

14 files changed

+1170
-152
lines changed

14 files changed

+1170
-152
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1263,17 +1263,6 @@ Compilation *Driver::BuildCompilation(ArrayRef<const char *> ArgList) {
12631263
T.setObjectFormat(llvm::Triple::COFF);
12641264
TargetTriple = T.str();
12651265
}
1266-
if (Args.hasArg(options::OPT_fsycl_device_only)) {
1267-
// -fsycl-device-only implies spir arch and SYCL Device
1268-
llvm::Triple T(TargetTriple);
1269-
// FIXME: defaults to spir64, should probably have a way to set spir
1270-
// possibly new -sycl-target option
1271-
T.setArch(llvm::Triple::spir64);
1272-
T.setVendor(llvm::Triple::UnknownVendor);
1273-
T.setOS(llvm::Triple(llvm::sys::getProcessTriple()).getOS());
1274-
T.setEnvironment(llvm::Triple::SYCLDevice);
1275-
TargetTriple = T.str();
1276-
}
12771266
if (const Arg *A = Args.getLastArg(options::OPT_target))
12781267
TargetTriple = A->getValue();
12791268
if (const Arg *A = Args.getLastArg(options::OPT_ccc_install_dir))
@@ -2384,7 +2373,9 @@ void Driver::BuildInputs(const ToolChain &TC, DerivedArgList &Args,
23842373
// actually use it, so we warn about unused -x arguments.
23852374
types::ID InputType = types::TY_Nothing;
23862375
Arg *InputTypeArg = nullptr;
2387-
bool IsSYCL = Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false);
2376+
bool IsSYCL =
2377+
Args.hasFlag(options::OPT_fsycl, options::OPT_fno_sycl, false) ||
2378+
Args.hasArg(options::OPT_fsycl_device_only);
23882379

23892380
// The last /TC or /TP option sets the input type to C or C++ globally.
23902381
if (Arg *TCTP = Args.getLastArgNoClaim(options::OPT__SLASH_TC,

clang/lib/Driver/ToolChains/Clang.cpp

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -4026,14 +4026,24 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40264026
const ArgList &Args, const char *LinkingOutput) const {
40274027
const auto &TC = getToolChain();
40284028
const llvm::Triple &RawTriple = TC.getTriple();
4029-
const llvm::Triple &Triple = TC.getEffectiveTriple();
4030-
const std::string &TripleStr = Triple.getTriple();
4029+
llvm::Triple Triple = TC.getEffectiveTriple();
40314030

40324031
bool KernelOrKext =
40334032
Args.hasArg(options::OPT_mkernel, options::OPT_fapple_kext);
40344033
const Driver &D = TC.getDriver();
40354034
ArgStringList CmdArgs;
40364035

4036+
// -fsycl-device-only implies a SPIRV arch triple. Do not set if current
4037+
// effective triple is SYCLDevice
4038+
if (Args.hasArg(options::OPT_fsycl_device_only) &&
4039+
Triple.getEnvironment() != llvm::Triple::SYCLDevice) {
4040+
const char *SYCLTargetArch = "spir64";
4041+
if (C.getDefaultToolChain().getTriple().getArch() == llvm::Triple::x86)
4042+
SYCLTargetArch = "spir";
4043+
Triple = C.getDriver().MakeSYCLDeviceTriple(SYCLTargetArch);
4044+
}
4045+
const std::string &TripleStr = Triple.getTriple();
4046+
40374047
// Check number of inputs for sanity. We need at least one input.
40384048
assert(Inputs.size() >= 1 && "Must have at least one input.");
40394049
// CUDA/HIP compilation may have multiple inputs (source file + results of
@@ -4048,7 +4058,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40484058
bool IsHIP = JA.isOffloading(Action::OFK_HIP);
40494059
bool IsOpenMPDevice = JA.isDeviceOffloading(Action::OFK_OpenMP);
40504060
bool IsSYCLOffloadDevice = JA.isDeviceOffloading(Action::OFK_SYCL);
4051-
bool IsSYCL = JA.isOffloading(Action::OFK_SYCL);
4061+
bool IsSYCL = JA.isOffloading(Action::OFK_SYCL) ||
4062+
Args.hasArg(options::OPT_fsycl_device_only);
40524063
bool IsHeaderModulePrecompile = isa<HeaderModulePrecompileJobAction>(JA);
40534064
assert((IsCuda || IsHIP || (IsOpenMPDevice && Inputs.size() == 2) || IsSYCL ||
40544065
IsHeaderModulePrecompile || Inputs.size() == 1) &&
@@ -4096,14 +4107,17 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
40964107
(IsSYCL || IsCuda || IsHIP) ? TC.getAuxTriple() : nullptr;
40974108
bool IsWindowsMSVC = RawTriple.isWindowsMSVCEnvironment();
40984109
bool IsIAMCU = RawTriple.isOSIAMCU();
4099-
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice);
4110+
bool IsSYCLDevice = (RawTriple.getEnvironment() == llvm::Triple::SYCLDevice ||
4111+
Triple.getEnvironment() == llvm::Triple::SYCLDevice);
41004112
// Using just the sycldevice environment is not enough to determine usage
41014113
// of the device triple when considering fat static archives. The
41024114
// compilation path requires the host object to be fed into the partial link
41034115
// step, and being part of the SYCL tool chain causes the incorrect target.
41044116
// FIXME - Is it possible to retain host environment when on a target
41054117
// device toolchain.
4106-
bool UseSYCLTriple = IsSYCLDevice && (!IsSYCL || IsSYCLOffloadDevice);
4118+
bool UseSYCLTriple =
4119+
IsSYCLDevice && (!IsSYCL || IsSYCLOffloadDevice ||
4120+
Args.hasArg(options::OPT_fsycl_device_only));
41074121

41084122
// Adjust IsWindowsXYZ for CUDA/HIP/SYCL compilations. Even when compiling in
41094123
// device mode (i.e., getToolchain().getTriple() is NVPTX/AMDGCN, not
@@ -4192,7 +4206,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
41924206
options::OPT_fno_sycl_early_optimizations,
41934207
Triple.getSubArch() != llvm::Triple::SPIRSubArch_fpga))
41944208
CmdArgs.push_back("-fno-sycl-early-optimizations");
4195-
else if (RawTriple.isSPIR()) {
4209+
else if (IsSYCLDevice) {
41964210
// Set `sycl-opt` option to configure LLVM passes for SPIR target
41974211
CmdArgs.push_back("-mllvm");
41984212
CmdArgs.push_back("-sycl-opt");
@@ -4205,7 +4219,8 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
42054219

42064220
// Pass the triple of host when doing SYCL
42074221
llvm::Triple AuxT = C.getDefaultToolChain().getTriple();
4208-
if (Args.hasFlag(options::OPT_fsycl_device_only, OptSpecifier(), false))
4222+
if (Args.hasArg(options::OPT_fsycl_device_only) &&
4223+
RawTriple.getEnvironment() == llvm::Triple::SYCLDevice)
42094224
AuxT = llvm::Triple(llvm::sys::getProcessTriple());
42104225
std::string NormalizedTriple = AuxT.normalize();
42114226
CmdArgs.push_back("-aux-triple");
@@ -6879,6 +6894,7 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType,
68796894
unsigned RTOptionID = options::OPT__SLASH_MT;
68806895
bool isNVPTX = getToolChain().getTriple().isNVPTX();
68816896
bool isSYCLDevice =
6897+
Args.hasArg(options::OPT_fsycl_device_only) ||
68826898
getToolChain().getTriple().getEnvironment() == llvm::Triple::SYCLDevice;
68836899
bool isSYCL = Args.hasArg(options::OPT_fsycl) || isSYCLDevice;
68846900
// For SYCL Windows, /MD is the default.
@@ -7893,7 +7909,8 @@ void SPIRVTranslator::ConstructJob(Compilation &C, const JobAction &JA,
78937909

78947910
TranslatorArgs.push_back("-o");
78957911
TranslatorArgs.push_back(Output.getFilename());
7896-
if (getToolChain().getTriple().isSYCLDeviceEnvironment()) {
7912+
if (getToolChain().getTriple().isSYCLDeviceEnvironment() ||
7913+
TCArgs.hasArg(options::OPT_fsycl_device_only)) {
78977914
TranslatorArgs.push_back("-spirv-max-version=1.1");
78987915
TranslatorArgs.push_back("-spirv-debug-info-version=legacy");
78997916
// Prevent crash in the translator if input IR contains DIExpression

clang/test/Driver/sycl.c

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
// DEFAULT: "-triple" "spir64-unknown-{{.*}}-sycldevice{{.*}}" "-fsycl-is-device"{{.*}} "-emit-llvm-bc"
4141
// DEFAULT: "-internal-isystem" "{{.*}}bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}sycl"
4242
// DEFAULT: "-internal-isystem" "{{.*lib.*clang.*include}}"
43+
// DEFAULT: "-std=c++17"
4344
// DEFAULT-NOT: "{{.*}}llvm-spirv"{{.*}} "-spirv-max-version=1.1"{{.*}} "-spirv-ext=+all,-SPV_INTEL_usm_storage_classes"
4445
// DEFAULT-NOT: "-std=c++11"
4546
// DEFAULT-NOT: "-std=c++14"
@@ -49,15 +50,28 @@
4950
// COMBINED: "-triple" "spir64-unknown-{{.*}}-sycldevice"{{.*}} "-fsycl-is-device"{{.*}} "-emit-llvm-bc"
5051
// TEXTUAL: "-triple" "spir64-unknown-{{.*}}-sycldevice{{.*}}" "-fsycl-is-device"{{.*}} "-emit-llvm"
5152

53+
/// -fsycl-device-only triple checks
54+
// RUN: %clang -fsycl-device-only -target x86_64-unknown-linux-gnu -### %s 2>&1 \
55+
// RUN: | FileCheck --check-prefix=DEVICE-64 %s
56+
// RUN: %clang_cl -fsycl-device-only --target=x86_64-unknown-linux-gnu -### %s 2>&1 \
57+
// RUN: | FileCheck --check-prefix=DEVICE-64 %s
58+
// DEVICE-64: clang{{.*}} "-triple" "spir64-unknown-unknown-sycldevice" {{.*}} "-aux-triple" "x86_64-unknown-linux-gnu"
59+
60+
// RUN: %clang -fsycl-device-only -target i386-unknown-linux-gnu -### %s 2>&1 \
61+
// RUN: | FileCheck --check-prefix=DEVICE-32 %s
62+
// RUN: %clang_cl -fsycl-device-only --target=i386-unknown-linux-gnu -### %s 2>&1 \
63+
// RUN: | FileCheck --check-prefix=DEVICE-32 %s
64+
// DEVICE-32: clang{{.*}} "-triple" "spir-unknown-unknown-sycldevice" {{.*}} "-aux-triple" "i386-unknown-linux-gnu"
65+
5266
/// Verify that the sycl header directory is before /usr/include
5367
// RUN: %clangxx -### -fsycl-device-only %s 2>&1 | FileCheck %s --check-prefix=HEADER_ORDER
5468
// RUN: %clangxx -### -fsycl %s 2>&1 | FileCheck %s --check-prefix=HEADER_ORDER
5569
// HEADER_ORDER-NOT: clang{{.*}} "/usr/include"{{.*}} "-internal-isystem" "{{.*}}bin{{[/\\]+}}..{{[/\\]+}}include{{[/\\]+}}
5670

5771
/// Verify -fsycl-device-only phases
5872
// RUN: %clang -### -ccc-print-phases -fsycl-device-only %s 2>&1 | FileCheck %s --check-prefix=DEFAULT-PHASES
59-
// DEFAULT-PHASES: 0: input, "{{.*}}", c
60-
// DEFAULT-PHASES: 1: preprocessor, {0}, cpp-output
73+
// DEFAULT-PHASES: 0: input, "{{.*}}", c++
74+
// DEFAULT-PHASES: 1: preprocessor, {0}, c++-cpp-output
6175
// DEFAULT-PHASES: 2: compiler, {1}, ir
6276
// DEFAULT-PHASES: 3: backend, {2}, ir
6377
// DEFAULT-PHASES-NOT: linker

sycl/gdb/libsycl.so-gdb.py

Lines changed: 97 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,16 @@
22
# See https://llvm.org/LICENSE.txt for license information.
33
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
44

5+
import re
56
import gdb
67
import gdb.xmethod
78
import gdb.printing
8-
import itertools
9-
import re
109

1110
### XMethod implementations ###
1211

13-
"""
14-
Generalized base class for buffer index calculation
15-
"""
1612
class Accessor:
13+
"""Generalized base class for buffer index calculation"""
14+
1715
def memory_range(self, dim):
1816
pass
1917

@@ -43,10 +41,9 @@ def value(self, arg):
4341
return self.data().cast(self.result_type.pointer())[self.index(arg)]
4442

4543

46-
"""
47-
For Host device memory layout
48-
"""
4944
class HostAccessor(Accessor):
45+
"""For Host device memory layout"""
46+
5047
def payload(self):
5148
return self.obj['impl']['_M_ptr'].dereference()
5249

@@ -59,10 +56,9 @@ def offset(self, dim):
5956
def data(self):
6057
return self.payload()['MData']
6158

62-
"""
63-
For CPU/GPU memory layout
64-
"""
6559
class DeviceAccessor(Accessor):
60+
"""For CPU/GPU memory layout"""
61+
6662
def memory_range(self, dim):
6763
return self.obj['impl']['MemRange']['common_array'][dim]
6864

@@ -73,10 +69,9 @@ def data(self):
7369
return self.obj['MData']
7470

7571

76-
"""
77-
Generic implementation for N-dimensional ID
78-
"""
7972
class AccessorOpIndex(gdb.xmethod.XMethodWorker):
73+
"""Generic implementation for N-dimensional ID"""
74+
8075
def __init__(self, class_type, result_type, depth):
8176
self.class_type = class_type
8277
self.result_type = result_type
@@ -106,25 +101,25 @@ def __call__(self, obj, arg):
106101
return None
107102

108103

109-
"""
110-
Introduces an extra overload for 1D case that takes plain size_t
111-
"""
112104
class AccessorOpIndex1D(AccessorOpIndex):
105+
"""Introduces an extra overload for 1D case that takes plain size_t"""
106+
113107
def get_arg_types(self):
114-
assert(self.depth == 1)
108+
assert self.depth == 1
115109
return gdb.lookup_type('size_t')
116110

117111

118-
class AccessorOpIndexMatcher(gdb.xmethod.XMethodMatcher):
112+
class AccessorMatcher(gdb.xmethod.XMethodMatcher):
113+
"""Entry point for cl::sycl::accessor"""
119114
def __init__(self):
120-
gdb.xmethod.XMethodMatcher.__init__(self, 'AccessorOpIndexMatcher')
115+
gdb.xmethod.XMethodMatcher.__init__(self, 'AccessorMatcher')
121116

122117
def match(self, class_type, method_name):
123118
if method_name != 'operator[]':
124119
return None
125120

126121
result = re.match('^cl::sycl::accessor<.+>$', class_type.tag)
127-
if (result == None):
122+
if result is None:
128123
return None
129124

130125
depth = int(class_type.template_argument(1))
@@ -137,15 +132,86 @@ def match(self, class_type, method_name):
137132
methods.append(AccessorOpIndex1D(class_type, result_type, depth))
138133
return methods
139134

135+
class PrivateMemoryOpCall(gdb.xmethod.XMethodWorker):
136+
"""Provides operator() overload for h_item argument"""
137+
138+
class ItemBase:
139+
"""Wrapper for cl::sycl::detail::ItemBase which reimplements index calculation"""
140+
141+
def __init__(self, obj, ):
142+
result = re.match('^cl::sycl::detail::ItemBase<(.+), (.+)>$', str(obj.type))
143+
self.dim = int(result[1])
144+
self.with_offset = (result[2] == 'true')
145+
self.obj = obj
146+
147+
def get_linear_id(self):
148+
index = self.obj['MIndex']['common_array']
149+
extent = self.obj['MExtent']['common_array']
150+
151+
if self.with_offset:
152+
offset = self.obj['MOffset']['common_array']
153+
if self.dim == 1:
154+
return index[0] - offset[0]
155+
elif self.dim == 2:
156+
return (index[0] - offset[0]) * extent[1] + (index[1] - offset[1])
157+
else:
158+
return ((index[0] - offset[0]) * extent[1] * extent[2]) + \
159+
((index[1] - offset[1]) * extent[2]) + (index[2] - offset[2])
160+
else:
161+
if self.dim == 1:
162+
return index[0]
163+
elif self.dim == 2:
164+
return index[0] * extent[1] + index[1]
165+
else:
166+
return (index[0] * extent[1] * extent[2]) + (index[1] * extent[2]) + index[2]
167+
168+
def __init__(self, result_type, dim):
169+
self.result_type = result_type
170+
self.dim = dim
171+
172+
def get_arg_types(self):
173+
return gdb.lookup_type("cl::sycl::h_item<%s>" % self.dim)
174+
175+
def get_result_type(self, *args):
176+
return self.result_type
177+
178+
def __call__(self, obj, *args):
179+
if obj['Val'].type.tag == self.result_type:
180+
# On device private_memory is a simple wrapper over actual value
181+
return obj['Val']
182+
else:
183+
# On host it wraps a unique_ptr to an array of items
184+
item_base = args[0]['localItem']['MImpl']
185+
item_base = self.ItemBase(item_base)
186+
index = item_base.get_linear_id()
187+
return obj['Val']['_M_t']['_M_t']['_M_head_impl'][index]
140188

141-
gdb.xmethod.register_xmethod_matcher(None, AccessorOpIndexMatcher(), replace=True)
189+
class PrivateMemoryMatcher(gdb.xmethod.XMethodMatcher):
190+
"""Entry point for cl::sycl::private_memory"""
191+
192+
def __init__(self):
193+
gdb.xmethod.XMethodMatcher.__init__(self, 'PrivateMemoryMatcher')
194+
195+
def match(self, class_type, method_name):
196+
if method_name != 'operator()':
197+
return None
198+
199+
result = re.match('^cl::sycl::private_memory<(cl::sycl::id<.+>), (.+)>$', class_type.tag)
200+
if result is None:
201+
return None
202+
203+
return PrivateMemoryOpCall(result[1], result[2])
204+
205+
206+
207+
gdb.xmethod.register_xmethod_matcher(None, AccessorMatcher(), replace=True)
208+
gdb.xmethod.register_xmethod_matcher(None, PrivateMemoryMatcher(), replace=True)
142209

143210
### Pretty-printer implementations ###
144211

145-
"""
146-
Print an object deriving from cl::sycl::detail::array
147-
"""
148212
class SyclArrayPrinter:
213+
"""Print an object deriving from cl::sycl::detail::array"""
214+
149215
class ElementIterator:
150216
def __init__(self, data, size):
151217
self.data = data
@@ -168,7 +234,7 @@ def __next__(self):
168234

169235
def __init__(self, value):
170236
if value.type.code == gdb.TYPE_CODE_REF:
171-
if hasattr(gdb.Value,"referenced_value"):
237+
if hasattr(gdb.Value, "referenced_value"):
172238
value = value.referenced_value()
173239

174240
self.value = value
@@ -182,7 +248,7 @@ def children(self):
182248
# There is no way to return an error from this method. Return an
183249
# empty iterable to make GDB happy and rely on to_string method
184250
# to take care of formatting.
185-
return [ ]
251+
return []
186252

187253
def to_string(self):
188254
try:
@@ -197,10 +263,9 @@ def to_string(self):
197263
def display_hint(self):
198264
return 'array'
199265

200-
"""
201-
Print a cl::sycl::buffer
202-
"""
203266
class SyclBufferPrinter:
267+
"""Print a cl::sycl::buffer"""
268+
204269
def __init__(self, value):
205270
self.value = value
206271
self.type = value.type.unqualified().strip_typedefs()
@@ -217,8 +282,7 @@ def to_string(self):
217282
self.value['impl'].address))
218283

219284
sycl_printer = gdb.printing.RegexpCollectionPrettyPrinter("SYCL")
220-
sycl_printer.add_printer("cl::sycl::id", '^cl::sycl::id<.*$', SyclArrayPrinter)
221-
sycl_printer.add_printer("cl::sycl::range", '^cl::sycl::range<.*$', SyclArrayPrinter)
285+
sycl_printer.add_printer("cl::sycl::id", '^cl::sycl::id<.*$', SyclArrayPrinter)
286+
sycl_printer.add_printer("cl::sycl::range", '^cl::sycl::range<.*$', SyclArrayPrinter)
222287
sycl_printer.add_printer("cl::sycl::buffer", '^cl::sycl::buffer<.*$', SyclBufferPrinter)
223288
gdb.printing.register_pretty_printer(None, sycl_printer, True)
224-

0 commit comments

Comments
 (0)