Uh oh!
There was an error while loading. Please reload this page.
Conversation
kripken
commented
Oct 26, 2023
(as background, the situation of such functions calling others, and even in cycles, happens in real-world Java code) |
gkdn
commented
Oct 26, 2023
Just want to give a heads up for following situation: If we start from However if you remove the For this reason we don't handle this cycle situation in JsCompiler. We only handle following: |
kripken
commented
Oct 26, 2023
Thanks @gkdn , good point... We first set the global to 1 and then call code, which means recursive calls to us return early even though the full code after us has not executed. So in that example This will require an analysis of the call graph, then. |
kripken
commented
Oct 26, 2023
Given: B$once(){if(B$done)return;B$done=true;A$once();// can we apply information from this call?C$once();// can we remove this?log("executed B");}Then it seems like what we want, to answer the first question, is "can But it seems like this is a problem for all functions, not just the case where But given indirect calls, it seems likely we'd fail to infer in most cases, I worry. That is, if Am I missing something? |
kripken
commented
Oct 26, 2023
After discussing offline with @gkdn I simplified this to handle the straightforward case that is apparently common, where a "once" function's body calls another, and has nothing else. In that case we can optimize here (but in the general case it is safer to avoid the danger of cycles and so forth; if we find a need for it later, we can investigate some call graph analysis, but as I said above, I worry about indirect calls ruining things as they always do...). PTAL @gkdn |
| // which is simple to reason about. To see why, consider that it is very | ||
| // different from this situation: |
There was a problem hiding this comment.
The explanation of why the more complicated case doesn't work didn't really help me understand why the simple case does work. I think it would be more helpful to explain what we are going to do in the simple case more directly, then explain why it doesn't generalize to the more complicated case.
There was a problem hiding this comment.
Good idea, I rewrote it that way.
But maybe wait to read it on seeing if @gkdn finds a fundamental problem in my code 😄
Uh oh!
There was an error while loading. Please reload this page.
gkdn
commented
Oct 27, 2023
@kripken This doesn't optimize the scenario that I was handling on my side. It looks like it doesn't have the same effect. I will take a look what is going on. |
Co-authored-by: Thomas Lively <tlively@google.com>
gkdn
commented
Oct 27, 2023
I disabled partial inlining and this is the left-over code: In my own handling I rewrite for example as which later gets inlined to parent clinit call. |
kripken
commented
Oct 27, 2023
@gkdn Makes sense, that also looks like a valid optimization. I'd like to do it in a followup PR to this however, to keep this one as simple as possible (the comments are already dozens of lines 😄 ). |
gkdn
commented
Oct 27, 2023
@kripken I think the optimization make sense but I'm not sure if it will have any extra value if we do the other optimization. IIUC this extra information will not be useful with the rewriting as it will provide the same information. I tested both optimizations together and it looks like the code size is exactly the same but I might be missing something. |
kripken
commented
Oct 27, 2023
Yeah, I think you're right, after other optimizations they end up equal. I implemented the other one and compared them on the tests from this PR: https://gist.github.com/kripken/56a0f4f1d70e9575273c154d6eb981f8 The difference is only in cases that inlining would end up helping out later. So this PR only helps accelerate the process. As it is fairly complex in the necessary comments, maybe it isn't worth it. I'll open a PR with the other one next week after I polish and test the code. |
kripken
commented
Oct 30, 2023
Replaced by #6061 |
Say that we have a "once" function like this:
This calls
Athe first time it is reached, and otherwise early-exits. It also callsonce.B, however, which may also be a once function. If it is, then we couldoptimize this:
After the first call we know the second will have executed, so it can be removed.
To make this work, two small fixes were needed: First, we need to not assume
that only the "once" global itself is the only global set in a "once" function.
Second, we need to look at the proper part of the "once" function when we
consider what it is known to always set (see details in the large new comment).