0

I'm currently considering porting some code that I have from OpenGL/GLSL to Vulkan/SPIR-V, and part of that code generates GLSL at runtime, so I'll have to generate SPIR-V instead. What I'm wondering is how I should relate to optimizations in the generated SPIR-V.

Particularly, I can't really find any information on what kind of expectations I should have on the driver's compiler. Should I expect it to do aggressive optimizations on its own and thus try to keep the SPIR-V code clean and keep as much "original intent" as possible in it for the compiler to look at? Or should I expect it to do fairly simplistic code generation, and try to do as aggressive optimization as possible when generating SPIR-V?

Just perhaps for particular examples, which of these kinds of things should I do when generating SPIR-V?

  • Eliminate redundant stores-then-loads of local variables?
  • Loop unrolling or peeling / function inlining?
  • Constant propagation / common subexpression elimination?
  • Keep as much as possible in SSA form instead of loads and stores to local variables?

My very naïve expectation is that the compiler will want to adapt its optimization passes to the particulars of the hardware and that I should therefore try and keep my SPIR-V code clean and high-level, where such things as loop unrolling would destroy information and keep the driver from deciding on its own unrolling, but I'm really just guessing without any real information.

Dolda2000
  • 25,216
  • 4
  • 51
  • 92
  • "*so I'll have to generate SPIR-V instead*" Is there some problem with using the existing GLSL-to-SPIR-V compiler? – Nicol Bolas May 01 '17 at 00:25
  • @NicolBolas: Yes, the fact that I'm generating the code at runtime, so I wouldn't want to rely on external tools. – Dolda2000 May 01 '17 at 00:26
  • Are you unable to include the compiler in your code at runtime? Because it comes in a library form too. – Nicol Bolas May 01 '17 at 00:26
  • @NicolBolas: For one thing, my code is in Java, and I don't think there's an existing JNI wrapper, at least. Also, I do have all the information available to generate SPIR-V directly, so since it's possible to keep the code clean of external dependencies, I don't see why not. – Dolda2000 May 01 '17 at 00:28
  • I would suggest looking at the quality of the SPIR-V code generated by glslang. If it does lots of complex constant expression folding and such, dead-code elimination, loop unrolling, and so forth, then your code should do likewise. If it doesn't, then you probably don't need to either. – Nicol Bolas May 01 '17 at 00:36
  • @NicolBolas: Actually, one of the reasons I asked this question was because I found a number of places on the web where people complained that glslang wasn't doing enough optimization, but I couldn't tell whether glslang is simply underdeveloped, or if these people were looking for optimizations that it shouldn't do. – Dolda2000 May 01 '17 at 00:38
  • "Shouldn't" is ultimately going to be based on the quality of the implementation *consuming* SPIR-V, so on that score your question is essentially unanswerable. Since lots of people use glslang, it stands to reason that implementers will build their SPIR-V optimizing code to handle the kinds of stuff it emits. – Nicol Bolas May 01 '17 at 01:10
  • 1
    @NicolBolas: Well, that is why I was hoping for an answer from someone who known what the implementations actually do. – Dolda2000 May 01 '17 at 01:11

1 Answers1

3

You can generally expect the runtime compiler (in the driver, consumes SPIR-V) to do a lot of standard optimizations. In many implementations it's the same backend as the one in the GL driver, and does most of the same optimizations. But the process of parsing the SPIR-V and translating it to the driver's internal representation is going to be faster if there's not a lot of unnecessary junk in there. So if you're writing your own generator, it's worth putting a bit of effort into generating "clean" SPIR-V.

You might take a look at shaderc, which is meant to be an easy-to-integrate library that uses glslang for GLSL-to-SPIR-V translation, and also can run spirv-opt to do some of the optimizations you named. As spirv-opt gets additional optimizations (under active development) shaderc will pick those up.

Jesse Hall
  • 6,441
  • 23
  • 29