As discussed in the parent patch, we sometimes need to describe a variable value substitution with a subregister qualifier, to say that "the value is the lower 32 bits of this 64 bit register def" for example. That then needs support during LiveDebugValues to interpret the subregister qualifiers, which is what this patch does.
Whenever we encounter a DBG_INSTR_REF and find its value by using a substitution, collect any subregister qualifiers seen. Then, accumulate the effects of the qualifiers to work out what offset and what size should be extracted from the defined register. Finally, for the target ValueIDNum, extract whatever subregister is in the correct position. Here's a worked example, from one of the comments in the code, consider some COPYs like this:
// CALL64 @foo, implicit-def $rax, debug-instr-number 4 // %0:gr64 = COPY $rax // %1:gr32 = COPY %0.sub_32bit // %2:gr16 = COPY %1.sub_16bit // %3:gr8 = COPY %2.sub_8bit // DBG_INSTR_REF 1, 0
This would be presented as the following substitutions (code to handle the above in the next patch in this series):
debugValueSubstitutions: - { srcinst: 1, srcop: 0, dstinst: 2, dstop: 0, subreg: 1 } # sub_8bit - { srcinst: 2, srcop: 0, dstinst: 3, dstop: 0, subreg: 4 } # sub_16bit - { srcinst: 3, srcop: 0, dstinst: 4, dstop: 1, subreg: 6 } # sub_32bit
Which means: extract 8 bits from 16 bits from 32 bits from instruction 4 operand 1. In InstrRefBasedImpl we identify $rax in the call, then examine the subregisters in reverse (lower 32, lower 16, lower 8) to identify $al. See the added test for some examples of picking out $ah instead. What this really needs is tests for more sophisticated architecture, but I'm insufficiently experienced with ARM, alas.
Currently, describing a subregister field of a larger value that has been spilt to the stack, is unimplemented. It's technically possible with more DIExpressions, I just haven't implemented it yet.