Skip to content

SPIRV Toolchain for Clang

AnastasiaStulova edited this page Aug 24, 2018 · 1 revision

Design Ideas: SPIR-V 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: opencltooling-wgchair@khronos.org).

Command line interface

Required modifications to the flags that Clang should accept:

  • Add triple spirv32-unknown-unknown and spirv64-unknown-unknown (NOTE: it's different to SPIR counterpart spir-unknown-unknown and spir64-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.

Use cases

A. Compile

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.

B. Link

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.

C. Optimize

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.

D. Debug

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.

File Extensions

.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).