In preparation for adding support for DBG_VALUE_LIST instructions in InstrRefLDV, this patch updates the logic for joining variables at block joins to support joining variables that use multiple debug operands. This is one of the more meaty "logical" changes, although the line count isn't too high - this changes pickVPHILoc to find a valid joined location for every operand, with part of the function being split off into pickValuePHILoc which finds a location for a single operand.
The additions/changes SGTM but I don't think I'd be able to catch an omission here - imo it's worth @jmorse having a quick look too.
is !OutValOp.isUndef() the same as OutValOp.ID != ValueIDNum::EmptyValue?
Is Locs.clear() left over from experimental changes? (Looks redundant to me?)
Basically, except we're skipping the check for IsConst here (as we assert !IsConst above) - but now that you mention it, might as well keep it the same for consistency's sake and legibility.
This looks good -- I've got some comments, but it's a good separation of the two things going on, selecting the location of an operand, and Doing Stuff (TM) for an entire variable value.
Possibly this is in another patch, but: I think this also deserves some straight-forward unit testing of multiple operands, as far as I can see only the single-operand versions are updated? It would be too much testing to have multiple-operand versions of each flavour of control flow, but some higher level testing, like checking values where one operand has different const-ness and the like don't get joined, should catch potential errors in the future.
Deleting this makes me twitch a little; and it looks like the code and comment are out of sync, the test is for whether this is a backedge (VPHI defined in the current block feeding back into itself).
I think the way this would fail is where there's an arbitrary, unresolved VPHI feeding into a block: I think without this test, we would then treat it like a live-through value, even if it ends up being something different. There might be some other portion of code that stops such an error being visible.
Does that make sense / is there a positive reason for deleting this?
IMO, wants a comment, "If this isn't due to be joined, use the already-agreed value". Seems obvious, but let's affirm future readers understanding.
Take reference, avoiding large copy? May or may not have reallocation/invalidation issues.
Could I suggest pickOperandPHILoc -- if we're terming each part of the overall Value an operand, we should make the function names consistent.
Wording nit -- to me this reads better (clear that we're abstracting over each individual operand, and joining all values of an operand together). This is probably pure taste, how do you feel it reads?
Yes - the reason it's deleted here is because the check has been shunted up to pickVPHILoc, before we reach this function; see line 2449:
// For unjoined VPHIs where we don't know the location, we definitely // can't find a join loc unless the VPHI is a backedge. if (OutVal.isUnjoinedPHI() && OutVal.BlockNo != MBB.getNumber()) return false;
Probably sensible - though I think there's a fairly low-hanging fruit optimization to make DbgOp smaller, so it might be better to just fix up that particular thing and make this change unnecessary.
Added some unit tests - I've only added a few, since there's little to test w.r.t. variadic stuff specifically: primarily just that we can join operands for variadic debug values, and that if the join is invalid for at least one operand then the whole thing is invalid; otherwise the function is pretty much just calling the old logic on each element of a list.
Addressed the review comments, with the exception of the const DbgOp & suggestion, because I think it would be better to just make DbgOp smaller (which I'll add separate to this patch).
Actually, beyond just that potential optimization - there's no way to avoid the copy in this case, because DbgOpIDMap.find() creates a new DbgOp to return anyway, so there's no reference to take. The only resolution would be to have DbgOp itself contain a pointer/reference, which would be a more significant change.
again, an unused variable, please figure out how to get this warning firing locally