<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Windows-1252">
<meta name="Generator" content="Microsoft Exchange Server">
<!-- converted from text --><style><!-- .EmailQuote { margin-left: 1pt; padding-left: 4pt; border-left: #800000 2px solid; } --></style>
</head>
<body>
<div>
<div dir="auto" style="direction:ltr; margin:0; padding:0; font-family:sans-serif; font-size:11pt; color:black">
I agree with Simon. This looks good conceptually. I have minor implementation comments but that can wait till the code reviews.<br>
<br>
</div>
<div dir="auto" style="direction:ltr; margin:0; padding:0; font-family:sans-serif; font-size:11pt; color:black">
Sorry for the delay and thanks for working on this.<br>
<br>
</div>
<div dir="auto" style="direction:ltr; margin:0; padding:0; font-family:sans-serif; font-size:11pt; color:black">
<span id="x_OutlookSignature">
<div dir="auto" style="direction:ltr; margin:0; padding:0; font-family:sans-serif; font-size:11pt; color:black">
Get <a href="https://aka.ms/ghei36">Outlook for Android</a></div>
</span><br>
</div>
<hr tabindex="-1" style="display:inline-block; width:98%">
<div id="x_divRplyFwdMsg" dir="ltr"><font face="Calibri, sans-serif" color="#000000" style="font-size:11pt"><b>From:</b> Simon Moll <moll@cs.uni-saarland.de><br>
<b>Sent:</b> Monday, June 17, 2019 10:02:58 AM<br>
<b>To:</b> Francesco Petrogalli; LLVM Development List; Clang Dev<br>
<b>Cc:</b> Renato Golin; Finkel, Hal J.; Andrea Bocci; Elovikov, Andrei; Alexey Bataev; Doerfert, Johannes; Saito, Hideki; Tian, Xinmin; nd; Roman Lebedev; Philip Reames; Shawn Landden<br>
<b>Subject:</b> Re: RFC: Interface user provided vector functions with the vectorizer.</font>
<div> </div>
</div>
</div>
<font size="2"><span style="font-size:11pt;">
<div class="PlainText">Hi Francesco,<br>
<br>
On 6/11/19 10:55 PM, Francesco Petrogalli wrote:<br>
> Dear all,<br>
><br>
> I have re-written the proposal for interfacing user provided vector<br>
> functions, originally posted in both llvm-dev and cfe-dev mailing<br>
> list:<br>
><br>
> "[RFC] Expose user provided vector function for auto-vectorization."<br>
><br>
> The proposal looks quite different from the original submission,<br>
> therefore I took the liberty to start a new thread.<br>
><br>
> The original thread generated some good discussion. In particular,<br>
> Simon Moll and Johannes Doerfert (CCed) have managed to provide good<br>
> arguments for the following claims:<br>
><br>
> 1. The Vector Function ABI name mangling scheme of a target is not<br>
>     enough to describe all uses cases of function vectorization that<br>
>     the compiler might end up needing to support in the future.<br>
I think the new name of the attribute makes this point clear.<br>
> 2. `declare variant` needs to be handled properly at IR level, to be<br>
>     able to give the compiler the full OpenMP context of the directive.<br>
><br>
> This proposal addresses those two concerns and other (I believe) minor<br>
> concerns that have been raised in the previous thread.<br>
><br>
> This proposal is provided with examples and a self assessment around<br>
> extendibility.<br>
><br>
> I have CCed all the people that have participated in the discussion so<br>
> far, please let me know if you think I have missed anything of what<br>
> have been raised.<br>
><br>
> Kind regards,<br>
><br>
> Francesco<br>
<br>
LGTM. Please add me as a reviewer for this when you post patches.<br>
<br>
Thanks!<br>
<br>
Simon<br>
<br>
><br>
> *** DRAFT OF THE PROPOSAL ***<br>
><br>
> # SCOPE OF THE RFC : Interface user provided vector functions with the vectorizer.<br>
><br>
> Because the users care about portability (across compilers, libraries<br>
> and systems), I believe we have to base sour solution on a standard<br>
> that describes the mapping from the scalar function to the vector<br>
> function.<br>
><br>
> Because OpenMP is standard and widely used, we should base our<br>
> solution on the mechanisms that the standard provides, via the<br>
> directives `declare simd` and `declare variant`, the latter when used<br>
> in with the `simd` trait in the `construct` set.<br>
><br>
> Please notice that:<br>
><br>
> 1. The scope of the proposal is not implementing full support for<br>
>     `pragma omp declare variant`.<br>
> 2. The scope of the proposal is not enabling the vectorizer to do new<br>
>     kind of vectorizations (e.g. RV-like vectorization described by<br>
>     Simon).<br>
> 3. The proposal aims to be extendible wrt 1. and 2.<br>
> 4. The IR attribute introduced in this proposal is equivalent to the<br>
>     one needed for the VecClone pass under development in<br>
>     <a href="https://reviews.llvm.org/D22792">https://reviews.llvm.org/D22792</a><br>
><br>
> # CLANG COMPONENTS<br>
><br>
> A C function attribute, `clang_declare_simd_variant`, to attach to the<br>
> scalar version. The attribute provides enough information to the<br>
> compiler about the vector shape of the user defined function. The<br>
> vector shapes handled by the attribute are those handled by the OpenMP<br>
> standard via `declare simd` (and no more than that).<br>
><br>
> 1. The function attribute handling in clang is crafted with the<br>
>     requirement that it will be possible to re-use the same components<br>
>     for the info generated by `declare variant` when used with a `simd`<br>
>     traits in the `construct` set.<br>
> 2. The attribute allows orthogonality with the vectorization that is<br>
>     done via OpenMP: the user vector function is still exposed for<br>
>     vectorization when not using `-fopenmp-[simd]` once the `declare<br>
>     simd` and `declare variant` directive of OpenMP will be available<br>
>     in the front-end.<br>
><br>
> ## C function attribute: `clang_declare_simd_variant`<br>
><br>
> The definition of this attribute has been crafted to match the<br>
> semantics of `declare variant` for a `simd` construct described in<br>
> OpenMP 5.0. I have added only the traits of the `device` set, `isa`<br>
> and `arch`, which I believe are enough to cover for the use case of<br>
> this proposal. If that is not the case, please provide an example,<br>
> extending the attribute will be easy even once the current one is<br>
> implemented.<br>
><br>
> ```<br>
> clang_declare_simd_variant(<variant-func-id>, <simd clauses>{, <context selector clauses>})<br>
><br>
> <variant-func-id>:= The name of a function variant that is a base language identifier, or,<br>
>                      for C++, a template-id.<br>
><br>
> <simd clauses> := <simdlen>, <mask>{, <optional simd clauses>}<br>
><br>
> <simdlen> := simdlen(<positive number>) | simdlen("scalable")<br>
><br>
> <mask>    := inbranch | notinbranch<br>
><br>
> <optional simd clauses> := <linear clause><br>
>                           | <uniform clause><br>
>                           | <align clause>  | {,<optional simd clauses>}<br>
><br>
> <linear clause>  := linear_ref(<var>,<step>)<br>
>                    | linear_var(<var>, <step>)<br>
>                    | linear_uval(<var>, <step>)<br>
>                    | linear(<var>, <step>)<br>
><br>
> <step> := <var> | <non zero number><br>
><br>
> <uniform clause> := uniform(<var>)<br>
><br>
> <align clause>   := align(<var>, <positive number>)<br>
><br>
> <var> := Name of a parameter in the scalar function declaration/definition<br>
><br>
> <non zero number> := ... | -2 | -1 | 1 | 2 | ...<br>
><br>
> <positive number> := 1 | 2 | 3 | ...<br>
><br>
> <context selector clauses> := {<isa>}{,} {<arch>}<br>
><br>
> <isa> := isa(target-specific-value)<br>
><br>
> <arch> := arch(target-specific-value)<br>
><br>
> ```<br>
><br>
> # LLVM COMPONENTS:<br>
><br>
> ## VectorFunctionShape class<br>
><br>
> The object `VectorFunctionShape` contains the information about the<br>
> kind of vectorization available for an `llvm::Call`.<br>
><br>
> The object `VectorFunctionShape` must contain the following information:<br>
><br>
> 1. Vectorization Factor (or number or concurrent lanes executed by the<br>
>     SIMD version of the function). Encoded by unsigned integer.<br>
> 2. Whether the vector function is requested for scalable<br>
>     vectorization, encoded by a boolean.<br>
> 3. Information about masking / no masking, encoded by a boolean.<br>
> 4. Information about the parameters, encoded in a container that<br>
>     carries objects of type `ParamaterType`, to describe features like<br>
>     `linear` and `uniform`.<br>
> 5. Function name redirection, if a user has specified to use a custom<br>
>     name instead of the Vector Function ABI ones.<br>
><br>
> Items 1. to 5. represents the information stored in the<br>
> `vector-function-abi-variant` attribute (see next section).<br>
><br>
> The object can be extended in the future to include new vectorization<br>
> kinds (for example the RV-like vectorization of the Region<br>
> Vectorizer), or to add more context information that might come from<br>
> other uses of OpenMP `declare variant`, or to add new Vector Function<br>
> ABIs not based on OpenMP. Such information can be retrieved by<br>
> attributes that will be added to describe the `Call` instance.<br>
><br>
> ## IR Attribute<br>
><br>
> We define a `vector-function-abi-variant` attribute that lists the<br>
> mangled names produced via the mangling function of the Vector<br>
> Function ABI rules.<br>
><br>
> ```<br>
> vector-function-abi-variant = "abi_mangled_name_01, abi_mangled_name_02(user_redirection),..."<br>
> ```<br>
><br>
> 1. Because we use only OpenMP `declare simd` vectorization, and<br>
>     because we require a vector Function ABI, we make this explicit<br>
>     in the name of the attribute.<br>
> 2. Because the Vector Function ABIs encode all the information<br>
>     needed to know the vectorization shape of the vector function in<br>
>     the mangled names, we provide the mangled name via the<br>
>     attribute.<br>
> 3. Function names redirection is specified by enclosing the name of<br>
>     the redirection in parenthesis, as in<br>
>     `abi_mangled_name_02(user_redirection)`.<br>
><br>
> ## Vector ABI Demangler<br>
><br>
> The “Vector ABI demangler”, is the component that demangles the data<br>
> in the `vector-function-abi-variant` attribute and that provides the<br>
> instances of the class `VectorFunctionShape` that can be derived by<br>
> the mangled names listed in the attribute.<br>
><br>
> ## Query interface: Search Vector Function System (SVFS)<br>
><br>
> An interface that can be queried by the LLVM components to understand<br>
> whether or not a scalar function can be vectorized, and that retrieves<br>
> the vector function to be used if such vector shape is available.<br>
><br>
> 1. This component is going to be unrelated to OpenMP.<br>
> 2. This component will use internally the demangler defined in the<br>
>     previous section, but it will not expose any aspect of the Vector<br>
>     Function ABI via its interface.<br>
><br>
> The interface provides two methods.<br>
><br>
> ```<br>
> std::vector<VectorFunctionShape> SVFS::isFunctionVectorizable(llvm::CallInst * Call);<br>
><br>
> llvm::Function * SVFS::getVectorizedFunction(llvm::CallInst * Call, VectorFunctionShape Info);<br>
> ```<br>
><br>
> The first method is used to list all the vector shapes that available<br>
> and attached to a scalar function. An empty results means that no<br>
> vector versions are available.<br>
><br>
> The second method retrieves the information needed to build a call to<br>
> a vector function with a specific `VectorFunctionShape` info.<br>
><br>
> # (SELF) ASSESSMENT ON EXTENDIBILITY<br>
><br>
><br>
> 1. Extending the C function attribute `clang_declare_simd_variant` to<br>
>     new Vector Function ABIs that use OpenMP will be straightforward<br>
>     because the attribute is tight to such ABIs and OpenMP.<br>
> 2. The C attribute `clang_declare_simd_variant` and the `declare<br>
>     variant` directive used for the `simd` trait will be sharing the<br>
>     internals in clang, so adding the OpenMP functionality for `simd`<br>
>     traits will be mostly handling the directive in the OpenMP<br>
>     parser. How this should be done is described in<br>
>     <a href="https://clang.llvm.org/docs/InternalsManual.html#how-to-add-an-attribute">
https://clang.llvm.org/docs/InternalsManual.html#how-to-add-an-attribute</a><br>
> 3. The IR attribute `vector-function-abi-variant` is not to be<br>
>     extended to represent other kind of vectorization other than those<br>
>     handled by `declare simd` and that are handled with a Vector<br>
>     Function ABI.<br>
> 4. The IR attribute `vector-function-abi-variant` is not defined to be<br>
>     extended to represent the information of `declare variant` in its<br>
>     totality.<br>
> 5. The IR attribute will not need to change when we will introduce non<br>
>     vector function ABI vectorization (RV-like, reductions...) or when<br>
>     we will decide to fully support `declare variant`. The information<br>
>     it carries will not need to be invalidated, but just extended with<br>
>     new attributes that will need to be handled by the<br>
>     `VectorFunctionShape` class, in a similar way the<br>
>     `llvm::FPMathOperator` does with the `llvm::FastMathFlags`, which<br>
>     operates on individual attributes to describe an overall<br>
>     functionality.<br>
><br>
> # Examples<br>
><br>
> ## Example 1<br>
><br>
> Exposing an Advanced SIMD vector function when targeting Advanced SIMD<br>
> in AArch64.<br>
><br>
> ```<br>
> double foo_01(double Input) __attribute__(clang_declare_simd_variant(“vector_foo_01", simdlen(2), notinbranch, isa("simd"));<br>
><br>
> // Advanced SIMD version<br>
> float64x2_t vector_foo_01(float64x2_t VectorInput);<br>
> ```<br>
><br>
> The resulting IR attribute is:<br>
><br>
> ```<br>
> attribute #0 = {vector-abi-variant="_ZGVnN2v_foo_01(vector_foo_01)"}<br>
> ```<br>
><br>
> ## Example 2<br>
><br>
> Exposing an Advanced SIMD vector function when targeting Advanced SIMD<br>
> in AArch64, but with the wrong signature. The user specifies a masked<br>
> version of the function in the clauses of the attribute, the compiler<br>
> throws an error suggesting the signature expected for<br>
> ``vector_foo_02.``<br>
><br>
> ```<br>
> double foo_02(double Input) __attribute__(clang_declare_simd_variant(“vector_foo_02", simdlen(2), inbranch, isa("simd"));<br>
><br>
> // Advanced SIMD version<br>
> float64x2_t vector_foo_02(float64x2_t VectorInput);<br>
> // (suggested) compiler error ->                      ^ Missing mask parameter of type `uint64x2_t`.<br>
> ```<br>
><br>
> ## Example 3<br>
><br>
> Targeting `sincos`-like signatures.<br>
><br>
> ```<br>
> void foo_03(double Input, double * Output) __attribute__(clang_declare_simd_variant(“vector_foo_03", simdlen(2), notinbranch, linear(Output, 1), isa("simd"));<br>
><br>
> // Advanced SIMD version<br>
> void vector_foo_03(float64x2_t VectorInput, double * Output);<br>
> ```<br>
><br>
> The resulting IR attribute is:<br>
><br>
> ```<br>
> attribute #0 = {vector-abi-variant="_ZGVnN2vl8_foo_03(vector_foo_03)"}<br>
> ```<br>
> ## Example 4<br>
><br>
> Scalable vectorization targeting SVE<br>
><br>
> ```<br>
> double foo_04(double Input) __attribute__(clang_declare_simd_variant(“vector_foo_04", simdlen("scalable"), notinbranch, isa("sve"));<br>
><br>
> // SVE version<br>
> svfloat64_t vector_foo_04(svfloat64_t VectorInput, svbool_t Mask);<br>
> ```<br>
><br>
> The resulting IR attribute is:<br>
><br>
> ```<br>
> attribute #0 = {vector-abi-variant="_ZGVsM2v_foo_04(vector_foo_04)"}<br>
> ```<br>
><br>
> ## Example 5<br>
><br>
> Fixed length vectorization targeting SVE<br>
><br>
> ```<br>
> double foo_05(double Input) __attribute__(clang_declare_simd_variant(“vector_foo_05", simdlen(4), inbranch, isa("sve"));<br>
><br>
> // Fixed-length SVE version<br>
> svfloat64_t vector_foo_05(svfloat64_t VectorInput, svbool_t Mask);<br>
> ```<br>
><br>
> The resulting IR attribute is:<br>
><br>
> ```<br>
> attribute #0 = {vector-abi-variant="_ZGVsM2v_foo_04(vector_foo_04)"}<br>
> ```<br>
><br>
> ## Example 06<br>
><br>
> This is an x86 example, equivalent to the one provided by Andrei<br>
> Elovikow in<br>
> <a href="http://lists.llvm.org/pipermail/llvm-dev/2019-June/132885.html">http://lists.llvm.org/pipermail/llvm-dev/2019-June/132885.html</a>. Godbolt<br>
> rendering with ICC at <a href="https://godbolt.org/z/Of1NxZ">https://godbolt.org/z/Of1NxZ</a><br>
><br>
> ```<br>
> float MyAdd(float* a, int b) __attribute__(clang_declare_simd_variant(“MyAddVec", simdlen(8), notinbranch, arch("core_2nd_gen_avx"))<br>
> {<br>
>    return *a + b;<br>
> }<br>
><br>
><br>
> __m256 MyAddVec(float* v_a, __m128i v_b1, __m128i v_b2);<br>
> ```<br>
><br>
> The resulting IR attribute is:<br>
><br>
> ```<br>
> attribute #0 = {vector-abi-variant="_ZGVbN8l4v_MyAdd(MyAddVec)"}<br>
> ```<br>
><br>
> ## Example showing interaction with `declare simd`<br>
><br>
> ```<br>
> #pragma omp declare simd linear(a) notinbranch<br>
> float foo_06(float *a, int x) __attribute__(clang_declare_simd_variant(“vector_foo_06", simdlen(4), linear(a), notinbranch, arch("armv8.2-a+simd")) {<br>
>      return *a + x;<br>
> }<br>
><br>
> // Advanced SIMD version<br>
> float32x4_t vector_foo_06(float *a, int32x4_t vx) {<br>
> // Custom implementation.<br>
> }<br>
> ```<br>
><br>
> The resulting IR attribute is made of three symbols:<br>
><br>
> 1. `_ZGVnN2l4v_foo_06` and `_ZGVnN4l4v_foo_06`, which represent the<br>
>     ones the compiler builds by auto-vectorizing `foo_06` according to<br>
>     the rule defined in the Vector Function ABI specifications for<br>
>     AArch64.<br>
> 2. `_ZGVnN4l4v_foo_06(vector_foo_06)`, which represents the<br>
>     user-defined redirection of the 4-lane version of `foo_06` to the<br>
>     custom implementation provided by the user when targeting Advanced<br>
>     SIMD for version 8.2 of the A64 instruction set.<br>
><br>
> ```<br>
> attribute #0 = {vector-function-abi-variant="_ZGVnN2l4v_foo_06,_ZGVnN4l4v_foo_06,_ZGVnN4l4v_foo_06(vector_foo_06)"}<br>
> ```<br>
><br>
-- <br>
<br>
Simon Moll<br>
Researcher / PhD Student<br>
<br>
Compiler Design Lab (Prof. Hack)<br>
Saarland University, Computer Science<br>
Building E1.3, Room 4.31<br>
<br>
Tel. +49 (0)681 302-57521 : moll@cs.uni-saarland.de<br>
Fax. +49 (0)681 302-3065  : <a href="http://compilers.cs.uni-saarland.de/people/moll">
http://compilers.cs.uni-saarland.de/people/moll</a><br>
<br>
</div>
</span></font>
</body>
</html>