[llvm-dev] [SPIR-V] SPIR-V in LLVM
Nicholas Wilson via llvm-dev
llvm-dev at lists.llvm.org
Tue Jun 20 17:38:45 PDT 2017
On 21 Jun 2017, at 8:20 am, Tom Stellard <tstellar at redhat.com<mailto:tstellar at redhat.com>> wrote:
On 06/20/2017 05:41 PM, Neil Hickey wrote:
Hi all, I'd like to kick this discussion off again, and summarise the points that have been expressed so far.
Firstly, as a member of Khronos, I'd like to state that this would be a very interesting development.
I am very interested in having a good LLVM IR -> SPIR-V solution, and I
think it's great that Khronos is interested in putting effort into making
this happen, however, I disagree with the approach you have outlined
mostly because I don't think it is the most effective use of developer
Khronos, for those who don't know, is a standards body developing open standards for accelerating rich media content on a wide variety of platforms, including GPUs as an example.
Khronos is made up of a large number of companies across a range of industries, but as an example, ARM, Google, Intel, Imagination are all members.
Khronos members are already working on writing backend for llvm that retarget SPIR-V, for example, taking LLVM-IR compiled from OpenCL and targeting this at something that can accept Vulkan, so there is clear interest within the community to see this happen.
Is this code available anywhere?
https://github.com/KhronosGroup/SPIRV-LLVM for a dated version (LLVM 3.6.1 and 3.8)
and llvm-target-spirv<https://github.com/thewilsonator/llvm-target-spirv> and llvm<https://github.com/thewilsonator/llvm> for my up to date (w.r.t LLVM) version.
Firstly, there are a number of benefits to having SPIR-V in LLVM as a backend, both to SPIR-V, the ecosystem and to LLVM.
* Allows any frontend targeting llvm to also target SPIR-V
I think people over estimate the difficulty of integrating a direct LLVM IR
to SPIR-V translator with frontends that emit LLVM IR. All a direct
translator does is take LLVM IR as an input and produce SPIR-V as an output,
interacting with it is not that complicated. I think whatever challenges
this presents would be much easier to solve than implementing a full GlobalIsel
I think he means in the general sense, as compared to no backend at all.
The only thing difficult with it is it currently stands is getting the metadata right and thats mostly lack f documentation.
* Improves robustness of open source tooling for SPIR-V
* Single place for toolchain - People don't need to knit repositories together from multiple locations
* Compatibility between LLVM and SPIR-V - As SPIR-V is integrated it will always track top of tree
These are advantages of having an LLVM IR to SPIR-V translator in tree,
but you get these same advantages no matter what type of translator it is
(e.g. direct LLVM IR to SPIR-V or GlobalISel SPIR-V backend).
* We can create a target triple to subset what dialect of SPIR-V we are targeting
* Using the aforementioned triple we can guide optimisations that take target information
Defining a triple does not require a backend.
* Challenges of implementing SPIR-V backend can influence LLVM backend development, to improve LLVM usability by less conventional targets
SPIR-V isn't just unconventional, it's also a higher-level language than
all the other targets, which are all closer to assembly languages.
* Benefits LLVM by improving support for GPU code generation specifically
I agree with this.
I'd also like to touch specifically on a point that I believe was originally made by Tom.
If the initial implementation of the SPIR-V backend went straight for GlobalISel and only GlobalISel then we would remove the need to worry about SelectionDAG and would remove some of the complexity from the translation step.
While I think GlobalISel would be better than SelectionDAG it still is not
a good fit for a language like SPIR-V. The main problem with both GlobalISel
and SelectionDAG is that you are taking a high-level IR (LLVM IR), translating
it to an low level, assembly-like IR (MachineInstr) and then translating it back to a
high-level IR (SPIR-V). From a technical perspective, this is a much inferior
solution than generating SPIR-V from LLVM IR directly, because you will be losing
information in the translation that will be very difficult, if not impossible, to
recover. It's also much more work than a direct translation to SPIR-V, so you
will be investing extra engineering effort in order to generate worse SPIR-V.
So as a proposal, could I suggest the following next steps?
1) Add a dummy SPIR-V target machine to llvm, replete with target triple
2) Implement an experimental backend making use of globalisel to target SPIR-V code generation
3) Add tests to verify correct execution
Moving forward, the plan would be to develop this into a fully featured and complete backend, with a complete set of tests, but targeting GlobalISel exclusively.
As I said before, I disagree with this approach. I don't think doing
a GlobalIsel based SPIR-V backend is a good use of engineering resources
nor will it produce the best quality of code.
I think you should re-evaluate your goals and decide, which of your goals
can be met by having an in-tree solution (no matter what that solution is
direct translator, GlobalISel backend or something else), and which of your
goals are met by having a GlobalISel-based backend. I think it's important
to separate those two ideas, because my observation is that the reason people
favor doing a GlobalISel or SelectionDAG based backend is because it is the
easiest way to get something in tree, and not because it is the best technical
solution, which is a not a good reason to make this kind of decision.
>From past discussions, one of the main reasons some LLVM developers did not want
a direct LLVM IR to SPIR-V translator in tree is that it would essentially
be introducing a second legalization framework (or third now that we have
GlobalIsel), which would place an increased maintenance burden on the community.
There wasn't a unanimous objection from the community, however, and I think
there is enough interest in this project that we could come up with some
kind of solution for an in-tree direct LLVM IR translator. However, it's
really hard to argue for a big change like this without any code or existing
user base to show the community how the benefits of this outweigh the costs.
I think a direct LLVM IR to SPIR-V translator is the best technical solution,
this is why my recommendation is to start by taking the existing
code that implements a direct LLVM IR to SPIR-V translator and develop it
as its own out-of-tree project, and by out-of-tree I mean a complete separate
project from LLVM not just a fork of it. Having an out-of-tree project
will allow you to improve the code and build up a community, without getting
bogged down by lengthy mailing list discussions or trying to integrate
major changes to core LLVM infrastructure in order to accommodate your
Once you have a good solution with a strong userbase, I think you will be in
a much better position to work with the community to come up with a solution
to integrate your translator into the official tree.
-------------- next part --------------
An HTML attachment was scrubbed...
More information about the llvm-dev