This patch makes the LiveDebugValues pass consider fragments when propagating DBG_VALUE insts between blocks, fixing PR41979. Fragment info for a variable location is added to the open-ranges key, which allows distinct fragments to be tracked separately. To handle overlapping fragments things become slightly funkier. To avoid excessive searching for overlaps in the data-flow part of LiveDebugValues, this patch:
- Pre-computes pairings of fragments that overlap, for each DILocalVariable
- During data-flow, whenever something happens that causes an open range to be terminated (via erase), any fragments pre-determined to overlap are also terminated.
The effect of which is that when encountering a DBG_VALUE fragment that overlaps others, the overlapped fragments do not get propagated to other blocks. We still rely on later location-list building to correctly handle overlapping fragments within blocks. Performance-wise, there are other options for implementing fast searching for overlapping fragments, but this seems alright.
Looking at the patch: DIExpression fragments grow a DenseMapInfo record so that fragments can be used in indexes. The "DebugVariable" class in LiveDebugValues loses its base of a std::pair: now that we have three things to index, we can't use std::pair's DenseMapInfo, so there's no point subclassing it. OpenRangesSet grows a reference to the precomputed map of overlapping fragments, and the LiveDebugValues class grows a method to build that map on the first run through the machine function. Finally, OpenRangesSet::erase now tries to close any overlapping fragments of the one being closed.
In terms of variable coverage, across a clang-3.4 build, applying this patch causes a grand total of _one_ new variable to have a location [applause]. Hacking llvm-dwarfdump to gather statistics on how _much_ (in bytes) of a variable is described when it has a location, for DW_TAG_structure_type's, we increase coverage from 98.9% of all possible bytes to 99.3%. It kind of sounds like missing fragment support wasn't causing too much of a loss in coverage for clang at least, however alternative coding styles that involve lots of classes that get broken up by SROA will have been worse hit.
In terms of performance, an average of three clang-3.4 builds with/without this patch shows a 0.8% increase in compile time. Looking closer at X86ISelLowering.cpp (a reference big-lump-of-c++), LiveDebugValues takes 0.32 seconds to run with this patch, versus 0.3 seconds without, out of a total of ~14 seconds total compilation time. IMHO, these increases in compile time are tolerable, seeing how this patch is an increase in functionality.