[llvm-dev] [SPIR-V] SPIR-V in LLVM

Neil Henning via llvm-dev llvm-dev at lists.llvm.org
Mon Jul 17 06:55:53 PDT 2017


Hey all,

Code finally got through legal, but the repo is live here 
https://github.com/google/clspv

This codebase is somewhere between alpha/beta as an estimate, but we've 
pushed a 1 million line OpenCL C codebase through it and got fully 
formed Vulkan SPIR-V out the other end.

I did not want to make the mistake of forking LLVM/Clang - so there are 
a bunch of passes in there that are us undoing things that Clang has 
options for (if we had a SPIRV triple).

Most of the meat of the producer is in 
https://github.com/google/clspv/blob/master/lib/SPIRVProducerPass.cpp

Hope this helps aid any decisions by the list.

Cheers,
-Codeplay Neil.

On 2017-06-22 03:08, Tom Stellard via llvm-dev wrote:
> On 06/21/2017 09:18 AM, Neil Hickey wrote:
>> Hi Tom,
>> 
>> I don't disagree, on a technical level, with any of your points. This 
>> is, as you have already pointed out, not the first time we have had 
>> this discussion and so far, two years after these discussions were 
>> first opened we are not any nearer to a solution that makes sense for 
>> all stake holders, hence why I think it prudent to explore other 
>> approaches, approaches that may not be the most efficient engineering 
>> solution, but approaches that allow us to make some kind of forward 
>> progress.
>> 
>> My motivation in this is having a solution that is well integrated 
>> with tooling that the ecosystem already uses and is comfortable with. 
>> Certainly coming from OpenCL C and C++, clang is an often used tool 
>> for compiling, and this already lives within the llvm project, 
>> allowing an option in clang that anyone can add to their compile line, 
>> which seamlessly generates SPIR-V for further consumption by an OpenCL 
>> or Vulkan runtime is, in my mind, the lowest barrier for adoption, and 
>> as such, likely to be the one that gets the most traction.
>> 
>> The barrier to getting the translator integrated into LLVM revolves 
>> around the ties that it creates between the future evolution of 
>> LLVM-IR and SPIR-V, two specifications that are controlled by 
>> different communities, whereas recasting the translator as a backend 
>> removes that tie, or at least forces the LLVM-IR to go through a 
>> lowering/ legalisation step, and also, if it breaks can be more easily 
>> disabled.
>> 
>> Assuming the objective is to keep this in llvm for ease of use by end 
>> users, and we do not want to pursue the full backend approach, there 
>> are a number of other options we could explore.
>> 
>> 1) Allow something like a backend to exist in LLVM, which can be 
>> switched off if it breaks, that allows for these types of translations 
>> between different intermediate languages, but doesn't have the 
>> requirement of going through MachineInstructions, i.e. it isn't really 
>> a backend. This mechanism could also have been used to target 
>> WebAssembly for example, and any other IR/ILs that we would like 
>> LLVM-IR to have a route to going forward.
>> 2) Create a tool, in llvm/tools similar to clang that creates a 
>> library and separate tool to provide the same functionality as the 
>> LLVM<->SPIR-V translator discussed previously. This could be 
>> officially hosted, like clang, if the community felt that appropriate, 
>> and would allow easy integration of the different tools, or being 
>> called as a library, to generate SPIR-V from LLVM.
>> 
> 
> I think these are both possible solutions, but we aren't going to be 
> able
> to know which is best until there is some code to look at and review.
> This is why I suggest moving whatever existing code there is into its 
> own
> public repository while it is cleaned up and improved.  I'm not 
> suggesting
> this as a long term solution, but just for a few months or however long 
> it
> takes to get clean code that builds against trunk, so that people can 
> start
> looking at and reviewing.
> 
> -Tom
> 
>> P.S.
>> 
>> The OpenCL over Vulkan work I mentioned is not yet open sourced but I 
>> believe the intention is to do so "soon".
>> 
>> 
>>> -----Original Message-----
>>> From: Tom Stellard [mailto:tstellar at redhat.com]
>>> Sent: 21 June 2017 01:21
>>> To: Neil Hickey; llvm-dev at lists.llvm.org
>>> Cc: Nicholas Wilson; nd
>>> Subject: Re: [llvm-dev] [SPIR-V] SPIR-V in LLVM
>>> 
>>> 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.
>>>> 
>>> 
>>> Hi Neil,
>>> 
>>> 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 resources.
>>> 
>>>> 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?
>>> 
>>>> 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 
>>> based
>>> backend.
>>> 
>>>>  * 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 translator.
>>> 
>>> 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.
>>> 
>>> -Tom
>>> 
>>> 
>> 
> 
> _______________________________________________
> LLVM Developers mailing list
> llvm-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev



More information about the llvm-dev mailing list