summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h
AgeCommit message (Collapse)Author
2025-07-10[llvm] export private symbols needed by unittests (#145767)Andrew Rogers
## Purpose Export a small number of private LLVM symbols so that unit tests can still build/run when LLVM is built as a Windows DLL or a shared library with default hidden symbol visibility. ## Background The effort to build LLVM as a WIndows DLL is tracked in #109483. Additional context is provided in [this discourse](https://discourse.llvm.org/t/psa-annotating-llvm-public-interface/85307). Some LLVM unit tests use internal/private symbols that are not part of LLVM's public interface. When building LLVM as a DLL or shared library with default hidden symbol visibility, the symbols are not available when the unit test links against the DLL or shared library. This problem can be solved in one of two ways: 1. Export the private symbols from the DLL. 2. Link the unit tests against the intermediate static libraries instead of the final LLVM DLL. This PR applies option 1. Based on the discussion of option 2 in #145448, this option is preferable. ## Overview * Adds a new `LLVM_ABI_FOR_TEST` export macro, which is currently just an alias for `LLVM_ABI`. * Annotates the sub-set of symbols under `llvm/lib` that are required to get unit tests building using the new macro.
2025-03-18[LiveDebugValues][NFC] Remove TargetPassConfig from LDVImpl (#131562)Akshat Oke
TPC is only used to access the option `ShouldEmitDebugEntryValues`.
2024-09-30[NFC] Use initial-stack-allocations for more data structures (#110544)Jeremy Morse
This replaces some of the most frequent offenders of using a DenseMap that cause a malloc, where the typical element-count is small enough to fit in an initial stack allocation. Most of these are fairly obvious, one to highlight is the collectOffset method of GEP instructions: if there's a GEP, of course it's going to have at least one offset, but every time we've called collectOffset we end up calling malloc as well for the DenseMap in the MapVector.
2024-09-29[LiveDebugValues] Simplify code with MapVector::insert_or_assign (NFC) (#110398)Kazu Hirata
Note that we must use insert_or_assign because operator[] would require DbgValue to have the default constructor.
2024-09-19[LiveDebugValues] Avoid repeated hash lookups (NFC) (#109242)Kazu Hirata
2024-07-18Reapply 078198f310d5 "Index DebugVariables and some DILocations"Jeremy Morse
Now revised to actually make the unit test compile, which I'd been ignoring. No actual functional change, it's a type difference. Original commit message follows. [DebugInfo][InstrRef] Index DebugVariables and some DILocations (#99318) A lot of time in LiveDebugValues is spent computing DenseMap keys for DebugVariables, and they're made up of three pointers, so are large. This patch installs an index for them: for the SSA and value-to-location mapping parts of InstrRefBasedLDV we don't need to access things like the variable declaration or the inlining site, so just use a uint32_t identifier for each variable fragment that's tracked. The compile-time performance improvements are substantial (almost 0.4% on the tracker). About 80% of this patch is just replacing DebugVariable references with DebugVariableIDs instead, however there are some larger consequences. We spend lots of time fetching DILocations when emitting DBG_VALUE instructions, so index those with the DebugVariables: this means all DILocations on all new DBG_VALUE instructions will normalise to the first-seen DILocation for the variable (which should be fine). We also used to keep an ordering of when each variable was seen first in a DBG_* instruction, in the AllVarsNumbering collection, so that we can emit new DBG_* instructions in a stable order. We can hang this off the DebugVariable index instead, so AllVarsNumbering is deleted. Finally, rather than ordering by AllVarsNumbering just before DBG_* instructions are linked into the output MIR, store instructions along with their DebugVariableID, so that they can be sorted by that instead.
2024-07-18Revert "[DebugInfo][InstrRef] Index DebugVariables and some DILocations ↵Jeremy Morse
(#99318)" This reverts commit 078198f310d55925ccd9e1aa5b6ff4af3b36bbc7. Buildbots unhappy, I must have fluffed it
2024-07-18[DebugInfo][InstrRef] Index DebugVariables and some DILocations (#99318)Jeremy Morse
A lot of time in LiveDebugValues is spent computing DenseMap keys for DebugVariables, and they're made up of three pointers, so are large. This patch installs an index for them: for the SSA and value-to-location mapping parts of InstrRefBasedLDV we don't need to access things like the variable declaration or the inlining site, so just use a uint32_t identifier for each variable fragment that's tracked. The compile-time performance improvements are substantial (almost 0.4% on the tracker). About 80% of this patch is just replacing DebugVariable references with DebugVariableIDs instead, however there are some larger consequences. We spend lots of time fetching DILocations when emitting DBG_VALUE instructions, so index those with the DebugVariables: this means all DILocations on all new DBG_VALUE instructions will normalise to the first-seen DILocation for the variable (which should be fine). We also used to keep an ordering of when each variable was seen first in a DBG_* instruction, in the AllVarsNumbering collection, so that we can emit new DBG_* instructions in a stable order. We can hang this off the DebugVariable index instead, so AllVarsNumbering is deleted. Finally, rather than ordering by AllVarsNumbering just before DBG_* instructions are linked into the output MIR, store instructions along with their DebugVariableID, so that they can be sorted by that instead.
2024-07-17[InstrRef][NFC] Avoid un-necessary DenseMap queries (#99048)Jeremy Morse
This patch adjusts how some data is stored to avoid a number of un-necessary DenseMap queries. There's no change to the compiler behaviour, and it's measurably faster on the compile time tracker. The BlockOrders vector in buildVLocValueMap collects the blocks over which a variables value have to be determined: however the Cmp ordering function makes two DenseMap queries to determine the RPO-order of blocks being compared. And given that sorting is O(N log(N)) comparisons this isn't fast. So instead, fetch the RPO-numbers of the block collection, order those, and then map back to the blocks themselves. The OrderToBB collection mapped an RPO-number to an MBB: it's completely un-necessary to have DenseMap here, we can just use the RPO number as an array index. Switch it to a SmallVector and deal with a few consequences when iterating. (And for good measure I've jammed in a couple of reserve calls).
2024-01-16[NFC] sentinal -> sentinelDavid Green
2023-12-23[LiveDebugValues][nfc] Reduce memory usage of InstrRef (#76051)Felipe de Azevedo Piovezan
Commit 1b531d54f623 (#74203) removed the usage of unique_ptrs of arrays in favour of using vectors, but inadvertently increased peak memory usage by removing the ability to deallocate vector memory that was no longer needed mid-LDV. In that same review, it was pointed out that `FuncValueTable` typedef could be removed, since it was "just a vector". This commit addresses both issues by making `FuncValueTable` a real data structure, capable of mapping BBs to ValueTables and able to free ValueTables as needed. This reduces peak memory usage in the compiler by 10% in the benchmarks flagged by the original review. As a consequence, we had to remove a handful of instances of the "declare-then-initialize" antipattern in unittests, as the FuncValueTable class is no longer default-constructible.
2023-12-14[InstrRef][nfc] Remove usage of unique_ptrs of arrays (#74203)Felipe de Azevedo Piovezan
These are usually difficult to reason about, and they were being used to pass raw pointers around with array semantic (i.e., we were using operator [] on raw pointers). To put it in InstrRef terminology: we were passing a pointer to a ValueTable but using it as if it were a FuncValueTable. These could have easily been SmallVectors, which now allow us to have reference semantics in some places, as well as simpler initialization. In the future, we can use even more pass-by-reference with some extra changes in the code.
2023-09-22[InstrRef][NFC] Improve diagram illustrating locations (#66944)Felipe de Azevedo Piovezan
The "register number" arrow should point to `LocationID`, not `LocIdx`.
2023-05-18[LiveDebugValues] Initialized variable to avoid msan reportsVitaly Buka
Reproducible with =-1 and assert: https://reviews.llvm.org/P8309 Reviewed By: jmorse Differential Revision: https://reviews.llvm.org/D150420
2023-05-11[NFC][LiveDebugValues] Clang-format b135df08Vitaly Buka
2023-05-11[LiveDebugValues] Temporarily initialize MLocTracker::CurBBVitaly Buka
Looks like code assumes that it will be always set, but it's not true: https://reviews.llvm.org/D150420. This is temporarily suppression to enabled stricter msan on a bot.
2023-04-25[llvm] Replace None with std::nullopt in comments (NFC)Kazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2023-03-15[llvm] Use *{Map,Set}::contains (NFC)Kazu Hirata
2023-01-06[DebugInfo] Add support for variadic DBG_INSTR_REFs in LiveDebugValuesStephen Tozer
Following support from the previous patches in this stack being added for variadic DBG_INSTR_REFs to exist, this patch modifies LiveDebugValues to handle those instructions. Support already exists for DBG_VALUE_LISTs, which covers most of the work needed to handle these instructions; this patch only modifies the transferDebugInstrRef function to correctly track them. Reviewed By: jmorse Differential Revision: https://reviews.llvm.org/D133927
2023-01-06[DebugInfo][NFC] Add new MachineOperand type and change DBG_INSTR_REF syntaxStephen Tozer
This patch makes two notable changes to the MIR debug info representation, which result in different MIR output but identical final DWARF output (NFC w.r.t. the full compilation). The two changes are: * The introduction of a new MachineOperand type, MO_DbgInstrRef, which consists of two unsigned numbers that are used to index an instruction and an output operand within that instruction, having a meaning identical to first two operands of the current DBG_INSTR_REF instruction. This operand is only used in DBG_INSTR_REF (see below). * A change in syntax for the DBG_INSTR_REF instruction, shuffling the operands to make it resemble DBG_VALUE_LIST instead of DBG_VALUE, and replacing the first two operands with a single MO_DbgInstrRef-type operand. This patch is the first of a set that will allow DBG_INSTR_REF instructions to refer to multiple machine locations in the same manner as DBG_VALUE_LIST. Reviewed By: jmorse Differential Revision: https://reviews.llvm.org/D129372
2022-12-19[DebugInfo] Add function to test debug values for equivalenceStephen Tozer
This patch adds a new function that can be used to check all the properties, other than the machine values, of a pair of debug values for equivalence. This is done by folding the "directness" into the expression, converting the expression to variadic form if it is not already in that form, and then comparing directly. In a few places which check whether two debug values are identical to see if their ranges can be merged, this function will correctly identify cases where two debug values are expressed differently but have the same meaning, allowing those ranges to be correctly merged. Differential Revision: https://reviews.llvm.org/D136173
2022-12-13[CodeGen] llvm::Optional => std::optionalFangrui Song
2022-12-04[llvm] Use std::nullopt instead of None in comments (NFC)Kazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04[llvm] Use std::nullopt instead of None in comments (NFC)Kazu Hirata
This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-12-04DebugInfoMetadata: convert Optional to std::optionalKrzysztof Parzyszek
2022-12-02[CodeGen] Use std::nullopt instead of None (NFC)Kazu Hirata
This patch mechanically replaces None with std::nullopt where the compiler would warn if None were deprecated. The intent is to reduce the amount of manual work required in migrating from Optional to std::optional. This is part of an effort to migrate from llvm::Optional to std::optional: https://discourse.llvm.org/t/deprecating-llvm-optional-x-hasvalue-getvalue-getvalueor/63716
2022-09-01Reapply "[DebugInfo] Extend the InstrRef LDV to support DbgValues with many Ops"Stephen Tozer
Re-landing with an erroneous assert removed. This reverts commit 58d104b352a65bec3fb7a8fd23bf2d408b4c76f7.
2022-08-24Revert "[DebugInfo] Extend the InstrRef LDV to support DbgValues with many Ops"Stephen Tozer
Reverting due to reported errors when running Linux kernel builds with KMSAN -gdwarf-4. This reverts commit 2cb9e1ac422f46de0ab728c6c9d50ebafbfe372a.
2022-08-23[DebugInfo] Extend the InstrRef LDV to support DbgValues with many OpsStephen Tozer
This patch builds on prior support patches to enable support for variadic debug values in InstrRefLDV, allowing DBG_VALUE_LISTs to have their ranges extended. Differential Revision: https://reviews.llvm.org/D128212
2022-08-23[DebugInfo][InstrRef] Handle transfers of variadic debug values in LDVStephen Tozer
This patch adds the last of the changes required to enable DBG_VALUE_LIST handling in InstrRefLDV, handling variadic debug values during the transfer tracking step. Most of the changes are fairly straightforward, and based around tracking multiple locations per variable in TransferTracker::VLocTracker. Differential Revision: https://reviews.llvm.org/D128211
2022-08-23[DebugInfo][InstrRef][NFC] Emit variadic debug values from InstrRefLDVStephen Tozer
In preparation for supporting DBG_VALUE_LIST in InstrRefLDV, this patch adds the logic for emitting DBG_VALUE_LIST instructions from InstrRefLDV. The logical changes here are fairly simple, with the main change being that instead of directly prepending offsets to the DIExpr, we use appendOpsToArg to modify the expression for individual debug operands in the expression. The function emitLoc is also changed to take a list of debug ops, with an empty list meaning an undef value. Differential Revision: https://reviews.llvm.org/D128209
2022-08-22[DebugInfo] Let InstrRefBasedLDV handle joins for lists of debug opsStephen Tozer
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. Differential Revision: https://reviews.llvm.org/D128180
2022-08-22[LiveDebugValues] Fix a warningKazu Hirata
This patch fixes: llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.h:330:5: error: anonymous types declared in an anonymous union are an extension [-Werror,-Wnested-anon-types]
2022-08-22[DebugInfo][NFC] Represent DbgValues with multiple ops in IRefLDVStephen Tozer
In preparation for allowing InstrRefBasedLDV to handle DBG_VALUE_LIST, this patch updates the internal representation that it uses to represent debug values to store a list of values. This is one of the more significant changes in terms of line count, but is fairly simple and should not affect the output of this pass. Differential Revision: https://reviews.llvm.org/D128177
2022-08-22[DebugInfo][NFC] Update LDV to use generic DBG_VALUE* MI interfaceStephen Tozer
Currently, InstrRefLDV only handles DBG_VALUE instructions, not DBG_VALUE_LIST, and as a result of this it handles these instructions using functions that only work for that type of debug value, i.e. using getOperand(0) to get the debug operand. This patch changes this to use the generic debug value functions, such as getDebugOperand and isDebugOffsetImm, as well as adding an IsVariadic field to the DbgValueProperties class and a few other minor changes to acknowledge DBG_VALUE_LISTs. Note that this patch does not add support for DBG_VALUE_LIST here, but is a precursor to other patches that do add that support. Differential Revision: https://reviews.llvm.org/D128174
2022-05-12[DebugInfo][InstrRef] Describe value sizes when spilt to stackJeremy Morse
This is a re-apply of D123599, which was reverted in 4fe2ab5279408, now with a more appropriate assertion. Original commit message follow: InstrRefBasedLDV can track and describe variable values that are spilt to the stack -- however it does not current describe the size of the value on the stack. This can cause uninitialized bytes to be read from the stack if a small register is spilt for a larger variable, or theoretically on big-endian machines if a large value on the stack is used for a small variable. Fix this by using DW_OP_deref_size to specify the amount of data to load from the stack, if there's any possibility for ambiguity. There are a few scenarios where this can be omitted (such as when using DW_OP_piece and a non-DW_OP_stack_value location), see deref-spills-with-size.mir for an explicit table of inputs flavours and output expressions. Differential Revision: https://reviews.llvm.org/D123599
2022-05-05Fix "the the" typo in documentation and user facing stringsBrian Tracy
There are many more instances of this pattern, but I chose to limit this change to .rst files (docs), anything in libcxx/include, and string literals. These have the highest chance of being seen by end users. Reviewed By: #libc, Mordante, martong, ldionne Differential Revision: https://reviews.llvm.org/D124708
2022-04-28Revert "[DebugInfo][InstrRef] Describe value sizes when spilt to stack"Zequan Wu
This reverts commit a15b66e76d1ecff625a4bbb4a46ff83a43138f49. This causes linker to crash at assertion: `Assertion failed: !Expr->isComplex(), file C:\b\s\w\ir\cache\builder\src\third_party\llvm\llvm\lib\CodeGen\LiveDebugValues\InstrRefBasedImpl.cpp, line 907`.
2022-04-27[DebugInfo][InstrRef] Describe value sizes when spilt to stackJeremy Morse
InstrRefBasedLDV can track and describe variable values that are spilt to the stack -- however it does not current describe the size of the value on the stack. This can cause uninitialized bytes to be read from the stack if a small register is spilt for a larger variable, or theoretically on big-endian machines if a large value on the stack is used for a small variable. Fix this by using DW_OP_deref_size to specify the amount of data to load from the stack, if there's any possibility for ambiguity. There are a few scenarios where this can be omitted (such as when using DW_OP_piece and a non-DW_OP_stack_value location), see deref-spills-with-size.mir for an explicit table of inputs flavours and output expressions. Differential Revision: https://reviews.llvm.org/D123599
2022-03-16Cleanup codegen includesserge-sans-paille
This is a (fixed) recommit of https://reviews.llvm.org/D121169 after: 1061034926 before: 1063332844 Discourse thread: https://discourse.llvm.org/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D121681
2022-03-10Revert "Cleanup codegen includes"Nico Weber
This reverts commit 7f230feeeac8a67b335f52bd2e900a05c6098f20. Breaks CodeGenCUDA/link-device-bitcode.cu in check-clang, and many LLVM tests, see comments on https://reviews.llvm.org/D121169
2022-03-10Cleanup codegen includesserge-sans-paille
after: 1061034926 before: 1063332844 Differential Revision: https://reviews.llvm.org/D121169
2022-03-01[DebugInfo][InstrRef][NFC] Use unique_ptr instead of raw pointersJeremy Morse
InstrRefBasedLDV allocates some big tables of ValueIDNum, to store live-in and live-out block values in, that then get passed around as pointers everywhere. This patch wraps the allocation in a std::unique_ptr, names some types based on unique_ptr, and passes references to those around instead. There's no functional change, but it makes it clearer to the reader that references to these tables are borrowed rather than owned, and we get some extra validity assertions too. Differential Revision: https://reviews.llvm.org/D118774
2022-02-10[DebugInfo][InstrRef] Don't fire assertions if debug-info is faultyJeremy Morse
It's inevitable that optimisation passes will fail to update debug-info: when that happens, it's best if the compiler doesn't crash as a result. Therefore, downgrade a few assertions / failure modes that would crash when illegal debug-info was seen, to instead drop variable locations. In practice this means that an instruction reference to a nonexistant or illegal operand should be tolerated. Differential Revision: https://reviews.llvm.org/D118998
2022-02-02[DebugInfo][InstrRef][NFC] Use depth-first scope search for variable locsJeremy Morse
This patch aims to reduce max-rss from instruction referencing, by avoiding keeping variable value information in memory for too long. Instead of computing all the variable values then emitting them to DBG_VALUE instructions, this patch tries to stream the information out through a depth first search: * Make use of the fact LexicalScopes gives a depth-number to each lexical scope, * Produce a map that identifies the last lexical scope to make use of a block, * Enumerate each scope in LexicalScopes' DFS order, solving the variable value problem, * After each scope is processed, look for any blocks that won't be used by any other scope, and emit all the variable information to DBG_VALUE instructions. Differential Revision: https://reviews.llvm.org/D118460
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] 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