<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<!--[if !mso]><style>v\:* {behavior:url(#default#VML);}
o\:* {behavior:url(#default#VML);}
w\:* {behavior:url(#default#VML);}
.shape {behavior:url(#default#VML);}
</style><![endif]--><style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
p.xmsonormal, li.xmsonormal, div.xmsonormal
        {mso-style-name:x_msonormal;
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.EmailStyle21
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:windowtext;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:2.0cm 42.5pt 2.0cm 3.0cm;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="RU" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Hi Anastasia,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Sorry for the delay.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > The main difference with OpenCL mode is that SYCL<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > mode (similar to other single-source GPU programming modes like<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > OpenMP/CUDA/HIP)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > keeps "default" address space for the declaration without address space<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > attribute annotations.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> Just FYI in C++ mode, Clang implements default/generic address space as<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> specified in embedded C (ISO/IEC TR 18037) s5.1 - 5.3.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> "When not specified otherwise, objects are allocated by default in a generic<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> address space, which corresponds to the single address space of ISO/IEC<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> 9899:1999."<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> "Objects are allocated in one or more address spaces. A unique generic address<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> space always exists. Every address space other than the generic one has a unique<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> name in the form of an identifier. Address spaces other than the generic one are<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> called named address spaces. An object is always completely allocated into at<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> least one address space. Unless otherwise specified, objects are allocated in<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> the generic address space."<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> It feels to me this is the model you intend to follow?
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">After reading the document I don't see major conflicts with our SYCL<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">implementation.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> If you use OpenCL address<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> space attributes outside of OpenCL mode there is limited logic that you will<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> inherit. For example deduction of address spaces wouldn't work but conversions<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> or generation to IR should work fine. It generally sounds like a viable approach<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> but OpenCL however used Default (no address space) as private AS for a very long<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> time and there are still a number of places where this assumption is inherent in<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> the implementation. This is not entirely strange as Default is use by many<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> languages for automatic storage anyway. My worry is there could be difficulties<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> in reusing the OpenCL address space model due to this.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> Btw can you elaborate on your implementation of constant addr space?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">As SPIR-V doesn't allow casts between constant and generic pointers, SYCL<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">implementation doesn't use OpenCL constant address space attribute. "const"<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">qualified "global" address space attribute is used instead.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > This keeps the code shared between the host and device<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > semantically-correct for both compilers: regular C++ host compiler and SYCL<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > compiler.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> Sorry perhaps I am not following this thought but can you explain how<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> address spaces make code semantically incorrect?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">It's not "address spaces" per se, but how OpenCL mode implements them.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Victor did a good job covering this question in this comment:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">https://reviews.llvm.org/D80932#2073542<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Example form this comment of valid C++ function, which is not valid in OpenCL<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">mode:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">```c++<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">template<typename T1, typename T2><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">struct is_same {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">    static constexpr int value = 0;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">};<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">template<typename T><o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">struct is_same<T, T> {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">    static constexpr int value = 1;<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">};<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">void foo(int p) {<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">    static_assert(is_same<decltype(p), int>::value, "int is not an int?"); // Fails: p is '__private int' != 'int'<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">    static_assert(is_same<decltype(&p), int*>::value, "int* is not an int*?");  // Fails: p is '__private int*' != '__generic int*'<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">}<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">```<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > To make all pointers without an explicit address space qualifier to be<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > pointers<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > in generic address space, we updated SPIR target address space map, which<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > currently maps default pointers to "private" address space.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> The address space map in Clang is not specific to pointer types. How do you<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> make it work for pointers only?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">I don't think we did anything specific to apply this change to pointers only.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Pointers provided here as an example to demonstrate the impact of the change in<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">LLVM IR representation for SPIR target.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > We made this change<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > specific to SYCL by adding SYCL environment component to the Triple to avoid<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > impact on other modes targeting SPIR target (e.g. OpenCL). We would be glad to<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > see get a feedback from the community if changing this mapping is applicable<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > for all the modes and additional specialization can be avoided (e.g.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > [AMDGPU](https://github.com/llvm/llvm-project/blob/master/clang/lib/Basic/Targets/AMDGPU.cpp#L329)<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > maps default to "generic" address space with a couple of exceptions).<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> Ok, does it mean that you map Default address space to OpenCL generic?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> Please note that Default address space is used outside of OpenCL for all<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> other languages so remapping this unconditionally will have a wider impact.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Current implementation applies different mapping only when "sycldevice"<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">environment is set in target triple.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">https://github.com/bader/llvm/pull/18/files#diff-d62fb2e1d8c597ce59fd10e018f6fb77R61<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">What languages do you think might be impacted if we enable this change<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">unconditionally? Are there modes other than OpenCL and SYCL targeting SPIR?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > There are a few cases when CodeGen assigns non-default address space:<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > 1. For declaration explicitly annotated with address space attribute<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> This is generally how CodeGen works mapping language address spaces to target<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> address spaces. Is there something different you do here for SYCL?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">No.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > 2. Variables with static storage duration and string literals are allocated in<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> >  global address space unless specific address space it specified.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > 3. Variables with automatic storage durations are allocated in private address<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> >   space. It's current compiler behavior and it doesn't require additional<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> >   changes.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> We already have this logic for OpenCL in Sema. I am not an expert in CodeGen but<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> I believe its primary task is to map language constructs onto the target specific IR<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> i.e. map from AST into IR. However, you are making it dial with language semantic<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> instead i.e. add missing AST logic such as address space attribute. I believe there<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> are good reasons to have layering architecture that separates various concerns.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> What drives your decision for moving this logic into CodeGen?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">I don't think (2) deal with language semantics. I assume we both talking about<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">the same case when variable declaration is not explicitly annotated with address<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">space attribute. According to language semantics such objects are allocated in<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">generic address space, but the problem is that most OpenCL implementations have<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">problems with consuming SPIR-V files with global variables in generic address<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">space. As an alternative to CodeGen changes we can consider handling this issue<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">in SPIR-V translator tool.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > For (2) and (3) cases, once "default" pointer to such variable is obtained, it<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > is immediately addrspacecast'ed to generic, because a user does not (and<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> > should not) specify address space for pointers in source code.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> <o:p>
</o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> Can you explain why you need this cast?
<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">This change is need to keep the types in LLVM IR consistent. Regular C++ user<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">code usually doesn't have address space annotations, so if memory references and<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">pointers are "generic". When allocation is done in named address space, we must<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">add address space cast to keep LLVM pointer types aligned.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> Can user not specify address spaces using<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> pointer classes that map into address space attributed types i.e. ending up with<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">> pointer with address spaces originating from the user code?<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Yes.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Feel free to join today's sync meeting at 9AM PT to have an online discussion.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Thanks,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US">Alexey<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b><span lang="EN-US">From:</span></b><span lang="EN-US"> Anastasia Stulova <Anastasia.Stulova@arm.com>
<br>
<b>Sent:</b> Thursday, July 9, 2020 2:51 PM<br>
<b>To:</b> Bader, Alexey <alexey.bader@intel.com>; cfe-dev (cfe-dev@lists.llvm.org) <cfe-dev@lists.llvm.org>; rjmccall@apple.com<br>
<b>Cc:</b> nd <nd@arm.com><br>
<b>Subject:</b> Re: [RFC] Re-use OpenCL address space attributes for SYCL<o:p></o:p></span></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Hi Alexey,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Thanks for the clarification.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> SYCL compiler re-use generic support for these attributes as is and modifies<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> Sema and CodeGen libraries.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Can you elaborate on your modifications in Sema and CodeGen, please?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> The main difference with OpenCL mode is that SYCL<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> mode (similar to other single-source GPU programming modes like<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> OpenMP/CUDA/HIP)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> keeps "default" address space for the declaration without address space<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> attribute annotations.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Just FYI in C++ mode, Clang implements default/generic address space as<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">specified in embedded C (ISO/IEC TR 18037) s5.1 - 5.3.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">"When not specified otherwise, objects are allocated by default in a generic<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">address space, which corresponds to the single address space of ISO/IEC<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">9899:1999."<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">"Objects are allocated in one or more address spaces. A unique generic address<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">space always exists. Every address space other than the generic one has a unique<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">name in the form of an identifier. Address spaces other than the generic one are<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">called named address spaces. An object is always completely allocated into at<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">least one address space. Unless otherwise specified, objects are allocated in<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">the generic address space."<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">It feels to me this is the model you intend to follow? If you use OpenCL address<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">space attributes outside of OpenCL mode there is limited logic that you will<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">inherit. For example deduction of address spaces wouldn't work but conversions<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">or generation to IR should work fine. It generally sounds like a viable approach<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">but OpenCL however used Default (no address space) as private AS for a very long<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">time and there are still a number of places where this assumption is inherent in<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">the implementation. This is not entirely strange as Default is use by many<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">languages for automatic storage anyway. My worry is there could be difficulties<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">in reusing the OpenCL address space model due to this.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Btw can you elaborate on your implementation of constant addr space?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> This keeps the code shared between the host and device<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> semantically-correct for both compilers: regular C++ host compiler and SYCL<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> compiler.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Sorry perhaps I am not following this thought but can you explain how<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">address spaces make code semantically incorrect?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> To make all pointers without an explicit address space qualifier to be<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> pointers<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> in generic address space, we updated SPIR target address space map, which<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> currently maps default pointers to "private" address space.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">The address space map in Clang is not specific to pointer types. How do you<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">make it work for pointers only?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> We made this change<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> specific to SYCL by adding SYCL environment component to the Triple to avoid<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> impact on other modes targeting SPIR target (e.g. OpenCL). We would be glad to<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> see get a feedback from the community if changing this mapping is applicable<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> for all the modes and additional specialization can be avoided (e.g.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> [AMDGPU](<a href="https://github.com/llvm/llvm-project/blob/master/clang/lib/Basic/Targets/AMDGPU.cpp#L329">https://github.com/llvm/llvm-project/blob/master/clang/lib/Basic/Targets/AMDGPU.cpp#L329</a>)<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> maps default to "generic" address space with a couple of exceptions).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Ok, does it mean that you map Default address space to OpenCL generic?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Please note that Default address space is used outside of OpenCL for all<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">other languages so remapping this unconditionally will have a wider impact.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> There are a few cases when CodeGen assigns non-default address space:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> <o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> 1. For declaration explicitly annotated with address space attribute<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">This is generally how CodeGen works mapping language address spaces to target<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">address spaces. Is there something different you do here for SYCL?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> 2. Variables with static storage duration and string literals are allocated in<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">>  global address space unless specific address space it specified.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> 3. Variables with automatic storage durations are allocated in private address<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">>   space. It's current compiler behavior and it doesn't require additional<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">>   changes.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">We already have this logic for OpenCL in Sema. I am not an expert in CodeGen but<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">I believe its primary task is to map language constructs onto the target specific IR<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">i.e. map from AST into IR. However, you are making it dial with language semantic<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">instead i.e. add missing AST logic such as address space attribute. I believe there<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">are good reasons to have layering architecture that separates various concerns.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">What drives your decision for moving this logic into CodeGen?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">> For (2) and (3) cases, once "default" pointer to such variable is obtained, it<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> is immediately addrspacecast'ed to generic, because a user does not (and<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">> should not) specify address space for pointers in source code.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Can you explain why you need this cast? Can user not specify address spaces using<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">pointer classes that map into address space attributed types i.e. ending up with<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">pointer with address spaces originating from the user code?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Cheers,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">Anastasia<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div>
<p class="MsoNormal"><span style="font-size:12.0pt;color:black"><o:p> </o:p></span></p>
</div>
<div class="MsoNormal" align="center" style="text-align:center">
<hr size="2" width="98%" align="center">
</div>
<div id="divRplyFwdMsg">
<p class="MsoNormal"><b><span style="color:black">From:</span></b><span style="color:black"> Bader, Alexey <<a href="mailto:alexey.bader@intel.com">alexey.bader@intel.com</a>><br>
<b>Sent:</b> 26 June 2020 13:04<br>
<b>To:</b> cfe-dev (<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>) <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>>; Anastasia Stulova <<a href="mailto:Anastasia.Stulova@arm.com">Anastasia.Stulova@arm.com</a>>;
<a href="mailto:rjmccall@apple.com">rjmccall@apple.com</a> <<a href="mailto:rjmccall@apple.com">rjmccall@apple.com</a>><br>
<b>Subject:</b> [RFC] Re-use OpenCL address space attributes for SYCL</span> <o:p>
</o:p></p>
<div>
<p class="MsoNormal"> <o:p></o:p></p>
</div>
</div>
<div>
<div>
<p class="xmsonormal"><span lang="EN-US">Hi,</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">We would like to re-use OpenCL address space attributes for SYCL to target</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">SPIR-V format and enable efficient memory access on GPUs.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">```c++</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  __attribute__((opencl_global))</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  __attribute__((opencl_local))</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  __attribute__((opencl_private))</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">```</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">The first patch enabling conversion between pointers annotated with OpenCL</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">address space attribute and "default" pointers is being reviewed here</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"><a href="https://reviews.llvm.org/D80932">https://reviews.llvm.org/D80932</a>.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Before moving further with the implementation we would like to discuss two</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">questions raised in review comments (<a href="https://reviews.llvm.org/D80932#2085848">https://reviews.llvm.org/D80932#2085848</a>).</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><b><span lang="EN-US">## Using attributes to annotate memory allocations</span></b><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Introduction section of SYCL-1.2.1 specification describes multiple compilation</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">flows intended by the design:</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> SYCL is designed to allow a compilation flow where the source file is passed</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> through multiple different compilers, including a standard C++ host compiler</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> of the developer’s choice, and where the resulting application combines the</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> results of these compilation passes. This is distinct from a single-source</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> flow that might use language extensions that preclude the use of a standard</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> host compiler. The SYCL standard does not preclude the use of a single</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> compiler flow, but is designed to not require it.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> The advantages of this design are two-fold. First, it offers better</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> integration with existing tool chains. An application that already builds</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> using a chosen compiler can continue to do so when SYCL code is added. Using</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> the SYCL tools on a source file within a project will both compile for an</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> OpenCL device and let the same source file be compiled using the same host</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> compiler that the rest of the project is compiled with. Linking and library</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> relationships are unaffected. This design simplifies porting of pre-existing</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> applications to SYCL. Second, the design allows the optimal compiler to be</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> chosen for each device where different vendors may provide optimized</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> tool-chains.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> SYCL is designed to be as close to standard C++ as possible. In practice,</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> this means that as long as no dependence is created on SYCL’s integration</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> with OpenCL, a standard C++ compiler can compile the SYCL programs and they</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> will run correctly on host CPU. Any use of specialized low-level features</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> can be masked using the C preprocessor in the same way that</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> compiler-specific intrinsics may be hidden to ensure portability between</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">> different host compilers.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Following this approach, SYCL uses C++ templates to represent pointers to</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">disjoint memory regions on an accelerator to enable compilation with standard</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">C++ toolchain and SYCL compiler toolchain.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">For instance:</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">```c++</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">// CPU/host implementation</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">template <typename T, address_space AS> class multi_ptr {</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  T *data; // ignore address space parameter on CPU</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  public:</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  T *get_pointer() { return data; }</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">}</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">// check that SYCL mode is ON and we can use non-standard annotations</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">#if defined(__SYCL_DEVICE_ONLY__)</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">// GPU/accelerator implementation</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">template <typename T, address_space AS> class multi_ptr {</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  // GetAnnotatedPointer<T, global>::type == "__attribute__((opencl_global)) T"</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  using pointer_t = typename GetAnnotatedPointer<T, AS>::type *;</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  pointer_t data;</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  public:</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  pointer_t get_pointer() { return data; }</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">}</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">#endif</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">```</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">User can use `multi_ptr` class as regular user-defined type in regular C++ code:</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">```c++</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">int *UserFunc(multi_ptr<int, global> ptr) {</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  /// ...</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">  return ptr.get_pointer();</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">}</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">```</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Depending on the compiler mode `multi_ptr` will either annotate internal data</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">with address space attribute or not.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><b><span lang="EN-US">## Implementation details</span></b><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">OpenCL attributes are handled by Parser in all modes. OpenCL mode has specific</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">logic in Sema and CodeGen components for these attributes.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">SYCL compiler re-use generic support for these attributes as is and modifies</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Sema and CodeGen libraries. The main difference with OpenCL mode is that SYCL</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">mode (similar to other single-source GPU programming modes like OpenMP/CUDA/HIP)</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">keeps "default" address space for the declaration without address space</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">attribute annotations. This keeps the code shared between the host and device</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">semantically-correct for both compilers: regular C++ host compiler and SYCL</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">compiler.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">To make all pointers without an explicit address space qualifier to be pointers</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">in generic address space, we updated SPIR target address space map, which</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">currently maps default pointers to "private" address space. We made this change</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">specific to SYCL by adding SYCL environment component to the Triple to avoid</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">impact on other modes targeting SPIR target (e.g. OpenCL). We would be glad to</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">see get a feedback from the community if changing this mapping is applicable for</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">all the modes and additional specialization can be avoided (e.g.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">[AMDGPU](<u><a href="https://github.com/llvm/llvm-project/blob/master/clang/lib/Basic/Targets/AMDGPU.cpp#L329">https://github.com/llvm/llvm-project/blob/master/clang/lib/Basic/Targets/AMDGPU.cpp#L329</a></u>)</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">maps default to "generic" address space with a couple of exceptions).</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">There are a few cases when CodeGen assigns non-default address space:</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">1. For declaration explicitly annotated with address space attribute</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">2. Variables with static storage duration and string literals are allocated in</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">   global address space unless specific address space it specified.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">3. Variables with automatic storage durations are allocated in private address</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">   space. It's current compiler behavior and it doesn't require additional</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">   changes.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">For (2) and (3) cases, once "default" pointer to such variable is obtained, it</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">is immediately addrspacecast'ed to generic, because a user does not (and should</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">not) specify address space for pointers in source code.</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">A draft patch containing complete change-set is available </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">[here](<u><a href="https://github.com/bader/llvm/pull/18/">https://github.com/bader/llvm/pull/18/</a></u>).</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US">Does this approach seem reasonable?</span><o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
<p class="xmsonormal">Thanks,<o:p></o:p></p>
<p class="xmsonormal">Alexey<o:p></o:p></p>
<p class="xmsonormal"> <o:p></o:p></p>
<p class="xmsonormal"><span lang="EN-US"> </span><o:p></o:p></p>
</div>
</div>
</div>
</div>
</body>
</html>