-
Notifications
You must be signed in to change notification settings - Fork 15.2k
Description
Filing this to track a work item discovered when working on #160765. This is an interaction with non-trivial remat which we should probably return to once #159211 has landed. This doesn't appear to be a correctness issue, but might be an opt quality issue.
In LiveRangeEdit::eliminateDeadDef, we delete definitions whose uses have been fully eliminated except that we keep rematerializable definitions at the start of their original live range. Except that if the remat instruction has a virtual register use, we don't.
Keeping the instruction is important for our ability to further rematerialize within the original live interval. Once we delete it, all further remat stops.
So, if we get a series of events like this:
- Given a very big live interval, split it into sub-ranges (say into a loop).
- Perform non-trivial remat, delete the original instruction.
- Further split the live interval
- Eventually need to spill one of the sub-intervals
- Try to remat the original def, fail, and spill instead.
The current heuristic is trying to balance the need to shrink the operand live ranges. This seems like a general valid concern.
I think we might be able to change how we find the rematerializable instruction in the original range, but haven't fully thought this through.
A test case which demonstrates this issue was added in #161614, as the same behavior triggered the violation of my newly added invariant. This is a rather hard to hit case.