During register allocation, some instructions can have stack spills fused into them. It means that when vregs are allocated on the stack we can convert:
SETCCr %0 DBG_VALUE $0
to
SETCCm %stack.0 DBG_VALUE %stack.0
for example. DBG_VALUE instructions can simply have their vreg operands replaced with a stack location, and it all Just Works (TM). Unfortunately instruction referencing finds this harder: a store to the stack doesn't have a specific operand number, therefore we don't substitute the old operand for a new operand, and the location is dropped.
This patch implements a solution: just recognise the memory operand attached to an instruction with a Special Number (TM), and record a substitution between the old value and the new one. Thus we would have:
SETCCr %0 [...] debug-instr-number 1 :: (store (s32) into %stack.0) DBG_INSTR_REF 1, 0
become
SETCCm %stack.0 [...] debug-instr-number 2 :: (store (s32) into %stack.0) DBG_INSTR_REF 1, 0
With a substitution from operand (1, 0) to (2, MemoryOperand). In LiveDebugValues, we can identify the stack slot written to just like a spill instruction, and track its value from that point onwards.
This patch installs the substitution code into InlineSpiller: it's not that interesting, just adds a substitution. It's not completely clear to me what all the circumstances that the spiller runs with are, so I've filtered to only substitute in common cases, see the two MIR tests added.
In InstrRefBasedLDV, we now:
- Recognise instructions that write to stack slots as def'ing that stack slot,
- Allow DBG_INSTR_REFs that refer to a memory operand to "read" the value defined by that instruction, in the stack slot.
Can you use const/constexpr here so that you can include the definition here in the header? Or is there some reason that this isn't const?