summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp
AgeCommit message (Collapse)Author
2022-02-02[DebugInfo][InstrRef][NFC] Free resources at an earlier stageJeremy Morse
This patch releases some memory from InstrRefBasedLDV earlier that it would otherwise. The underlying problem is: * We store a big table of "live in values for each block", * We translate that into DBG_VALUE instructions in each block, And both exist in memory at the same time, which needlessly doubles that information. The most of what this patch does is: as we progressively translate live-in information into DBG_VALUEs, we free the variable-value / machine-value tracking information as we go, which significantly reduces peak memory. While I'm here, also add a clear method to wipe variable assignments that have been accumulated into VLocTracker objects, and turn a DenseMap into a SmallDenseMap to avoid an initial allocation. Differential Revision: https://reviews.llvm.org/D118453
2022-02-02[DebugInfo][InstrRef][NFC] Cache some PHI resolutionsJeremy Morse
Install a cache of DBG_INSTR_REF -> ValueIDNum resolutions, for scenarios where the value has to be reconstructed from several DBG_PHIs. Whenever this happens, it's because branch folding + tail duplication has messed with the SSA form of the program, and we have to solve a mini SSA problem to find the variable value. This is always called twice, so it makes sense to cache the value. This gives a ~0.5% geomean compile-time-performance improvement on CTMark. Differential Revision: https://reviews.llvm.org/D118455
2022-02-02Re-apply 3fab2d138e30, now with a triple addedJeremy Morse
Was reverted in 1c1b670a73a9 as it broke all non-x86 bots. Original commit message: [DebugInfo][InstrRef] Add a max-stack-slots-to-track cut-out In certain circumstances with things like autogenerated code and asan, you can end up with thousands of Values live at the same time, causing a large working set and a lot of information spilled to the stack. Unfortunately InstrRefBasedLDV doesn't cope well with this and consumes a lot of memory when there are many many stack slots. See the reproducer in D116821. It seems very unlikely that a developer would be able to reason about hundreds of live named local variables at the same time, so a huge working set and many stack slots is an indicator that we're likely analysing autogenerated or instrumented code. In those cases: gracefully degrade by setting an upper bound on the amount of stack slots to track. This limits peak memory consumption, at the cost of dropping some variable locations, but in a rare scenario where it's unlikely someone is actually going to use them. In terms of the patch, this adds a cl::opt for max number of stack slots to track, and has the stack-slot-numbering code optionally return None. That then filters through a number of code paths, which can then chose to not track a spill / restore if it touches an untracked spill slot. The added test checks that we drop variable locations that are on the stack, if we set the limit to zero. Differential Revision: https://reviews.llvm.org/D118601
2022-02-01Revert "[DebugInfo][InstrRef] Add a max-stack-slots-to-track cut-out"Kevin Athey
This reverts commit 3fab2d138e30c65249e1eaea6cc68b2b7f50955a. Breaking PPC sanitizer build: https://lab.llvm.org/buildbot/#/builders/105/builds/20857
2022-02-01[DebugInfo][InstrRef][NFC] Bypass a frequently-noop loopJeremy Morse
Bypass this loop if it would do nothing -- if there are no register masks to be examined, there's no point looking at each location to see if the location has been def'd. Awkwardly, this was responsible for almost an entire half a percent of performance improvement on CTMark. Differential Revision: https://reviews.llvm.org/D118613
2022-02-01[DebugInfo][InstrRef] Add a max-stack-slots-to-track cut-outJeremy Morse
In certain circumstances with things like autogenerated code and asan, you can end up with thousands of Values live at the same time, causing a large working set and a lot of information spilled to the stack. Unfortunately InstrRefBasedLDV doesn't cope well with this and consumes a lot of memory when there are many many stack slots. See the reproducer in D116821. It seems very unlikely that a developer would be able to reason about hundreds of live named local variables at the same time, so a huge working set and many stack slots is an indicator that we're likely analysing autogenerated or instrumented code. In those cases: gracefully degrade by setting an upper bound on the amount of stack slots to track. This limits peak memory consumption, at the cost of dropping some variable locations, but in a rare scenario where it's unlikely someone is actually going to use them. In terms of the patch, this adds a cl::opt for max number of stack slots to track, and has the stack-slot-numbering code optionally return None. That then filters through a number of code paths, which can then chose to not track a spill / restore if it touches an untracked spill slot. The added test checks that we drop variable locations that are on the stack, if we set the limit to zero. Differential Revision: https://reviews.llvm.org/D118601
2022-02-01[DebugInfo][InstrRef][NFC] Don't build a map of un-needed valuesJeremy Morse
When finding locations for variable values at the start of a block, we build a large map of every value to every location, and then pick out the locations for values that are desired. This takes up quite a lot of time, because, unsurprisingly, there are usually more values in registers and stack slots than there are variables. This patch instead creates a map of desired values to their locations, which are initially illegal locations. Then, as we examine every available value, we can select locations for values we care about, and ignore those that we don't. This substantially reduces the amount of work done (i.e., building a map up of values to locations that nothing wants or needs). Geomean performance improvement of 1% on CTMark, woo. Differential Revision: https://reviews.llvm.org/D118597
2022-01-31[DebugInfo][InstrRef][NFC] Refactor ahead of further optimisationsJeremy Morse
This patch shuffles some functions around so that some blocks of code can be reused. In particular, * Move the determination of "which blocks are in scope" to its own function, as it's non-trivial to solve. Delete the "InScopeBlocks" collection too, which nothing reads from. * Split transfer emission (i.e., installing DBG_VALUEs into blocks) into its own function. * Name some useful types. * Rename "ScopeToBlocks" to "ScopeToAssignBlocks", as that's what the collection contains, blocks where assignments happen. Differential Revision: https://reviews.llvm.org/D118454
2022-01-31[DebugInfo][InstrRef] Don't fully propagate single assigned variablesJeremy Morse
If we only assign a variable value a single time, we can take a short-cut when computing its location: the variable value is only valid up to the dominance frontier of where the assignemnt happens. Past that point, there are other predecessors from where the variable has no value, meaning the variable has no location past that point. This patch recognises this scenario, and avoids expensive SSA computation, to improve compile-time performance. Differential Revision: https://reviews.llvm.org/D117877
2022-01-30[Support][NFC] Fix generic `ChildrenGetterTy` of `IDFCalculatorBase`Markus Böck
Both IDFCalculatorBase and its accompanying DominatorTreeBase only supports pointer nodes. The template argument is the block type itself and any uses of GraphTraits is therefore done via a pointer to the node type. However, the ChildrenGetterTy type of IDFCalculatorBase has a use on just the node type instead of a pointer to the node type. Various parts of the monorepo has worked around this issue by providing specializations of GraphTraits for the node type directly, or not been affected by using specializations instead of the generic case. These are unnecessary however and instead the generic code should be fixed instead. An example from within Tree is eg. A use of IDFCalculatorBase in InstrRefBasedImpl.cpp. It basically instantiates a IDFCalculatorBase<MachineBasicBlock, false> but due to the bug above then goes on to specialize GraphTraits<MachineBasicBlock> although GraphTraits<MachineBasicBlock*> exists (and should be used instead). Similar dead code exists in clang which defines redundant GraphTraits to work around this bug. This patch fixes both the original issue and removes the dead code that was used to work around the issue. Differential Revision: https://reviews.llvm.org/D118386
2022-01-20[DebugInstrRef] Memoize variable order during sorting (NFC)Nikita Popov
Instead of constructing DebugVariables and looking up the order in the comparison function, compute the order upfront and then sort a vector of (order, instr). This improves compile-time by -0.4% geomean on CTMark ReleaseLTO-g. Differential Revision: https://reviews.llvm.org/D117575
2022-01-18[DebugInstrRef] Add some missing const qualifiers (NFC)Nikita Popov
2022-01-18[DebugInstrRef] Use DenseMap for ValueToLoc (NFC)Nikita Popov
Just replacing std::map with DenseMap here is a major regression -- because this code used an identity hash for ValueIDNum. Because ValueIDNum is composed of multiple components, it is important that we use a reasonably good hash function here, so switch it to hash_value. DenseMapInfo::getHashValue<uint64_t> would not be sufficient. This gives a -0.8% geomean improvement on CTMark ReleaseLTO-g.
2022-01-13[DebugInfo][InstrRef] Short-circuit unnecessary preferred location map ↵Eugene Zhulenev
construction Reviewed By: cota Differential Revision: https://reviews.llvm.org/D117162
2021-12-03[CodeGen] Use range-based for loops (NFC)Kazu Hirata
2021-11-30[DebugInfo][InstrRef] Avoid dropping fragment info during PHI eliminationJeremy Morse
InstrRefBasedLDV used to crash on the added test -- the exit block is not in scope for the variable being propagated, but is still considered because it contains an assignment. The failure-mode was vlocJoin ignoring assign-only blocks and not updating DIExpressions, but pickVPHILoc would still find a variable location for it. That led to DBG_VALUEs created with the wrong fragment information. Fix this by removing a filter inherited from VarLocBasedLDV: vlocJoin will now consider assign-only blocks and will update their expressions. Differential Revision: https://reviews.llvm.org/D114727
2021-11-29[DebugInfo][InstrRef] Terminate overlapping variable fragmentsJeremy Morse
If we have a variable where its fragments are split into overlapping segments: DBG_VALUE $ax, $noreg, !123, !DIExpression(DW_OP_LLVM_fragment_0, 16) ... DBG_VALUE $eax, $noreg, !123, !DIExpression(DW_OP_LLVM_fragment_0, 32) we should only propagate the most recently assigned fragment out of a block. LiveDebugValues only deals with live-in variable locations, as overlaps within blocks is DbgEntityHistoryCalculators domain. InstrRefBasedLDV has kept the accumulateFragmentMap method from VarLocBasedLDV, we just need it to recognise DBG_INSTR_REFs. Once it's produced a mapping of variable / fragments to the overlapped variable / fragments, VLocTracker uses it to identify when a debug instruction needs to terminate the other parts it overlaps with. The test is updated for some standard "InstrRef picks different registers" variation, and the order of some unrelated DBG_VALUEs changes. Differential Revision: https://reviews.llvm.org/D114603
2021-11-29[DebugInfo][InstrRef] Preserve properties of restored variablesJeremy Morse
InstrRefBasedLDV observes when variable locations are clobbered, scans what values are available in the machine, and re-issues a DBG_VALUE for the variable if it can find another location. Unfortunately, I hadn't joined up the Indirectness flag, so if it did this to an Indirect Value, the indirectness would be dropped. Fix this, and add a test that if we clobber a variable value (on the stack in this case), then the recovered variable location keeps the Indirect flag. Differential Revision: https://reviews.llvm.org/D114378
2021-11-25[DebugInfo][InstrRef] Add extra indirection for NRVO testsJeremy Morse
In some scenarios, usually involving NRVO, we can issue indirect DBG_VALUEs after SelectionDAG, even in instruction referencing mode (if the variable is an argument). If the corresponding argument value is spilt to the stack, then we have: * Indirection from it being on the stack, * Indirection from it being a dbg.declare or a dbg.addr. However InstrRefBasedLDV only emits one level of indirection. This patch adds the second, by adding an extra DW_OP_deref if necessary. The two tests modified fail otherwise -- they feature some NRVO, and require two levels of indirection to be correct. Differential Revision: https://reviews.llvm.org/D114364
2021-11-25[DebugInfo][InstrRef] Track variable assignments in out-of-scope blocksJeremy Morse
DBG_INSTR_REF's and DBG_VALUE's can end up in blocks that aren't in the lexical scope of their variable. It's arguable as to what we should do about this, however VarLocBasedLDV permits such variable locations to be propagated, so let's allow it in InstrRefBasedLDV. It's necessary for the modified test to work. Differential Revision: https://reviews.llvm.org/D114578
2021-11-24[DebugInfo][InstrRef] Cope with win32 calls changing SP in LiveDebugValuesJeremy Morse
Almost all of the time, call instructions don't actually lead to SP being different after they return. An exception is win32's _chkstk, which which implements stack probes. We need to recognise that as modifying SP, so that copies of the value are tracked as distinct vla pointers. This patch adds a target frame-lowering hook to see whether stack probe functions will modify the stack pointer, store that in an internal flag, and if it's true then scan CALL instructions to see whether they're a stack probe. If they are, recognise them as defining a new stack-pointer value. The added test exercises this behaviour: two calls to _chkstk should be considered as producing two different values. Differential Revision: https://reviews.llvm.org/D114443
2021-11-24[DebugInfo][InstrRef] Ignore SP clobbers on call instructions even moreJeremy Morse
Avoid un-necessarily recreating DBG_VALUEs on call instructions. In LiveDebugvalues we choose to ignore any clobbers of SP by call instructions, as they're irrelevant to our model of the machine. We currently do so for tracking register values (MTracker); do the same for tracking variable locations (TTracker). Test modified to endure that a duplicate DBG_VALUE is not created after the call in struction in this test. Differential Revision: https://reviews.llvm.org/D114365
2021-11-09[llvm] Use MachineBasicBlock::{successors,predecessors} (NFC)Kazu Hirata
2021-10-25[DebugInfo][InstrRef][NFC] Switch to using DenseMaps and similarJeremy Morse
There are a few STL containers hanging around that can become DenseMaps, SmallVectors and similar. This recovers a modest amount of compile time performance. While I'm here, adjust the bit layout of ValueIDNum: this was always supposed to act like a value type, however it seems that clang doesn't compile the comparison functions to act that way. Add a uint64_t to a union that explicitly aliases the bitfields, so that we can compare the whole value as a single integer. Differential Revision: https://reviews.llvm.org/D112333
2021-10-25[DebugInfo][InstrRef] Recover stack-slot tracking performanceJeremy Morse
This patch is like D111627 -- instead of calculating IDF for every location on the stack, only do it for the smallest units of interference, and copy the PHIs for those units to any aliases. The test added runs placeMLocPHIs directly, and tests that: * A def of the lower 8 bits of a stack slot causes all aliasing regs to have PHIs placed, * It doesn't cause the equivalent location to x86's $ah, which isn't aliased, to have a PHI placed. Differential Revision: https://reviews.llvm.org/D112324
2021-10-25[DebugInfo][InstrRef] Track values fused into stack spillsJeremy Morse
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 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. This patch adds substitution code to InlineSpiller to record such fused spills, and tracking in InstrRefBasedLDV to recognise such values, and produce the value numbers for them. Everything to do with the movement of stack-defined values is already handled in InstrRefBasedLDV. Differential Revision: https://reviews.llvm.org/D111317
2021-10-25[DebugInfo][NFC] Avoid a use-after-freeJeremy Morse
This patch swaps two lines -- the CurSucc reference can be invalidated by the call to DFS.push_back, therefore that should happen last. The usual hat-tip to asan for catching this. This patch also swaps an ealier call to ToAdd.insert and DFS.push_back, where a stable iterator (from successors()) is being used. This isn't strictly necessary, but is good for consistency and avoiding readers asking themselves why the two code portions have a different order.
2021-10-22[DebugInfo][Instr] Track subregisters across stack spills/restoresJeremy Morse
Sometimes we generate code that writes to a subregister, then spills / restores a super-register to the stack, for example: $eax = MOV32ri 0 MOV64mr $rsp, 1, $noreg, 16, $noreg, $rax $rcx = MOV64rm $rsp, 1, $noreg, 8, $noreg This patch takes a different approach: it adds another index to MLocTracker that identifies a size/offset within a stack slot. A location on the stack is then a pari of {FrameIndex, SlotNum}. Spilling and restoring now involves pairing up the src/dest register numbers, and the dest/src stack position to be transferred to/from. Location coverage improves as a result, compile-time performance decreases, alas. One limitation is that if a PHI occurs inside a stack slot: DBG_PHI %stack.0, 1 We don't know how large the resulting value is, and so might have difficulty picking which value to use. DBG_PHI might need to be augmented in the future with such a size. Unit tests added ensure that spills and restores correctly transfer to positions in the Location => Value map, and that different register classes written to the stack will correctly clobber all other positions in the stack slot. Differential Revision: https://reviews.llvm.org/D112133
2021-10-22[DebugInfo][InstrRef] Add unit tests for transfer-function buildingJeremy Morse
This patch adds some unit tests for the machine-location transfer-function building parts of InstrRefBasedLDV: i.e., test that if we feed some MIR into the transfer-function building code, does it create the correct transfer function. There are a number of minor defects that get corrected in the process: * The unit test was selecting the x86 (i.e. 32 bit) backend rather than x86_64's 64 bit backend, * COPY instructions weren't actually having their subregister values correctly represented in the transfer function. Subregisters were being defined by the COPY, rather than taking the value in the source register. * SP aliases were at risk of being clobbered, if an SP subregister was clobbered. Differential Revision: https://reviews.llvm.org/D112006
2021-10-20[DebugInfo][InstrRef] Track a single variable at a timeJeremy Morse
Here's another performance patch for InstrRefBasedLDV: rather than processing all variable values in a scope at a time, instead, process one variable at a time. The benefits are twofold: * It's easier to reason about one variable at a time in your mind, * It improves performance, apparently from increased locality. The downside is that the value-propagation code gets indented one level further, plus there's some churn in the unit tests. Differential Revision: https://reviews.llvm.org/D111799
2021-10-19[DebugInfo][InstrRef] Avoid un-necessary densemap copies and comparisonsJeremy Morse
This is purely a performance patch: InstrRefBasedLDV used to use three DenseMaps to store variable values, two for long term storage and one as a working set. This patch eliminates the working set, and updates the long term storage in place, thus avoiding two DenseMap comparisons and two DenseMap assignments, which can be expensive. Differential Revision: https://reviews.llvm.org/D111716
2021-10-18Fix signed/unsigned comparison after b5426ced71280Jeremy Morse
gcc11 warns that this counter causes a signed/unsigned comaprison when it's later compared with a SmallVector::difference_type. gcc appears to be correct, clang does not warn one way or the other.
2021-10-14[DebugInfo][InstrRef] Place variable-values PHI using LLVM utilitiesJeremy Morse
This patch is very similar to D110173 / a3936a6c19c, but for variable values rather than machine values. This is for the second instr-ref problem, calculating the correct variable value on entry to each block. The previous lattice based implementation was broken; we now use LLVMs existing PHI placement utilities to work out where values need to merge, then eliminate un-necessary ones through value propagation. Most of the deletions here happen in vlocJoin: it was trying to pick a location for PHIs to happen in, badly, leading to an infinite loop in the MIR test added, where it would repeatedly switch between register locations. The new approach is simpler: either PHIs can be eliminated, or they can't, and the location of the value is a different problem. Various bits and pieces move to the header so that they can be tested in the unit tests. The DbgValue class grows a "VPHI" kind to represent variable value PHIS that haven't been eliminated yet. Differential Revision: https://reviews.llvm.org/D110630
2021-10-13[DebugInfo][InstrRef] Only calculate IDF for reg unitsJeremy Morse
In D110173 we start using the existing LLVM IDF calculator to place PHIs as we reconstruct an SSA form of machine-code program. Sadly that's slower than the old (but broken) way, this patch attempts to recover some of that performance. The key observation: every time we def a register, we also have to def it's register units. If we def'd $rax, in the current implementation we independently calculate PHI locations for {al, ah, ax, eax, hax, rax}, and they will all have the same PHI positions. Instead of doing that, we can calculate the PHI positions for {al, ah} and place PHIs for any aliasing registers in the same positions. Any def of a super-register has to def the unit, and vice versa, so this is sound. It cuts down the SSA placement we need to do significantly. This doesn't work for stack slots, or registers we only ever read, so place PHIs normally for those. LiveDebugValues choses to ignore writes to SP at calls, and now have to ignore writes to SP register units too. Differential Revision: https://reviews.llvm.org/D111627
2021-10-13Follow up a3936a6c19c to work around an old compiler bugJeremy Morse
Old versions of gcc want template specialisations to happen within the namespace where the template lives; this is still present in gcc 5.1, which we officially support, so it has to be worked around.
2021-10-13[DebugInfo][InstrRef] Use PHI placement utilities for machine locationsJeremy Morse
InstrRefBasedLDV used to try and determine which values are in which registers using a lattice approach; however this is hard to understand, and broken in various ways. This patch replaces that approach with a standard SSA approach using existing LLVM utilities. PHIs are placed at dominance frontiers; value propagation then eliminates un-necessary PHIs. This patch also adds a bunch of unit tests that should cover many of the weirder forms of control flow. Differential Revision: https://reviews.llvm.org/D110173
2021-10-12Scatter NDEBUG to fix after 838b4a533e6Jeremy Morse
These "dump" methods call into MachineOperand::dump, which doesn't exist with NDEBUG, thus we croak. Disable LiveDebugValues dump methods when NDEBUG is turned on to avoid this.
2021-10-12[DebugInfo][NFC] Move LiveDebugValues class to headerJeremy Morse
This patch shifts the InstrRefBasedLDV class declaration to a header. Partially because it's already massive, but mostly so that I can start writing some unit tests for it. This patch also adds the boilerplate for said unit tests. Differential Revision: https://reviews.llvm.org/D110165
2021-10-07[MachineInstr] Move MIParser's DBG_VALUE RegState::Debug invariant into ↵Jack Andersen
MachineInstr::addOperand Based on the reasoning of D53903, register operands of DBG_VALUE are invariably treated as RegState::Debug operands. This change enforces this invariant as part of MachineInstr::addOperand so that all passes emit this flag consistently. RegState::Debug is inconsistently set on DBG_VALUE registers throughout LLVM. This runs the risk of a filtering iterator like MachineRegisterInfo::reg_nodbg_iterator to process these operands erroneously when not parsed from MIR sources. This issue was observed in the development of the llvm-mos fork which adds a backend that relies on physical register operands much more than existing targets. Physical RegUnit 0 has the same numeric encoding as $noreg (indicating an undef for DBG_VALUE). Allowing debug operands into the machine scheduler correlates $noreg with RegUnit 0 (i.e. a collision of register numbers with different zero semantics). Eventually, this causes an assert where DBG_VALUE instructions are prohibited from participating in live register ranges. Reviewed By: MatzeB, StephenTozer Differential Revision: https://reviews.llvm.org/D110105
2021-10-05[DebugInfo][InstrRef] Track all of DBG_PHIs operandsJeremy Morse
An important part of the instruction referencing solution is that we identify all the registers that values move between before we then compute an SSA-like function from the machine code, and from the variable intrinsics. DBG_PHIs weren't causing all the subregisters of their operands to be tracked; this patch forces that to happen. The practical implications were that not enough space is allocated for storing values when analysing the function -- asan will crash on the attached test case with an unpatched compiler. Non-asan llc's will produce a DBG_VALUE $noreg, where it should be $dil. Differential Revision: https://reviews.llvm.org/D109064
2021-08-20[DebugInfo][InstrRef] Correctly ignore DBG_VALUE_LIST in InstrRef modeJeremy Morse
This patch makes InstrRefBasedLDV "safe" to work with DBG_VALUE_LISTs. It doesn't actually interpret them, but it recognises that they specify variable locations and avoids propagating false locations, which is better than the current state. Observe the attached tes * We avoid propagating DBG_VALUE_LISTs into successor blocks, as they're not "currently" supported, * We don't propagate other variable locations across DBG_VALUE_LISTs, because we know that the variable location is terminated by the DBG_VALUE_LIST. Differential Revision: https://reviews.llvm.org/D108143
2021-08-20[DebugInfo][InstrRef] Remove a faulty assertionJeremy Morse
This patch removes an assertion, and adds a regression test showing why the assertion is broken. For context, LocIdx is a key/index number for machine locations, so that we can describe locations as a single integer and ignore whether they're on the stack, in registers or otherwise. Back when InstrRefBasedLDV was added, I happened to bake in a "special" zero number for various reasons, which Vedant identified as undesirable in this review comment: https://reviews.llvm.org/D83047#inline-765495 . I subsequently removed that special zero number, but it looks like I didn't delete this assertion at the time, which assumes that a zero LocIdx is invalid. The attached test shows that this assertion is reachable on valid code -- on x86 $rsp always gets the LocIdx number zero, and if you transfer a variable value into it, InstrRefBasedLDV crashes on that assertion. The code might be a bit wild to be storing variables to $rsp like that, however we shouldn't crash on it. Differential Revision: https://reviews.llvm.org/D108134
2021-08-17[DebugInfo][InstrRef] Honour too-much-debug-info cutoutsJeremy Morse
This reapplies 54a61c94f93, its follow up in 547b712500e, which were reverted 95fe61e63954. Original commit message: VarLoc based LiveDebugValues will abandon variable location propagation if there are too many blocks and variable assignments in the function. If it didn't, and we had (say) 1000 blocks and 1000 variables in scope, we'd end up with 1 million DBG_VALUEs just at the start of blocks. Instruction-referencing LiveDebugValues should honour this limitation too (because the same limitation applies to it). Hoist the relevant command line options into LiveDebugValues.cpp and pass it down into the implementation classes as an argument to ExtendRanges. I've duplicated all the run-lines in live-debug-values-cutoffs.mir to have an instruction-referencing flavour. Differential Revision: https://reviews.llvm.org/D107823
2021-08-16Revert 54a61c94f93 and its follow up in 547b712500eJeremy Morse
These were part of D107823, however asan has found something excitingly wrong happening: https://lab.llvm.org/buildbot/#/builders/5/builds/10543/steps/13/logs/stdio
2021-08-16Suppress signedness-comparison warningJeremy Morse
This is a follow-up to 54a61c94f93.
2021-08-16[DebugInfo][InstrRef] Honour too-much-debug-info cutoutsJeremy Morse
VarLoc based LiveDebugValues will abandon variable location propagation if there are too many blocks and variable assignments in the function. If it didn't, and we had (say) 1000 blocks and 1000 variables in scope, we'd end up with 1 million DBG_VALUEs just at the start of blocks. Instruction-referencing LiveDebugValues should honour this limitation too (because the same limitation applies to it). Hoist the relevant command line options into LiveDebugValues.cpp and pass it down into the implementation classes as an argument to ExtendRanges. I've duplicated all the run-lines in live-debug-values-cutoffs.mir to have an instruction-referencing flavour. Differential Revision: https://reviews.llvm.org/D107823
2021-07-09[X86] Return src/dest register from stack spill/restore recogniserJeremy Morse
LLVM provides target hooks to recognise stack spill and restore instructions, such as isLoadFromStackSlot, and it also provides post frame elimination versions such as isLoadFromStackSlotPostFE. These are supposed to return the store-source and load-destination registers; unfortunately on X86, the PostFE recognisers just return "1", apparently to signify "yes it's a spill/load". This patch alters the hooks to correctly return the store-source and load-destination registers: This is really useful for debug-info as we it helps follow variable values as they move on/off the stack. There should be no codegen changes: the only other users of these PostFE target hooks are MachineInstr::getRestoreSize and MachineInstr::getSpillSize, which don't attempt to interpret the returned register location. While we're here, delete the (InstrRef) LiveDebugValues heuristic that tries to find the spill source register by looking for a killed reg -- we should be able to rely on the target hooks for that. This involves temporarily turning off a n InstrRef LivedDebugValues test on aarch64 (patch to re-enable it is in D104521). Differential Revision: https://reviews.llvm.org/D105428
2021-07-09[Debug-info][InstrRef] Avoid an unnecessary map orderingJeremy Morse
We keep a record of substitutions between debug value numbers post-isel, however we never actually look them up until the end of compilation. As a result, there's nothing gained by the collection being a std::map. This patch downgrades it to being a vector, that's then sorted at the end of compilation in LiveDebugValues. Differential Revision: https://reviews.llvm.org/D105029
2021-07-01[DebugInfo][InstrRef][2/4] Use subreg substitutions in LiveDebugValuesJeremy Morse
Added in 47c3fe2a22cf, 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 adds. 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 Currently, describing a subregister field of a larger value that has been spilt to the stack, is unimplemented. Differential Revision: https://reviews.llvm.org/D88894
2021-07-01[DebugInfo][InstrRef][1/4] Support transformations that widen valuesJeremy Morse
Very late in compilation, backends like X86 will perform optimisations like this: $cx = MOV16rm $rax, ... -> $rcx = MOV64rm $rax, ... Widening the load from 16 bits to 64 bits. SEeing how the lower 16 bits remain the same, this doesn't affect execution. However, any debug instruction reference to the defined operand now refers to a 64 bit value, nto a 16 bit one, which might be unexpected. Elsewhere in codegen, there's often this pattern: CALL64pcrel32 @foo, implicit-def $rax %0:gr64 = COPY $rax %1:gr32 = COPY %0.sub_32bit Where we want to refer to the definition of $eax by the call, but don't want to refer the copies (they don't define values in the way LiveDebugValues sees it). To solve this, add a subregister field to the existing "substitutions" facility, so that we can describe a field within a larger value definition. I would imagine that this would be used most often when a value is widened, and we need to refer to the original, narrower definition. Differential Revision: https://reviews.llvm.org/D88891