_______________________________________________
LLVM Developers mailing list
llvm...@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-dev
Thanks for taking the initiative to work on this. A well supported LLVM IR to SPIR-V
transformation layer is something that could be very useful.
> SPIRV-LLVM’s SPIRV support is not a real backend and does not live in /lib/Target/SPIRV. This has been solved, SPIRV is now a proper target(s). I have not copied the tests across yet, and they will need to be updated in light of the changes made/being made below.
> It only support’s the OpenCL “flavour” of SPIRV, but not the Vulkan. I plan on eventually supporting this but its priority is less than that of mainline integration.
> Intrinsics (for both Core and OpenCL extension instructions, Vulkan to follow) are done through C++ "Itanium with extensions” mangling. I plan to convert these to a table-gen format and cull the associated mangling code..
> Likewise the instruction format is currently done through a home-brew table format, which I am in the process of converting to table-gen. The core instructions are almost complete, but I haven’t started on the OpenCL instructions.
> As noted in the talk the textual representation is different from the the reference implementation. I see no advantage of the current format over the reference implementation’s format, infact theirs is much easier to read, This is a low priority.
> The instruction table-gen tables contain a significant number of critical non-instruction tables (there are no registers) and therefore a proper table-gen backend needs to be written to accomodate for this. Required.
> There are some LLVM “infrastructure” things (TargetInfo, MCTargetDesc) that I have stubs in order to get LLVM to compile, I have no idea what I’m doing and those were mostly adapted from Sparc and RISCV. Due to the lack of a Dyld and the fact that SPIR-V is intermediate format, there is no point of a jit, Simple optimisations (CSE,DCE, some very simple inlining) would be nice to have, as would DebugInfo support.
>
> The code is available at my GitHub:
> SPIRV backend https://github.com/thewilsonator/llvm-target-spirv
> LLVM https://github.com/thewilsonator/llvm/tree/compute
> should you want to inspect/offer advice.
>
> I am very busy until about July, but I just want to put this out here to gather interest / feedback / contributors.
>
First of all you may want to review the thread from a few years ago about
putting a SPIR-V target into LLVM:
http://llvm.1065342.n5.nabble.com/RFC-Proposal-for-Adding-SPIRV-Target-td82552.html
The fact that the SPIR-V target translates LLVM IR to SPIR-V directly and
does not use SelectionDAG/MachineInstrs or any of the standard lowering
mechanism is a strong case against having it in lib/Target. There are
two solutions for this: have the code live outside of lib/Target or as an
out-of-tree project(maybe as part of SPIRV-Tools[1]) or rewrite it to use
the standard lowering mechanism of LLVM.
In my opinion, doing LLVM IR->SPIR-V directly is a better option than
trying to convert it to a proper LLVM target. SPIR-V is too high level
to be able to gain any advantage from using LLVM's standard lowering
mechanism.
You will lose a lot of the type information going through the
SelectionDAG/MachineInstr layers, which is a major disadvantage. Also,
since almost everything is legal in SPIR-V, you won't be getting the
same kind of advantages from it as other targets.
SPIR-V and LLVM IR are actually fairly similar in terms of what level of the
compiler stack the were designed for, so I think doing a simple
LLVM IR -> SPIR-V conversion will be the easiest and give you the best
results in the the end.
Also, if you are able to integrate it into SPIR-V Tools you will be able
to re-use the existing SPIR-V in memory representation and the
reader/writer APIs.
I realize that having a separate library will make this more difficult to
integrate into clang, but there are other targets that use external tools
for linking/assembling so, you may be able to find a way to write a SPIR-V
driver for clang that called out to this external tool for the
LLVM IR -> SPIR-V phase.
-Tom
[1] https://github.com/KhronosGroup/SPIRV-Tools
> Thanks,
> Nicholas Wilson
On 1 May 2017, at 11:53 pm, Tom Stellard via llvm-dev <llvm...@lists.llvm.org> wrote:
> First of all you may want to review the thread from a few years ago about putting a SPIR-V target into LLVM:
> http://llvm.1065342.n5.nabble.com/RFC-Proposal-for-Adding-SPIRV-Target-td82552.html
Thanks I will take a look.
> The fact that the SPIR-V target translates LLVM IR to SPIR-V directly and > does not use SelectionDAG/MachineInstrs or any of the standard lowering > mechanism is a strong case against having it in lib/Target.
Can you even use tablegen as a not target for generating binary format descriptions and intrinsics (serious question)? I think it will require a custom tablegen backend anyway though. One of the primary reasons for being a target is that we can have intrinsics that map directly to core and OpenCL/Vulkan extension instructions, as opposed to the mangling hacks used at the moment, which hurt use by anyone who can’t mangle C++ and windows users because it doesn’t make ANY sense to mangle some stuff as Itanuinm and some stuff as MS.
I am in the process of trying to make it “more traditional” where possible and it makes sense to do so, but I do not fully understand the backend pipeline and am just trying to express the intrinsics and binary format with tablegen at the moment. Regardless of the actual transformation pipeline used I think it should go in target for the advantages stated above, and the one that I missed was, it has its own target triples! Also IIRC the Mill CPUs will/(do?) only use one or two of the backend passes and I can’t imagine them not being considered targets.
>There are > two solutions for this: have the code live outside of lib/Target or as an > out-of-tree project(maybe as part of SPIRV-Tools[1]) or rewrite it to use > the standard lowering mechanism of LLVM.
The first loses the advantages of being a target, the second loses that and the advantages of more eyes of LLVM devs AND staying in sync with the rest of the codebase, not to mention releases! And I can’t see any advantages gained from either of those two possibilities.
>In my opinion, doing LLVM IR->SPIR-V directly is a better option than
>trying to convert it to a proper LLVM target. SPIR-V is too high level
>to be able to gain any advantage from using LLVM's standard lowering
>mechanism.
>
>You will lose a lot of the type information going through the
>SelectionDAG/MachineInstr layers, which is a major disadvantage. Also,
>since almost everything is legal in SPIR-V, you won't be getting the
>same kind of advantages from it as other targets.
>
>SPIR-V and LLVM IR are actually fairly similar in terms of what level of the
>compiler stack the were designed for, so I think doing a simple
>LLVM IR -> SPIR-V conversion will be the easiest and give you the best
>results in the the end.
Perhaps, I do not understand the backend pipeline, but that is entirely orthogonal to targethood.
>Also, if you are able to integrate it into SPIR-V Tools you will be able
>to re-use the existing SPIR-V in memory representation and the
>reader/writer APIs.
The in memory representation is already there (inherited from SPIRV-LLVM) and will be refined once the tablegen work is complete, i.e. redundant code removed and integration with the tables. >I realize that having a separate library will make this more difficult to
>integrate into clang, but there are other targets that use external tools
>for linking/assembling so, you may be able to find a way to write a SPIR-V
>driver for clang that called out to this external tool for the
>LLVM IR -> SPIR-V phase.
An external library looks to get the worst of all worlds. I have no interest in clang, as my work is for LDC. The external library approach would require me writing a driver for LDC and then someone else writing a driver for clang, duplicating both code AND effort/bug fixes across multiple projects. There is already enough to do w.r.t metadata for the producer without having to alter their compilation pipeline as well. I plan to reduce the dependance on metadata as much as possible, but still.
Nic
> On 2 May 2017, at 8:48 am, Tom Stellard <tste...@redhat.com> wrote:
> You would probably need to write a new tablegen backend to generate
> instruction tables that would be used outside of LLVM.
I think I need to write one anyway because I need to generate lots of tables other than the instruction table (there are no registers and therefore no register table), at least one for each subsection of section 3 of the spec and then some. Wether or not it is inside or outside of LLVM is irrelevant. What is, is that I’m not sure that the same can be said for intrinsics, which will enable the removal of the mangling hacks.
>> I am in the process of trying to make it “more traditional” where possible and it makes sense to do so, but I do not fully understand the backend pipeline and am just trying to express the intrinsics and binary format with tablegen at the moment. Regardless of the actual transformation pipeline used I think it should go in target for the advantages stated above, and the one that I missed was, it has its own target triples! Also IIRC the Mill CPUs will/(do?) only use one or two of the backend passes and I can’t imagine them not being considered targets.
>>
>
> A "more traditional" backend is more than just using tablegen to generate
> the instruction definitions. It means implementing an instruction selector
> and using SelectionDAG and MachineInstrs. What I'm saying is that
> SPIR-V is not a good fit for the existing infrastructure, so I think
> it would be good to consider alternatives before going to far down that path.
Indeed, tablegen is the first step. I intend to incorporate as much of the standard pipeline as makes sense (e.g. no register allocation because there are no registers). As I have said I know very little about the backend pipeline so I can’t comment a whole lot. Is SelectionDAG matching pieces of the IR and choosing instruction from them? Because I definitely want to do that, if it is a thing (the tablegen files are currently dag free and do not inherit from `Instruction` because I do not understand that process, I am merely transcribing the spec), any information is welcome.
> I think we may be using different definitions of driver in this case.
> From the perspective of LDC, it doesn't seem like it would matter
> much if LLVM IR -> SPIR-V were in the LLVM tree or outside of it.
> In both cases you have a library that takes LLVM IR as input and
> produces SPIR-V as output.
>
> -Tom
My point is that it is duplicated effort (i.e. one for LDC, one for clang and so on), and is redundant if it is a proper target. I am willing to put in the effort to allay concerns regarding the pipelining and legalisation, but I am steadfast in my opinion that it should be a target unless the benefits of not being a target can be shown to outweigh those of being a target.
Right, what I was trying to say is that there are more benefits from
having this not be a target than there is from having it be a target.
What you are proposing is a lot of work, and even if it does help to
avoid some duplicate work (which to be honest, I still don't quite
understand what duplication there would be if it weren't a target),
I don't think that is enough to justify the effort required.
-Tom
>Hi,
>Right, what I was trying to say is that there are more benefits from
Please enumerate them, I have seen none posted so far . The implied “it is what all the the other backends do” w.r.t ISel/MC is at best(worst?) an implementation detail, and I’m still not quite sure why Chandler was so adamant about that. He seemed to imply that generating straight from the IR (as opposed to post legalisation?) introduces a direct dependance in the IR that the rest of LLVM would then be required to not break? I agree that the SPIRV backend should be insulated from changes the IR, although I’m not sure how to achieve that property. I’m also not sure how much, if at all, it would be susceptible to that to begin with. Deletions of instructions/attributes would obviously cause breakage and additions may cause unhandled and/or invalid combinations. I still don’t get the severity if this though, insight appreciated.
So there are really two questions here:
1. Should targets be required to use SelectionDAG/GlobalISEL ?
2. Should SPIR-V use SelectionDAG/GlobalISel?
In my opinion, regardless of the answer to question #1, the answer
to question #2 is no, SPIR-V should not use SelectionDAG/GlobalISel.
I touched on this before in previous emails, but the main problem is that
SelectionDAG (and GlobalISel to a lesser extent) plus the whole MachineInstr
layer is a much lower-level representation than SPIR-V, so you will
need to do a lot of extra work and/or modifications to existing
infrastructure in order to get a working target, and even then
you may be limited to emitting poor quality SPIR-V that other
backends will have a hard time optimizing.
With all this work, what advantages are you getting? If the
only reason to do it this way is so you can use intrinsics,
or TargetLibraryInfo, or easier integration with other tools,
I think it would be better to try to save the effort and try
to solve those problems in some other way.
LLVM IR -> SPIR-V directly will give you better code, lower compile
times. It will be more simple and easier to maintain, and you will
be able to re-use existing SPIR-V parsers/writers that exist
in SPIRV-Tools.
This goes back to something I mentioned in my original email, but
I really think the best thing to do for this project right now is to
keep it separate from LLVM, clean up the code, and try to get people
using it. It's going to be much easier to get this upstream in LLVM or
even convince people that the answer to question #1 should be 'no' if we
have a code base that is mature, well supported, and has a healthy
userbase.
>
>>What you are proposing is a lot of work, and even if it does help to
>>avoid some duplicate work (which to be honest, I still don't quite
>>understand what duplication there would be if it weren't a target),
>>I don't think that is enough to justify the effort required.
>
> My point is that (modulo metadata, which I am still investigating better alternatives, and calling conventions) if SPIRV is a target, then a producer need not change their compilation pipeline /at all/ to target SPIRV. There should be no effort required, it would come as a property of being a target. I think we are confusing each other again :(
>
> Leaving that aside for a moment, there are a number of advantages/requirements that, correct me if I’m wrong, would be impossible without a proper target.
>
> * Most critically: Intrinsics. I am almost certain that you would not accept the current mangling hacks, and if I am to support windows neither can I. Any solution would therefore need to be able to register intrinsics and I believe this is impossible without a target (and even if it is, it makes less sense than a target that doesn’t use ISel/MC). Not being able to use intrinsics is a complete deal breaker.
>
You don't need to register intrinsics to be able to use them, and
it's also possible to register them without a backend, but this has not
been done before.
> *Basic optimisations (basic CSE,DCE,inlining): requires a TargetLibraryInfoImpl(?) which I believe requires a target. While not strictly necessary it would improve the readability of the resulting IR/SPIRV. All of the more complex optimisations would be done “post ingestion” of the SPIRV and with a different target triple so are unaffected by any decision made. See my reply to Hongbin for an approach.
You don't need a target for this. TargeLibraryInfo is constructed
based on the triple.
>So there are really two questions here:
> This goes back to something I mentioned in my original email, but
> I really think the best thing to do for this project right now is to
> keep it separate from LLVM, clean up the code, and try to get people
> using it. It's going to be much easier to get this upstream in LLVM
> or
> even convince people that the answer to question #1 should be 'no' if
> we
> have a code base that is mature, well supported, and has a healthy
> userbase.
I think SPIR-V should go into tip LLVM eventually, I think it should not
use SelectionDAG/GlobalISel because it doesn't make sense in my opinion.
But the most important issue is getting LLVM based languages be able to
target SPIR-V.
I think it would be highly beneficial if any SPIR-V target was used to
make external targets in LLVM/Clang work much more nicely. Being blunt -
external targets in LLVM suck, you're forced to patch the source code.
If a SPIR-V target could be used to:
- Allow experimental targets to be discovered outwith the LLVM tree (EG.
the target doesn't have to be in lib/Target)
- Move target triple information into the lib/Target/* folders (or at
least allow a target to register a triple and information about the
target in the target folder)
That'll get us a huge step towards being able to use LLVM with external
targets, and also allow a bunch of developers to use a SPIR-V backend as
if it was in tip LLVM, thus demonstrating its viability for upstream.
Cheers,
-Neil.
-Eli
--
Employee of Qualcomm Innovation Center, Inc.
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project
If type legalization really is required, I think we should at least take using SelectionDAG off the table. At worst I think this should directly jump to using global isel.
-Matt
While in practice most SPIR-V consumers are going to only accept i16/32/64, f/16/32/64 and pointers as the base types, I couldn't actually find anything in the spec that says otherwise. This is particularly relevant for FPGAs that can support arbitrary integers (not sure about their consumers / synthesis tools though). Perhaps I should seek clarification from Khronos and maybe add that as a new capability.
SPIR-V is constrained in the environment specs that consume it -
https://github.com/KhronosGroup/Vulkan-Docs/blob/1.0/doc/specs/vulkan/appendices/spirvenv.txt
for Vulkan 1.0.
Vulkan does not support i8 types (currently), and has optional i16, i64,
f64 types.
SPIR-V as a thing does not have these constraints though, so outwith an
environment (we're losing the usefulness of SPIR-V without being able to
feed it to a Vulkan/OpenCL driver) it can support arbitrary type widths.
Cheers,
- Codeplay Neil.
On 2017-05-09 08:53, Nicholas Wilson via llvm-dev wrote:
> While in practice most SPIR-V consumers are going to only accept
> i16/32/64, f/16/32/64 and pointers as the base types, I couldn't
> actually find anything in the spec that says otherwise. This is
> particularly relevant for FPGAs that can support arbitrary integers
> (not sure about their consumers / synthesis tools though). Perhaps I
> should seek clarification from Khronos and maybe add that as a new
> capability.
>
> -------------------------
>
> FROM: Friedman, Eli <efri...@codeaurora.org>
> SENT: Tuesday, 9 May 2017 1:31:58 AM
> TO: tste...@redhat.com; Nicholas Wilson
> CC: llvm...@lists.llvm.org
> SUBJECT: Re: [llvm-dev] [SPIR-V] SPIR-V in LLVM
Indeed this is great news!
>
> Thanks! I want to get this in so I don’t have to maintain a separate version for my work on LDC, the LLVM D Compiler.
>
I want to mirror this comment, the fact that if I want use SPIR-V I
need to versions of my compiler made me just drop the idea of adding
support for it.
>> Actually one of the topics in the OpenCL BoF during EuroLLVM is to discuss about whether we should put SPIRV as one of the LLVM backends. Some of the guys in ARM and Codeplay participate that BoF.
>
> Great, any help (especially by those who actually know what they doing when it come to LLVM backends, i.e. not me ;) ) is greatly appreciated. Co-ordination will be the key to getting this done in a reasonable timeframe.
>
>> Although there is no concrete conclusion, I think your work would be a valuable materials for folks in both Khronos and LLVM to determine whether put SPIRV under lib/Target.
>
> I think SPIRV should be a proper target (and therefore live in $ROOT/lib/Target) for a number of reasons.
>
> 1) Logically it is a target: it produces binary code and is the last stage in the compilation pipeline.
>
> 2) it makes it easier for consumers (LDC, clang) to set up the build system / CMake as they only need specify they wish to target SPIRV rather than specify they want to link to libLLVMSPIRV.a with some CMake hackery. This was part of the reason for making it a target, as I was unable to get LDC’s build system to pull in the required library from Khronos’ SPIRV-LLVM.
>
> 3) it will integrate much better into consumers existing consumers compilation pipelines, as for LDC, there were, until I made it a target, some rather ugly hacks to fit it in with the rest of the codebase that was setup to just pass the IR to a backend.
>
> 4) if its a target then it will stay up to date with LLVM and not stagnate fall many releases behind.
>
> There are probably some others I am missing.
While I can't really comment on where in the code it should live. But
with my frontend developer hat I'll like say it should be treated as
much as possible as a target, at least as long as I can use the C-API
to get the C binary from a module that I have generated I am happy.
Cheers, Jakob.
Philip
In light of how thorny this request has been perceived in the past, I'd
honestly rather just make external targets work _without_ patching LLVM
being a requirement, and then any SPIR-V target (or any other external
LLVM targets too!) can live, mature, and prove its usefulness while
there is an avenue to use vanilla tip LLVM with the SPIR-V target and go
through the normal mechanisms.
Cheers,
-Codeplay Neil.
In the past we also had a C and an LLVM-IR builder-backend (also known
as Cpp backend) which did not use instruction selection. That is,
there are other uses cases for non-SelectionDAG/GlobalISEL backends.
I have no use for the Cpp backend, but a revival of the C backend
could be interesting.
Michael
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.
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.
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
* 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
* 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
* Challenges of implementing SPIR-V backend can influence LLVM backend development, to improve LLVM usability by less conventional targets
* Benefits LLVM by improving support for GPU code generation specifically
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.
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.
Neil
On 21 Jun 2017, at 5:41 am, Neil Hickey <Neil....@arm.com> wrote: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
* 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
* 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
* Challenges of implementing SPIR-V backend can influence LLVM backend development, to improve LLVM usability by less conventional targets
* Benefits LLVM by improving support for GPU code generation specifically
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.
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
On 21 Jun 2017, at 8:20 am, Tom Stellard <tste...@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.
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.
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.
P.S.
The OpenCL over Vulkan work I mentioned is not yet open sourced but I believe the intention is to do so "soon".
_______________________________________________
Looking at the APIs it should be possible to just implement TargetMachine (but not LLVMTargetMachine which is only meant for lib/CodeGen targets) and register that with the target registry.
Note that I have never actually done so, so I may be missing some things. It also seems the last non-CodeGen target in public tree was the cpp target which was removed a few years ago so hopefully the API has not regressed without testing.
Still I think it would be a good idea to at least evaluate/try this as I've got the feeling lib/CodeGen may get more in the way than being helpful in this case...
- Matthias
Yep, as I recall, the C backend works this way too. The C backend is
also not in-tree any more, but there are some fairly-recent
forward-ports on github (e.g.
https://github.com/JuliaComputing/llvm-cbe/tree/master/lib/Target/CBackend).
>
> Note that I have never actually done so, so I may be missing some things. It also seems the last non-CodeGen target in public tree was the cpp target which was removed a few years ago so hopefully the API has not regressed without testing.
>
> Still I think it would be a good idea to at least evaluate/try this as I've got the feeling lib/CodeGen may get more in the way than being helpful in this case...
I agree. If there's some capability from CodeGen that you specifically
wanted to take advantage of, please elaborate.
-Hal
--
Hal Finkel
Lead, Compiler Technology and Programming Languages
Leadership Computing Facility
Argonne National Laboratory
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
I also agree that lib/CodeGen would hinder rather than help us (which is
why I stuck with using a few ModulePass's instead!)
- Codeplay Neil.
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 Jul 17, 2017, at 6:55 AM, Neil Henning via llvm-dev <llvm...@lists.llvm.org> wrote: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).
* Bool should stay as an i1 instead of being moved between i8 <-> i1
continuously.
* We want structs to be the return type instead of using sret.
* We want structs to be passed by value instead of byval pointers.
* We want our pointer types to all be in the non-integral address space.
* We want alloca to be in a non-0 address space.
All of the above is fixable by having an actual SPIR-V target triple.
I think there was push-back previously on just adding a triple because
many of us still want a real SPIR-V target in LLVM. If we could add a
triple now and then continue the backend discussions after that would be
helpful for us!
Cheers,
-Codeplay Neil.
_______________________________________________
Yup - one thing to note is that for the clspv project the only target we
care about is Vulkan SPIR-V. It's quite a bit more difficult to target
Vulkan SPIR-V because there are a ton of extra restrictions on top of
what OpenCL SPIR-V has.
For us, doing a clean-room implementation on tip of tree with no patches
to Clang/LLVM was a requirement.
Cheers,
-Codeplay Neil.
Nice, congratulations!
Best,
Tobias
Hi there,
any news on coordination? We have customers who are successfully using
Mesa in their products, and that are now asking about OpenCL.
My current impression is that easiest would be to do what Tom suggested
before, and only re-evaluate inclusion in LLVM proper once things are
more mature.
One path for me would be to take Khronos' or Nic's work and convert it
into something that can be packaged by Linux distributions (so it needs
to work with the latest LLVM release, with no patches).
Another path would be to extend clspv to cover the whole of OpenCL, but
I don't know if Codeplay/Google are interested in taking such patches.
Is here interest in coordinating efforts?
Regards,
Tomeu
What hardware are they using? Note that SPIR-V is not required to run
mesa's OpenCL on AMD hardware.
> My current impression is that easiest would be to do what Tom suggested
> before, and only re-evaluate inclusion in LLVM proper once things are
> more mature.
>
> One path for me would be to take Khronos' or Nic's work and convert it
> into something that can be packaged by Linux distributions (so it needs
> to work with the latest LLVM release, with no patches).
>
> Another path would be to extend clspv to cover the whole of OpenCL, but
> I don't know if Codeplay/Google are interested in taking such patches.
>
> Is here interest in coordinating efforts?
>
I recommend using clspv, in addition to having a clang-based driver
for compiling OpenCL C, it exposes the LLVM IR -> SPIR-V passes via
a header, so it should be easy to integrate it into existing
compilation pipelines.
It also is easy to package as it is already a stand-alone project.
-Tom
We have seen most direct interest on Adreno.
>> My current impression is that easiest would be to do what Tom suggested
>> before, and only re-evaluate inclusion in LLVM proper once things are
>> more mature.
>>
>> One path for me would be to take Khronos' or Nic's work and convert it
>> into something that can be packaged by Linux distributions (so it needs
>> to work with the latest LLVM release, with no patches).
>>
>> Another path would be to extend clspv to cover the whole of OpenCL, but
>> I don't know if Codeplay/Google are interested in taking such patches.
>>
>> Is here interest in coordinating efforts?
>>
>
> I recommend using clspv, in addition to having a clang-based driver
> for compiling OpenCL C, it exposes the LLVM IR -> SPIR-V passes via
> a header, so it should be easy to integrate it into existing
> compilation pipelines.
>
> It also is easy to package as it is already a stand-alone project.
Noted, thanks for the recommendation.
Finally took some time to find out how hard would be to put Khronos'
LLVM-SPIRV into a shape that could be used by Mesa, and it didn't turn
that bad: https://gitlab.collabora.com/tomeu/llvm-spirv
I basically took Khronos' master branch, rewrote history to remove
anything not SPIRV-specific, and applied on top Nic's changes to match
LLVM 6.0. Also borrowed some build system changes from clspv.
>> Another path would be to extend clspv to cover the whole of OpenCL, but
>> I don't know if Codeplay/Google are interested in taking such patches.
Doesn't look like that would be the case:
https://github.com/google/clspv/issues/63
>> Is here interest in coordinating efforts?
>>
>> Regards,
>>
>> Tomeu
>
> Definitely although I’m a bit busy at the moment. I hope you can make it to IWOCL.
Will look at being there. For the moment I'm going to count on using
this fork as a starting point so I can start my work on
Mesa/Clover/Freedreno.
Everybody else is welcome to contribute changes towards making it
suitable for inclusion in LLVM, but I need it to not regress in the
meantime.
Regards,
Tomeu