Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Optimize out casts that must succeed #9928

Open
niloc132 opened this issue Feb 19, 2024 · 0 comments
Open

Optimize out casts that must succeed #9928

niloc132 opened this issue Feb 19, 2024 · 0 comments

Comments

@niloc132
Copy link
Contributor

Following #9917, we should at least optimize away the cast that occurs because of the instanceof operator, as it must succeed.

The simplified generated code today is

o instanceof Foo && null != (foo = (Foo) o))

which compiles out to roughly

instanceOf(o, 100) && null != (foo = (castTo(o, 100)) , o)

(The null check is so that the cast+assignment can be part of the boolean expression that was formerly just an instanceof)

The cast will obviously succeed, and when generating code could be replaced with just an unchecked cast.

Removing the cast will be a minor performance and size improvement here, resulting in output something like

instanceOf(o, 100) && null != (foo = o)

Ideally it would go further and determine that the expression always returns non-null (null instanceof anything is always false). Note that we can't however use the "truthiness" of the value foo in general, since Boolean.FALSE would fail that.

This would probably be implemented in GwtAstBuilder with the rest of the pattern matching instanceof, since it only need happen once.


For plain instanceof checks, this is trickier, but might still be possible. This seems like it would be better expressed as an optimization to perform in the optimizedJavaOneTime step, so that it can interact with other optimizations and simplify other code away. I'm not aware of other optimizations that use runtime values (i.e. the result of foo instanceof Bar) to make a decision about optimizing code - the DataflowAnalysis pass might fit this, but is disabled by default. Essentially, we could visit any if where the instanceof is alone or only &&'d with other expressions, and in its "then" block we could rewrite the cast, if any - or, any chain of &&d expressions with a chain of instanceof and a matching cast, we could rewrite the cast.

Originally I had thought that this would be easier to build generally, so we would want to use the same pass for both cases, but if this is trickier, it would be nice to optimize the new case right away.


It looks like there is already an ast node for unchecked casts - JUnsafeTypeCoercion is used already for @UncheckedCast, and will compile out to just the expression that is passed in. If we're certain that the type cannot be null (i.e. it passed a null check through the instanceof operation), we should be sure to strengthen the type to non-null before passing it in - this will avoid any possible concerns in the JUnsafeTypeCoercion.getType implementation not strengthening for us. It is possible that existing optimizations will deal with the rest of the null check for us.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant