From 75325f5f6ada3e53215a18860ef2be35bbb172d6 Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Tue, 6 May 2025 11:52:57 -0400 Subject: [PATCH 1/6] Add proposal for symbol visibility. --- proposals/NNNN-symbol-visibility.md | 90 +++++++++++++++++++++++++++++ 1 file changed, 90 insertions(+) create mode 100644 proposals/NNNN-symbol-visibility.md diff --git a/proposals/NNNN-symbol-visibility.md b/proposals/NNNN-symbol-visibility.md new file mode 100644 index 0000000..5e86e04 --- /dev/null +++ b/proposals/NNNN-symbol-visibility.md @@ -0,0 +1,90 @@ +# Global symbol visibility + +* Proposal: [NNNN](http://NNNN-filename.md) +* Author(s): [Steven Perron](https://github.com/s-perron) +* Status: **Design In Progress** + +*During the review process, add the following fields as needed:* + +* PRs: [\#NNNN](https://github.com/llvm/llvm-project/pull/NNNN) +* Issues: [\#NNNN](https://github.com/llvm/llvm-project/issues/NNNN) +* Posts: [LLVM Discourse](https://discourse.llvm.org/) + +## Introduction + +Section 3.6 of the +[HLSL specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf) +defined the possible linkages for names. This proposal updates how these +linkages are represented in LLVM IR. The current implementation presents +challenges for the SPIR-V backend due to inconsistencies with OpenCL. We propose +that names with program linkage in HLSL should have external linkage and default +visibility in LLVM IR, while names with external linkage in HLSL should have +external linkage and hidden visibility in LLVM IR. + +## Motivation + +Consider the following HLSL snippet: + +``` +void external_linkage() { … } +export void program_linkage() { … } +``` + +In llvm-ir, these function will be represented as: + +``` +define void @external_linkage()() local_unnamed_addr #0 !dbg !8 { + ret void, !dbg !12 +} + +define void @program_linkage()() local_unnamed_addr #1 !dbg !13 { + ret void, !dbg !14 +} + +attributes #0 = { ... } # no hlsl.export +attributes #1 = { ... "hlsl.export" ...} +``` + +In the DirectX backend, there is a pass that will “finalize” the linkage. It +will change `@external_linkage’s` linkage to internal, and remove the +`hlsl.export` attribute from `@program_linkage`. + +The SPIR-V backend emits the `Export` linkage attribute for every symbol with +external linkage. For the example above, `external_linkage` would be decorated +with the `Export` linkage attribute giving it the equivalent of program linkage. +We cannot change this without modifying the behaviour for OpenCL. OpenCL +generates functions that look exactly like `external_linkage` and they require +the `Export` linkage attribute in the SPIR-V. + +To be consistent with OpenCL, we must represent function with program linkage +the way we currently represent functions with `external_linkage`. Then we can +represent functions with external linkage as with some other attribute. + +## Proposed solution + +I propose mapping HLSL concepts found in section 3.6 of the HLSL specification +as follows: + +HLSL concept | LLVM-IR concept +:---------------------------------- | :--------------- +Translation unit | Translation unit +Program (partially or fully linked) | Shared library + +Then, we can map the HLSL linkages to LLVM IR as follows: + +| HLSL Linkage | LLVM-IR representation | +|----------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Program linkage**:
Visible outside the program | **Linkage type: external**
**Visibility style: default**
These symbols are potentially visible outside the shared library. | +| **External linkage**:
These symbols are visible outside the translation unit, but not outside the program. | **Linkage type: external**
**Visibility style: hidden**
These symbols are visible outside the translation unit and therefore participate in linking. However, the hidden visibility style means they are not visible outside the shared library. | +| **Internal linkage**:
Visible anywhere in the translation unit, but not outside it. | **Linkage type: internal**
**Visibility style: default**
These symbols are accessible in the current translation unit but will be renamed to avoid collisions during linking. That is, they are not visible outside the translation unit. | + + +See the LLVM language reference for definitions of the +[linkage types](https://llvm.org/docs/LangRef.html) and +[visibility styles](https://llvm.org/docs/LangRef.html). + +This provides a clean conceptual mapping from HLSL to LLVM IR and will be +consistent with OpenCL’s implementation. + +Backends should assume they are generating HLSL programs. If any linking occurs, +it happens before the backend. From 75f218fe89bc6ebdd6388cad523021bf7d7ba8d4 Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Wed, 14 May 2025 12:42:31 -0400 Subject: [PATCH 2/6] Add extra explainations. --- proposals/NNNN-symbol-visibility.md | 51 +++++++++++++++-------------- 1 file changed, 27 insertions(+), 24 deletions(-) diff --git a/proposals/NNNN-symbol-visibility.md b/proposals/NNNN-symbol-visibility.md index 5e86e04..77a22da 100644 --- a/proposals/NNNN-symbol-visibility.md +++ b/proposals/NNNN-symbol-visibility.md @@ -1,14 +1,8 @@ # Global symbol visibility -* Proposal: [NNNN](http://NNNN-filename.md) -* Author(s): [Steven Perron](https://github.com/s-perron) -* Status: **Design In Progress** - -*During the review process, add the following fields as needed:* - -* PRs: [\#NNNN](https://github.com/llvm/llvm-project/pull/NNNN) -* Issues: [\#NNNN](https://github.com/llvm/llvm-project/issues/NNNN) -* Posts: [LLVM Discourse](https://discourse.llvm.org/) +* Proposal: [NNNN](http://NNNN-filename.md) +* Author(s): [Steven Perron](https://github.com/s-perron) +* Status: **Design In Progress** ## Introduction @@ -16,29 +10,39 @@ Section 3.6 of the [HLSL specification](https://microsoft.github.io/hlsl-specs/specs/hlsl.pdf) defined the possible linkages for names. This proposal updates how these linkages are represented in LLVM IR. The current implementation presents -challenges for the SPIR-V backend due to inconsistencies with OpenCL. We propose +challenges for the SPIR-V backend due to inconsistencies with OpenCL. In HLSL, a +name can have external linkage and program linkage, among other. If a name has +external linkage, it is visible outside the translation unit, but not outside a +linked program. +A name with program linkage is visible outside a partially linked program. +We propose that names with program linkage in HLSL should have external linkage and default visibility in LLVM IR, while names with external linkage in HLSL should have -external linkage and hidden visibility in LLVM IR. +external linkage and hidden visibility in LLVM IR. They both have external +linkage because they are visible outside the translation unit. Default +visibility means the name is visible outside a shared library (program). Hidden +visibility means the name is not visible outside the shared library (program). ## Motivation -Consider the following HLSL snippet: +The way HLSL linkage is represented in the current clang compiler is +inconsistent with how OpenCL SPIRV represents equivalent concepts. Consider the +following HLSL snippet: ``` -void external_linkage() { … } -export void program_linkage() { … } +void external_linkage() {} +export void program_linkage() {} ``` In llvm-ir, these function will be represented as: ``` -define void @external_linkage()() local_unnamed_addr #0 !dbg !8 { - ret void, !dbg !12 +define void @external_linkage()() local_unnamed_addr [#0](#0) { + ret void } -define void @program_linkage()() local_unnamed_addr #1 !dbg !13 { - ret void, !dbg !14 +define void @program_linkage()() local_unnamed_addr [#1](#1) { + ret void } attributes #0 = { ... } # no hlsl.export @@ -58,17 +62,17 @@ the `Export` linkage attribute in the SPIR-V. To be consistent with OpenCL, we must represent function with program linkage the way we currently represent functions with `external_linkage`. Then we can -represent functions with external linkage as with some other attribute. +distinguish functions with external linkage with some other attribute. ## Proposed solution I propose mapping HLSL concepts found in section 3.6 of the HLSL specification as follows: -HLSL concept | LLVM-IR concept -:---------------------------------- | :--------------- -Translation unit | Translation unit -Program (partially or fully linked) | Shared library + HLSL concept | LLVM-IR concept +:------------------------------------|:----------------- + Translation unit | Translation unit + Program (partially or fully linked) | Shared library Then, we can map the HLSL linkages to LLVM IR as follows: @@ -78,7 +82,6 @@ Then, we can map the HLSL linkages to LLVM IR as follows: | **External linkage**:
These symbols are visible outside the translation unit, but not outside the program. | **Linkage type: external**
**Visibility style: hidden**
These symbols are visible outside the translation unit and therefore participate in linking. However, the hidden visibility style means they are not visible outside the shared library. | | **Internal linkage**:
Visible anywhere in the translation unit, but not outside it. | **Linkage type: internal**
**Visibility style: default**
These symbols are accessible in the current translation unit but will be renamed to avoid collisions during linking. That is, they are not visible outside the translation unit. | - See the LLVM language reference for definitions of the [linkage types](https://llvm.org/docs/LangRef.html) and [visibility styles](https://llvm.org/docs/LangRef.html). From a87d7d7f4e2ac3f94663a933652f5829777c02c5 Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Wed, 14 May 2025 12:43:40 -0400 Subject: [PATCH 3/6] Format table. --- proposals/NNNN-symbol-visibility.md | 56 ++++++++++++++++++----------- 1 file changed, 35 insertions(+), 21 deletions(-) diff --git a/proposals/NNNN-symbol-visibility.md b/proposals/NNNN-symbol-visibility.md index 77a22da..34c6f25 100644 --- a/proposals/NNNN-symbol-visibility.md +++ b/proposals/NNNN-symbol-visibility.md @@ -1,8 +1,8 @@ # Global symbol visibility -* Proposal: [NNNN](http://NNNN-filename.md) -* Author(s): [Steven Perron](https://github.com/s-perron) -* Status: **Design In Progress** +* Proposal: [NNNN](http://NNNN-filename.md) +* Author(s): [Steven Perron](https://github.com/s-perron) +* Status: **Design In Progress** ## Introduction @@ -13,15 +13,14 @@ linkages are represented in LLVM IR. The current implementation presents challenges for the SPIR-V backend due to inconsistencies with OpenCL. In HLSL, a name can have external linkage and program linkage, among other. If a name has external linkage, it is visible outside the translation unit, but not outside a -linked program. -A name with program linkage is visible outside a partially linked program. -We propose -that names with program linkage in HLSL should have external linkage and default -visibility in LLVM IR, while names with external linkage in HLSL should have -external linkage and hidden visibility in LLVM IR. They both have external -linkage because they are visible outside the translation unit. Default -visibility means the name is visible outside a shared library (program). Hidden -visibility means the name is not visible outside the shared library (program). +linked program. A name with program linkage is visible outside a partially +linked program. We propose that names with program linkage in HLSL should have +external linkage and default visibility in LLVM IR, while names with external +linkage in HLSL should have external linkage and hidden visibility in LLVM IR. +They both have external linkage because they are visible outside the translation +unit. Default visibility means the name is visible outside a shared library +(program). Hidden visibility means the name is not visible outside the shared +library (program). ## Motivation @@ -69,18 +68,33 @@ distinguish functions with external linkage with some other attribute. I propose mapping HLSL concepts found in section 3.6 of the HLSL specification as follows: - HLSL concept | LLVM-IR concept -:------------------------------------|:----------------- - Translation unit | Translation unit - Program (partially or fully linked) | Shared library +HLSL concept | LLVM-IR concept +:---------------------------------- | :--------------- +Translation unit | Translation unit +Program (partially or fully linked) | Shared library Then, we can map the HLSL linkages to LLVM IR as follows: -| HLSL Linkage | LLVM-IR representation | -|----------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| **Program linkage**:
Visible outside the program | **Linkage type: external**
**Visibility style: default**
These symbols are potentially visible outside the shared library. | -| **External linkage**:
These symbols are visible outside the translation unit, but not outside the program. | **Linkage type: external**
**Visibility style: hidden**
These symbols are visible outside the translation unit and therefore participate in linking. However, the hidden visibility style means they are not visible outside the shared library. | -| **Internal linkage**:
Visible anywhere in the translation unit, but not outside it. | **Linkage type: internal**
**Visibility style: default**
These symbols are accessible in the current translation unit but will be renamed to avoid collisions during linking. That is, they are not visible outside the translation unit. | +| HLSL Linkage | LLVM-IR representation | +| --------------------------------- | ---------------------------------------- | +| **Program linkage**:
Visible | **Linkage type: external**
| +: outside the program : **Visibility style\: default**
These : +: : symbols are potentially visible outside : +: : the shared library. : +| **External linkage**:
These | **Linkage type: external**
| +: symbols are visible outside the : **Visibility style\: hidden**
These : +: translation unit, but not outside : symbols are visible outside the : +: the program. : translation unit and therefore : +: : participate in linking. However, the : +: : hidden visibility style means they are : +: : not visible outside the shared library. : +| **Internal linkage**:
Visible | **Linkage type: internal**
| +: anywhere in the translation unit, : **Visibility style\: default**
These : +: but not outside it. : symbols are accessible in the current : +: : translation unit but will be renamed to : +: : avoid collisions during linking. That : +: : is, they are not visible outside the : +: : translation unit. : See the LLVM language reference for definitions of the [linkage types](https://llvm.org/docs/LangRef.html) and From 33ad6df2621604f4e786fa24a3da0db7f4f9f9aa Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Wed, 14 May 2025 12:45:52 -0400 Subject: [PATCH 4/6] Revert "Format table." This reverts commit a87d7d7f4e2ac3f94663a933652f5829777c02c5. --- proposals/NNNN-symbol-visibility.md | 56 +++++++++++------------------ 1 file changed, 21 insertions(+), 35 deletions(-) diff --git a/proposals/NNNN-symbol-visibility.md b/proposals/NNNN-symbol-visibility.md index 34c6f25..77a22da 100644 --- a/proposals/NNNN-symbol-visibility.md +++ b/proposals/NNNN-symbol-visibility.md @@ -1,8 +1,8 @@ # Global symbol visibility -* Proposal: [NNNN](http://NNNN-filename.md) -* Author(s): [Steven Perron](https://github.com/s-perron) -* Status: **Design In Progress** +* Proposal: [NNNN](http://NNNN-filename.md) +* Author(s): [Steven Perron](https://github.com/s-perron) +* Status: **Design In Progress** ## Introduction @@ -13,14 +13,15 @@ linkages are represented in LLVM IR. The current implementation presents challenges for the SPIR-V backend due to inconsistencies with OpenCL. In HLSL, a name can have external linkage and program linkage, among other. If a name has external linkage, it is visible outside the translation unit, but not outside a -linked program. A name with program linkage is visible outside a partially -linked program. We propose that names with program linkage in HLSL should have -external linkage and default visibility in LLVM IR, while names with external -linkage in HLSL should have external linkage and hidden visibility in LLVM IR. -They both have external linkage because they are visible outside the translation -unit. Default visibility means the name is visible outside a shared library -(program). Hidden visibility means the name is not visible outside the shared -library (program). +linked program. +A name with program linkage is visible outside a partially linked program. +We propose +that names with program linkage in HLSL should have external linkage and default +visibility in LLVM IR, while names with external linkage in HLSL should have +external linkage and hidden visibility in LLVM IR. They both have external +linkage because they are visible outside the translation unit. Default +visibility means the name is visible outside a shared library (program). Hidden +visibility means the name is not visible outside the shared library (program). ## Motivation @@ -68,33 +69,18 @@ distinguish functions with external linkage with some other attribute. I propose mapping HLSL concepts found in section 3.6 of the HLSL specification as follows: -HLSL concept | LLVM-IR concept -:---------------------------------- | :--------------- -Translation unit | Translation unit -Program (partially or fully linked) | Shared library + HLSL concept | LLVM-IR concept +:------------------------------------|:----------------- + Translation unit | Translation unit + Program (partially or fully linked) | Shared library Then, we can map the HLSL linkages to LLVM IR as follows: -| HLSL Linkage | LLVM-IR representation | -| --------------------------------- | ---------------------------------------- | -| **Program linkage**:
Visible | **Linkage type: external**
| -: outside the program : **Visibility style\: default**
These : -: : symbols are potentially visible outside : -: : the shared library. : -| **External linkage**:
These | **Linkage type: external**
| -: symbols are visible outside the : **Visibility style\: hidden**
These : -: translation unit, but not outside : symbols are visible outside the : -: the program. : translation unit and therefore : -: : participate in linking. However, the : -: : hidden visibility style means they are : -: : not visible outside the shared library. : -| **Internal linkage**:
Visible | **Linkage type: internal**
| -: anywhere in the translation unit, : **Visibility style\: default**
These : -: but not outside it. : symbols are accessible in the current : -: : translation unit but will be renamed to : -: : avoid collisions during linking. That : -: : is, they are not visible outside the : -: : translation unit. : +| HLSL Linkage | LLVM-IR representation | +|----------------------------------------------------------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| **Program linkage**:
Visible outside the program | **Linkage type: external**
**Visibility style: default**
These symbols are potentially visible outside the shared library. | +| **External linkage**:
These symbols are visible outside the translation unit, but not outside the program. | **Linkage type: external**
**Visibility style: hidden**
These symbols are visible outside the translation unit and therefore participate in linking. However, the hidden visibility style means they are not visible outside the shared library. | +| **Internal linkage**:
Visible anywhere in the translation unit, but not outside it. | **Linkage type: internal**
**Visibility style: default**
These symbols are accessible in the current translation unit but will be renamed to avoid collisions during linking. That is, they are not visible outside the translation unit. | See the LLVM language reference for definitions of the [linkage types](https://llvm.org/docs/LangRef.html) and From ac939757157a286f21ea6009eb51e9fe6f10c516 Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Wed, 14 May 2025 12:53:47 -0400 Subject: [PATCH 5/6] Fill in proposal number 0026 --- .../{NNNN-symbol-visibility.md => 0026-symbol-visibility.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename proposals/{NNNN-symbol-visibility.md => 0026-symbol-visibility.md} (99%) diff --git a/proposals/NNNN-symbol-visibility.md b/proposals/0026-symbol-visibility.md similarity index 99% rename from proposals/NNNN-symbol-visibility.md rename to proposals/0026-symbol-visibility.md index 77a22da..ce345db 100644 --- a/proposals/NNNN-symbol-visibility.md +++ b/proposals/0026-symbol-visibility.md @@ -1,6 +1,6 @@ # Global symbol visibility -* Proposal: [NNNN](http://NNNN-filename.md) +* Proposal: [0026](http://0026-filename.md) * Author(s): [Steven Perron](https://github.com/s-perron) * Status: **Design In Progress** From 3d20f55e72bf0843a8b463beb962354738a89b37 Mon Sep 17 00:00:00 2001 From: Steven Perron Date: Wed, 14 May 2025 12:54:40 -0400 Subject: [PATCH 6/6] Fix typo --- proposals/0026-symbol-visibility.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/proposals/0026-symbol-visibility.md b/proposals/0026-symbol-visibility.md index ce345db..436460c 100644 --- a/proposals/0026-symbol-visibility.md +++ b/proposals/0026-symbol-visibility.md @@ -11,7 +11,7 @@ Section 3.6 of the defined the possible linkages for names. This proposal updates how these linkages are represented in LLVM IR. The current implementation presents challenges for the SPIR-V backend due to inconsistencies with OpenCL. In HLSL, a -name can have external linkage and program linkage, among other. If a name has +name can have external linkage and program linkage, among others. If a name has external linkage, it is visible outside the translation unit, but not outside a linked program. A name with program linkage is visible outside a partially linked program.