Remove casts and boxing for dynamic math#18849
Conversation
|
With this patch, i see only small differences in that nightly benchmark between static and dynamic now, typically something like this: |
How was it before? |
|
In general I have to closer look into the code! I know, we cannot use the IDefLink class here, as the operands are SExpression not ALink, so we need a lot of if then else. But the current code just looking for Sort.DEF is fine (as simple). The IDefLink is more needed for the inverse case (links that make an expression at end). Maybe we find a better solution for the def rewriting, there is room for improvement. As a fisrt step this looks good! |
Before typically like a 15% difference.
These E-nodes are different than that case. In this case we just want to not generate the casts and boxing, and instead take the types and expected return values as-is and pass to invokedynamic, thats what the change does. If we want to reduce if-then-else (this is pre-existing, from the static case, i am afraid to heavily refactor it here), then the easiest way to do that, would be to refactor nodes to have the same behavior. For example shifts have different promotion than additions, but they are all bundled in one EBinary.
I don't really see it as rewriting the node, as it doesnt do that. It just inhibits the explicit casts and boxing. For these cases it can be done on return value and arguments without anything heavy. Some cases are still to be improved. For example compound assignments in EChain. But see my comment, i think thats too scary to optimize right now as i see bugs looking at it, we need tons of tests for those compound assignments first... |
|
|
||
| /** Writes a dynamic binary instruction: returnType, lhs, and rhs can be different */ | ||
| public void writeDynamicBinaryInstruction(Location location, Type returnType, Type lhs, Type rhs, Operation operation) { | ||
| org.objectweb.asm.Type descriptor = org.objectweb.asm.Type.getMethodType(returnType.type, lhs.type, rhs.type); |
There was a problem hiding this comment.
I would change the name here to somthing like methodType.
In addition: This looks like messy code duplication. Maybe just use a simple wrapper method for the invokeDynamic, to not copy paste each line?
There was a problem hiding this comment.
Its not easy to refactor without it being trappy. Remember, not all of these are 'binary' instructions. Some are shifts. so each guy needs to set at least 2 things, what type he is and what instruction.
To me, we simply have to stop categorizing all of these as the same thing. They are very different operators. It causes all the if-then-else.
There was a problem hiding this comment.
Also the Operation enum we have is currently not helpful here to address these issues, because it is more of a syntax level thing. It only has one - for example. It does not know about any semantics.
There was a problem hiding this comment.
I don't plan to change this on the issue. Please look at the changes, it used a switch on invokedynamic before this PR. Its not my fault. Lets fix it separate.
There was a problem hiding this comment.
OK. It was just a suggestion. UweSays: Switch statements are very non-java like and must die :-)
There was a problem hiding this comment.
I know, i am just exhausted from the slave labor on this one already. I did try to do the refactorings you suggested, to try to make it cleaner and also remove string constants and stuff. But it got messy quickly (the root problem, Operator is syntax oriented).
I'm not gonna leave it alone. I just want to iterate here. There is a lot to followup with. For example return values of unary operators, compound assignments, all other cases where we do inefficient casts.
|
I'm +1 on these changes. Great use of the extra type information. |
|
+1 also from my side! |
|
I'm gonna followup by splitting up that massive DefOperations test too. We should have it for each operator. Some stuff is still missing like compound assignment tests and there are bugs in those for def!!!! |
#18847 gave us the ability to optimize this stuff when we know types, but we don't use it yet.
This patch removes the manual boxing/promotion/conversion and just hands over what we have for the binary math and comparison operators. For example in the script in the nightly benchmark:
We remove two calls to Double.valueOf: one because we know the
_scoreis a double argument, we don't need to box it, and another because we know the math function returns a double.Instead of:
We do:
I added lots of tests to DefOptimizationTests for parameter and return values, and also correctness tests to DefOperationsTests for when we have partial types. I also found and fixed some bugs along the way (e.g. EComp did not work correctly when only one operand was
def, it only looked at the RHS).