Inlining of constants etc. in generated HLSL

  • OtisInf
  • Topic Author
More
5 years 4 months ago - 5 years 4 months ago #1 by OtisInf Inlining of constants etc. in generated HLSL was created by OtisInf
I was inspecting the HLSL of my shader and I noticed that one line generated relatively a lot of code in the HLSL, which at first looks like unnecessary.

The line (in reshade shader lang)
coc = tex2Dlod(source, float4(texcoord + coordOffset, 0, 0)).r;

The HLSL generated:
#line 358
			float2 _127 = (texcoord + coordOffset);
			const uint _128 = (1);
			const uint _129 = (0);
#line 358
			float _130 = _127[_129];
#line 358
			float _131 = _127[_128];
			const float _132 = (0.00000000);
			const float _133 = (0.00000000);
#line 358
			float4 _134 = float4(_130, _131, _132, _133);
#line 358
			float4 _135 = source.t.SampleLevel(source.s, _134.xy, _134.w);
			const uint _136 = (0);
#line 358
			float _137 = _135[_136];
#line 358
			coc = _137;
Questions:
- Is there a reason why the constants aren't inlined?
- Why are there constants generated for swizzles, aren't these always the same? (so why generate them at this level and not at the global level?)
- The code uses more registers than needed. E.g. _137 is unneeded, as the value can be read directly into the variable 'coc', which is also how the original code is defined. Is this done because there's no analysis how a variable is used ? (i.e. at any cost the operation on the right hand side of an assignment is cached in a local variable to avoid having to re-do the operation later on again ? ).

Analysis of usage patterns is a pain so I don't blame you for not having analysis for this ;), was just interesting to see how 1 line of code results in multiple statements which seem unavoidable: when I rewrote the one line into code which uses float2's as var[0] etc., it resulted in same code or more, so there was little to do to optimize this to have much less statements.

I imagine the d3dcompiler will optimize a lot of this and therefore there's no need to do extra work here, but I don't know whether it indeed does this or not, hence my questions ;)

Thanks in advance!
Last edit: 5 years 4 months ago by OtisInf.

Please Log in or Create an account to join the conversation.

  • crosire
More
5 years 4 months ago - 5 years 4 months ago #2 by crosire Replied by crosire on topic Inlining of constants etc. in generated HLSL

OtisInf wrote: - Is there a reason why the constants aren't inlined?

More complicated code. A constant is a SSA assignment like any other. Inlining them would require an additional step that keeps track of all the SSA IDs that are constants and print them directly instead of printing the SSA ID to the output. Surely possible, but not really worth the effort.

OtisInf wrote: - Why are there constants generated for swizzles, aren't these always the same? (so why generate them at this level and not at the global level?)

This is for compatibility with SPIR-V. It's more optimal to use a component lookup in SPIR-V compared to a swizzle (since there are no single-component swizzle instructions in SPIR-V). As such the compiler front-end converts single-component swizzles to component lookups. And the compiler backend (including the HLSL one) won't know that this was originally a swizzle.
The SPIR-V backend re-uses the same SSA ID for constants of the same value (since SPIR-V does not allow multiple constant definitions with the same value), but the HLSL backend doesn't since I didn't see it worth the effort. So it will just recreate a new constant every time.

OtisInf wrote: - The code uses more registers than needed. E.g. _137 is unneeded, as the value can be read directly into the variable 'coc', which is also how the original code is defined. Is this done because there's no analysis how a variable is used ? (i.e. at any cost the operation on the right hand side of an assignment is cached in a local variable to avoid having to re-do the operation later on again ? ).

The final code won't use more registers. The Microsoft HLSL compiler will resolve all these (as you suspected) and will generate the same code as if it was written inline. Note that the Microsoft compiler internally uses the very same representation (it converts to SSA too), so this should actually simplifies its work.
Last edit: 5 years 4 months ago by crosire.
The following user(s) said Thank You: OtisInf, seri14

Please Log in or Create an account to join the conversation.

  • OtisInf
  • Topic Author
More
5 years 4 months ago - 5 years 4 months ago #3 by OtisInf Replied by OtisInf on topic Inlining of constants etc. in generated HLSL
Thanks for the info! Agreed, the extra work doesn't seem worth it. Had totally forgotten about SSA's (It's been, what... 25 years or so since I last read the Dragon Book (Aoh Sethi Ullman :)) and after reading up about them understand better now why you did it this way :)
Last edit: 5 years 4 months ago by OtisInf.
The following user(s) said Thank You: crosire

Please Log in or Create an account to join the conversation.

  • crosire
More
4 years 2 months ago #4 by crosire Replied by crosire on topic Inlining of constants etc. in generated HLSL
One year later and this is actually implemented now (to reduce the size of the generated code and make it more readable).

Please Log in or Create an account to join the conversation.

We use cookies
We use cookies on our website. Some of them are essential for the operation of the forum. You can decide for yourself whether you want to allow cookies or not. Please note that if you reject them, you may not be able to use all the functionalities of the site.