-
Notifications
You must be signed in to change notification settings - Fork 0
Description
The SPIRV backend doesn't really care that a value might be loaded and immediately stored to another variable.
The idea to solve it is to implement a caching system for every variable, such that we know if a OpLoad is out of date or not, and if it isn't, we can completely omit the extra load. Any OpStore to that variable would invalidate the load.
But perhaps even better would be to avoid doing OpStore for values that just get loaded back again. This would be possible by, when assigning a value to a variable that is function-local, the store is emitted and instead the symbol for that variable is replaced with the result of the value we would otherwise store.
%4 = OpVariable %ptr_int Function
%5 = OpIAdd %int %1 %2
OpStore %5 %4
%6 = OpLoad %int %4
%7 = OpIMul %int %6 %2
Would become:
%4 = OpIAdd %int %1 %2
%5 = OpIMul %int %4 %2
Thus eliminating the OpVariable, OpStore and OpLoad completely for this quite common pattern. Note that this would become very tricky if the variable is written to differently in a branch, which is why the first stack based method is cleaner to generate, but less effective in practice.
For that case, we'd need to use phi nodes, and only apply this logic on variables that are never passed as pointers to other functions. The optimizer deals with this with the mem2reg pass, but minimizing the work of the optimizer will definitely save on compilation times.