@@ -201,6 +201,19 @@ __sycl_device_global_registration __sycl_device_global_registrar;
201
201
} // namespace sycl::detail
202
202
```
203
203
204
+ Examples below are written for the following code snippet:
205
+
206
+ ```
207
+ #include <sycl/sycl.hpp>
208
+
209
+ static sycl::device_global<int> Foo;
210
+ namespace inner {
211
+ sycl::device_global<double[2]> Bar;
212
+ } // namespace inner
213
+
214
+ // ...
215
+ ```
216
+
204
217
The integration footer generated by the compiler contains the definition of the
205
218
constructor, which calls a function in the DPC++ runtime, which registers
206
219
needed mappings:
@@ -213,7 +226,7 @@ __sycl_device_global_registration::__sycl_device_global_registration() noexcept
213
226
__register_uniquely_identifiable_object(
214
227
&::Foo,
215
228
/* same string returned from __builtin_sycl_unique_stable_id(::Foo) */,
216
- "specialization_id ");
229
+ "device_global ");
217
230
__register_uniquely_identifiable_object(
218
231
&::inner::Bar,
219
232
/* same string returned from __builtin_sycl_unique_stable_id(::inner::Bar) */,
@@ -224,6 +237,67 @@ __sycl_device_global_registration::__sycl_device_global_registration() noexcept
224
237
} // namespace sycl::detail
225
238
```
226
239
240
+ ### Handling shadowed variables
241
+
242
+ The example above shows a simple case where the user's device global variables
243
+ can all be uniquely referenced via fully qualified lookup (e.g.
244
+ ` ::inner::Bar ` ). However, it is possible for users to construct applications
245
+ where this is not the case, for example:
246
+
247
+ ```
248
+ sycl::device_global<int> FuBar;
249
+ namespace {
250
+ sycl::device_global<int> FuBar;
251
+ }
252
+ ```
253
+
254
+ In this example, the ` FuBar ` variable in the global namespace shadows a
255
+ variable with the same name in the unnamed namespace. The integration footer
256
+ can reference the variable in the global namespace as ` ::FuBar ` , but there is
257
+ no way to reference the variable in the unnamed namespace using fully qualified
258
+ lookup.
259
+
260
+ Such programs are still legal, though. The integration footer can support
261
+ cases like this by defining a shim function that returns a reference to the
262
+ shadowed device global:
263
+
264
+ ```
265
+ namespace {
266
+ namespace __sycl_detail {
267
+
268
+ static constexpr decltype(FuBar) &__shim_1() {
269
+ return FuBar; // References 'FuBar' in the unnamed namespace
270
+ }
271
+
272
+ } // namespace __sycl_detail
273
+ } // namespace (unnamed)
274
+
275
+ namespace sycl::detail {
276
+
277
+ __sycl_device_global_registration::__sycl_device_global_registration() noexcept {
278
+ __register_uniquely_identifiable_object(
279
+ &::FuBar,
280
+ /* same string returned from __builtin_sycl_unique_stable_id(::FuBar) */,
281
+ "device_global");
282
+ __register_uniquely_identifiable_object(
283
+ &::__sycl_detail::__shim_1(),
284
+ /* same string returned from __builtin_sycl_unique_stable_id(::(unnamed)::FuBar) */,
285
+ "device_global");
286
+ }
287
+
288
+ } // namespace sycl::detail
289
+ ```
290
+
291
+ The ` __shim_1() ` function is defined in the same namespace as the second
292
+ ` FuBar ` device global, so it can reference the variable through unqualified
293
+ name lookup. Furthermore, the name of the shim function is globally unique, so
294
+ it is guaranteed not to be shadowed by any other name in the translation unit.
295
+ This problem with variable shadowing is also a problem for the integration
296
+ footer we use for specialization constants. See the [ specialization constant
297
+ design document] [ 5 ] for more details on this topic.
298
+
299
+ [ 5 ] : < SpecializationConstants.md >
300
+
227
301
## Custom host compiler approach
228
302
229
303
With this approach, we simply schedule a one more pass in the optimization
0 commit comments