Conversation
Keno
left a comment
There was a problem hiding this comment.
This is nice work, but doesn't work as is, because it doesn't consider the state of the heap.
For example, consider the following function:
function foo()
arr = Int[0]
a = arr[]
arr[] = 1
b = arr[]
(a, b)
end
As is, a, and b will be considered congruent and replaced with each other. However, this is incorrect.
|
That said, if we promote inaccessiblememonly to an IR flag, we could probably do this at least for things that don't touch memory, which might still be useful. Will have to wait until after #50805 though, since the flag space is currently full. |
I'm a bit confused, this seems to work fine for me. I see the same IR before the GVN pass, after the GVN pass and after "compact 2" on master (#95af5a08926). Looking at the flags of |
|
Hmm, I may have been wrong, and IR_FLAG_CONSISTENT might be strong enough. I'll need to think about it again to make sure. |
Having thought about it some more, I think the semantics of IR_FLAG_CONSISTENT are probably sufficient to ensure that this bails on things that access non-consistent memory, so that part is probably fine.
e2951e1 to
9485da8
Compare
|
Does this fix #50887? |
Yes that was the inspiration for this. |
|
FTR, if you put a |
Also hopefully fix some indexing bugs.
It broke building Julia for some reason, ``` Segmentation fault in expression starting at compiler/compiler.jl:181 perform_lifting! at ./compiler/ssair/passes.jl:667 ```
Add fast path back in.
Prevent accidental use and make intent clearer
I think this should all be legal. Unfortunately iterating over `compact` makes this pass significantly slower, ~2x, as lots of time is spent in `renumber_ssa2!`.
This reverts commit 057d817. This broke building somehow and was quite slow anyways.
Address review. Fix bug in not wrapping result form `ssa_to_ssa` in a `SSAValue` before writing into `key` in `perform_symbolic_evaluation`
Fixes simplification of PhiNode to SSAValue by reverting indexing fix and setting `firstval` to equivalent SSAValue.
Indices are Int's I believe.
`sort!` is not defined for memory whilst bootstrapping.
This enables common subexpression elimination, fixes #50887. This is based on the NewGVN pass in LLVM.
A possible avenue for increasing the number of eliminations would be to implement code hoisting (eg. an expression that is also present in all predecessors to a block could be moved to the immediate dominator and then replaced; alternatively we could replace it with a phi node) or Partial Redundancy Elimination.
I'm not sure when it would be optimal for this pass to run, the effects of a function may allow a non inlined call to be eliminated completely whilst when inlined only parts may be deleted.
For small functions most of the time is spent on allocating two arrays (
ssa_to_ssaand the array backingval_to_ssa). For larger functions theget!dominates, #51091 speeds upget!2x. I don't think there any easy optimizations left, one possible avenue would be computing use lists (a list of every instruction in which aSSAValueis used) and using that to not have to iterate over every instruction.