Treat operands of Phi
instructions as escaped
#16465
Draft
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Note: contains a few IR diffs that I haven't fully investigated.
During escape analysis, we currently allow an address to be used as an operand of a
Phi
instruction without escaping, as long as the result of thatPhi
instruction does not escape. This is probably correct for the technical definition of "escape", since we would still be seeing all uses of that address even after it propagates through thePhi
. However, when consuming the results of escape analysis (in SSA construction), we really treat "escapes" as meaning "there might be a memory access that accesses this allocation without us being able to prove that the memory access only accesses this allocation." For example:Neither
&x
nor&y
technically "escapes", because they are both consumed only at the store to*p
. However,*p
might access either of the two locations, which means that we need to treat bothx
andy
as aliased locations, assigned to the same virtual variable.The expedient thing to do is to treat all operands of a
Phi
instruction as escaped, since anything that might access memory via the result of thePhi
could be accessing any of multiple allocations, which is what I've done in this PR.If we wanted to be more precise, we could stick with our original definition of "escapes" meaning "we can't see all potential consumers of this address". We could then define a "consumes escaped" property for each memory access, which holds if we can't see all possible producers of the accessed memory address; this is essentially the dual of "escapes". We would then group all allocations into equivalence classes as follows:
Two allocations A and B are in the same class if any of the following hold:
Each equivalence class would get a unique virtual variable. This is almost what we have today. We already have a virtual variable for each never-aliased, never-escaped allocation. We also already have a single virtual variable containing all escaped allocations. The difference is that, with my fix from this PR, any allocation that could be one of mulitple targets of a memory access is lumped into the "all escaped" virtual variable. With the more precise approach, we could have virtual variables that contained multiple non-escaped allocations, distinct from the "all escaped" virtual variable.
I suspect that the more precise approach is not worth the effort, though.