-
Notifications
You must be signed in to change notification settings - Fork 224
SPIRV Toolchain for Clang
This document details a proposal for adding the SPIR-V target to Clang and the invocation of the following external tools in the Clang driver:
-
a SPIRV-LLVM Translator tool that allows to generate portable binaries in the SPIR-V format that can be further used as an input to various proprietary toolchains/backends.
-
the SPIR-V linker from SPIRV-Tools for linking SPIR-V object files.
This document has been created by the OpenCL Tooling Ecosystem Group of Khronos (contact: [email protected]).
Required modifications to the flags that Clang should accept:
-
Add triple
spirv32-unknown-unknown
andspirv64-unknown-unknown
(NOTE: it's different to SPIR counterpartspir-unknown-unknown
andspir64-unknown-unknown
). -
Add new flag
--spirv-path=/some/path
for specifying the location of all SPIR-V tools and separate paths per tool--spirv-trans-path
,--spirv-link-path
. -
Add
-Xspirv-trans
,-Xspirv-link
to allow passing flags to the translator and to the linker respectively.
1. Compile down to SPIR-V object
clang -c test.cl -target spirv[32|64]-unknown-unknown -o test.spv
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test.cl -emit-llvm-bc -o test.bc
(ii) llvm-spirv test.bc -o test.spv
This will use default translator from installation.
Default output name: test.spv
.
2. Compile down to SPIR-V object with the path to the translator given from command line
clang -c test.cl -target spirv[32|64]-unknown-unknown -o test.spv --spirv-trans-path=/usr/bin/
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test.cl -emit-llvm-bc -o test.bc
(ii) /usr/bin/llvm-spirv test.bc -o test.spv
Default output name: test.spv
.
3. Compile down to SPIR-V assembly with the path to the translator given from command line
clang -S test.cl -target spirv[32|64]-unknown-unknown --spirv-trans-path=/usr/bin/ -o test.spt
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test.cl -emit-llvm-bc -o test.bc
(ii) /usr/bin/llvm-spirv -spirv-text test.bc -o test.spt
Default output name: test.spt
.
4. Compile down to bitcode
clang -emit-llvm test.cl -target spirv[32|64]-unknown-unknown -o test.bc
This will result in the following driver action:
clang -cc1 -emit-llvm-bc test.cl -triple spirv[32|64]-unknown-unknown -o test.bc
Default output name: test.bc
.
5. Emit LLVM IR from SPIR-V module(s).
clang test1.spv test2.spv -emit-llvm -c -target spirv-unknown-unknown
This will result in the following driver actions:
(i) llvm-spirv -r test1.spv -o test1.bc
(ii) llvm-spirv -r test2.spv -o test2.bc
Default output name: test1.bc
and test2.bc
.
6. Creating SPIR-V libraries
clang test1.cl test2.spv -o test.spv -target spirv[32|64]-unknown-unknown -Xspirv-link --create-library --allow-partial-linkage
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test1.cl -emit-llvm-bc -o test1.bc
(ii) llvm-spirv test1.bc -o test1.spv
(iii) spirv-link --create-library --allow-partial-linkage -o test.spv test1.spv test2.spv
Default output name: a.spv
.
7. Compile down to SPIR-V final binary
clang test.cl -target spirv[32|64]-unknown-unknown -o test.spvbin
This will result in the following driver actions:
(i) clang -target spirv[32|64]-unknown-unknown test.cl -emit-llvm -o test.bc
(ii) llvm-spirv test.bc -o test.spv
(iii) spirv-link test.spv -o test.spvbin
This will use default translator from installation.
Default output name: a.spvbin
.
1. Linking multiple SPIR-V modules with the path to the linker given
clang -target spirv[32|64]-unknown-unknown test1.spv test2.spv -o test.spvbin --spirv-link-path=/usr/bin
This will result in the following driver action:
/usr/bin/spirv-link -o test.spvbin test1.spv test2.spv
Default output name: a.spvbin
.
2. Compile and link multiple SPIR-V modules with the common path
clang test1.cl test2.spv -o test.spvbin -target spirv[32|64]-unknown-unknown --spirv-path=/usr/bin
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test1.cl -emit-llvm-bc -o test1.bc
(ii) /usr/bin/llvm-spirv test1.bc -o test1.spv
(iii) /usr/bin/spirv-link -o test.spvbin test1.spv test2.spv
Default output name: a.spvbin
.
3. Compile and link multiple SPIR-V modules with the separate paths to tools
clang test1.cl test2.spv -o test.spvbin -target spirv[32|64]-unknown-unknown --spirv-link-path=/usr/bin/link --spirv-trans-path=/usr/bin/trans
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test1.cl -emit-llvm-bc -o test1.bc
(ii) /usr/bin/trans/llvm-spirv test1.bc -o test1.spv
(iii) /usr/bin/link/spirv-link -o test.spvbin test1.spv test2.spv
Default output name: a.spvbin
.
4. Link separate mixed CL, IR and SPIR-V modules into final binary
clang test1.cl test2.bc test3.spv -o test.spvbin -target spirv[32|64]-unknown-unknown
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test1.cl -emit-llvm-bc -o test1.bc
(ii) llvm-spirv test1.bc -o test1.spv
(iii) clang -cc1 -triple spirv[32|64]-unknown-unknown test2.bc -emit-llvm-bc -o test2.bc
(iv) llvm-spirv test2.bc -o test2.spv
(v) spirv-link -o test.spvbin test1.spv test2.spv test3.spv
Default output name: a.spvbin
.
1. Compile down to SPIR-V object from OpenCL source or bitcode file(s) with optimisations
clang -c test.cl -target spirv[32|64]-unknown-unknown -o test.spv -O3
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test.cl -emit-llvm-bc -o test.bc -O3
(ii) llvm-spirv test.bc -o test.spv
Default output name: test.spv
.
1. Compile down to SPIR-V object with debug info
clang -c test.cl -target spirv[32|64]-unknown-unknown -o test.spv -g
This will result in the following driver actions:
(i) clang -cc1 -triple spirv[32|64]-unknown-unknown test.cl -emit-llvm-bc -o test.bc -g
(ii) llvm-spirv test.bc -o test.spv
Default output name: test.spv
.
.cl - OpenCL C/C++ file.
.spv - SPIR-V module/object file or a library (doesn’t have to contain entry points, contains exported and optionally external symbols). Single SPIR-V module/object file corresponds to one .cl source file. Library can be linked from several modules/object files.
.spt - SPIR-V assembly.
.spvbin - SPIR-V bin (with at least one entry point and no external symbols unless --allow-partial-linkage is passed to the linker).