Closed Drakim closed 4 years ago
I don't understand that else
case. If the thing only exists at compile-time, how can there be two branches?
For example, let's say you have two clever integer division methods using bitwise logic. One of them is faster than the other but only works if you have a positive integer, while the other one is a tad slower but can take any integer, positive or negative. You could then use a "hint" which conditionally checks the integer, so that the slower division method is used whenever the compiler is unsure of the sign of the integer, while the faster division method is used when the compiler is certain it's holding a positive integer.
Without the hint functionality, you'd be forced to only use the slower division method for all inputs, or you'd be forced to have a runtime branch to pick one or the other (or use a macro, but then it only works on constant integers, not compiler-deduced integers).
Is there no current way to achieve this by creating an abstract over your js.lib.Float64Array ?
If not then could conditional compilation be extended to work with more complex patterns like structure matching and your use cases, certainly a # would be clearer for users reading code, just hint seems to mix normal code with compiler code.
This is interesting, but I don't think the solution is normal haxe code. I this case, what it looks like you want is:
if (@:compileTime x==0) ...
The 'if' would only be true if it was certain at compile time. This would be nice for inline functions:
inline function idiv(num:Int,denom:Int) {
if ( @compileTime denom & (denom-1) == 0 )
// do bit shift
else
// do long way
}
But it also looks like an optimization you are after here is based on not assigning new array values to 0 on certain targets. This could be done as a macro or another compiler pass without the need for annotation.
Is there no current way to achieve this by creating an abstract over your js.lib.Float64Array ?
I'm fairly convinced this is utterly impossible, the abstract stuff is simply resolved at the wrong time in the compilation process to do anything useful here. If you have some crafty idea on how it could be done, I'd love to hear it.
If not then could conditional compilation be extended to work with more complex patterns like structure matching and your use cases, certainly a # would be clearer for users reading code, just hint seems to mix normal code with compiler code.
I agree, I don't really want there to be a "hint()" conditional exactly like I've suggested, honestly I don't know what would be the most fitting way of implementing it syntax wise, but I felt my proposal would be hard to understand if I didn't at the very least suggest something, as I would just be talking about a vague problem and nothing else.
But it also looks like an optimization you are after here is based on not assigning new array values to 0 on certain targets. This could be done as a macro or another compiler pass without the need for annotation.
Not assigning 0 to zero initialized memory is just one of the several use cases I have in mind. However, not even that can be solved by a macro, as a macro would only be able to do it with constant identifiers like = 55, it wouldn't work with "compiler deduced values" like the examples in my proposal.
But I'm curious about this "another compiler pass" you are talking about. What exactly is that, or are you talking about something theoretical?
If I'm reading this right, this feature is similar to if constexpr
in C++?
From the title I initially thought you were going to suggest hints such as "likely" branches, which can help C(++) compilers to optimise branching code.
If I'm reading this right, this feature is similar to if constexpr in C++?
I only have skin-deep knowledge of C++ so I couldn't say. But in layman's terms, I simply want to be able to tell the compiler "If you are absolutely certain that \<condition> then do \<fast option> otherwise fall back to \<safe option>".
From the title I initially thought you were going to suggest hints such as "likely" branches, which can help C(++) compilers to optimise branching code.
It's more like helping the compiler pick between safe and unsafe code. Like removing a bounds check if the compiler can be 100% certain the index won't go above the bounds.
One example would be a theoretical paintPixel(color:Int) method. When invoked, it should paint a pixel upon a bitmap, but while doing so it should account for the alpha channel of the new pixel, so if alpha is 50% then the new pixel should be 50/50 blended with what's already there. Now, we want to optimize this so that if the alpha is completely opaque then the new color simply overwrites the old one without any unnecessary color blending mathematics.
In today's Haxe, we can solve this in a few ways, but they all have downsides:
The programmer could be given a paintPixel() and paintOpaquePixel() method and be asked to manually keep track of which one at all times. Obviously not very programmer-friendly.
A runtime check could pick between paintPixel() and paintOpaquePixel() based on the alpha value, but such a conditional branch might end up being more expensive than what we save in the first place. In cases where the compiler can be certain of a value, it can DCE remove that conditional branch, but if it's uncertain of the alpha channel, it will leave the conditional there to check.
A macro could pick between paintPixel() and paintOpaquePixel() if the macro sees that the provided color value has a opaque alpha channel. This only works for inline and constant integer values, if there is even one layer of abstraction or indirection, even a trivial one, the macro will see a variable identifier and always pick the slowest option.
Honestly after much thinking and soul-searching I don't think I would vote in favor of my own proposal. While it does attempt to solve a very real problem I'm facing, my I can plainly see that my proposed solution is hacky and very "glued on", and wouldn't fit naturally into how the Haxe compiler does things. So I'm not putting this proposal up for a vote until something better can be figured out.
If somebody does have any ideas for how it could be implemented more smoothly, please leave a comment.
Closing this for now
My proposal for a hint-conditional for the Haxe. I am not very confident in my suggested solution, but this is a genuine issue I've encountered and this is the best way I have of presenting it. Very open to alternative ways of thinking about the issue and ways to solve it.
Rendered version