summaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/DwarfExpression.cpp
AgeCommit message (Collapse)Author
2025-02-27[CodeGen][NVPTX] Add a TRI function get the Dwarf register number for a ↵Craig Topper
virtual register. (#129017) NVPTX needs to be able to get the Dwarf register number for a virtual register. The interface we have for this today is on MCRegisterInfo and take a MCRegister argument. It shouldn't be legal to convert a Register containing a virtual register to an MCRegister. This patch adds a getDwarfRegNumForVirtReg function that takes a Register to TRI and splits the NVPTX override of getDwarfRegNum.
2024-09-26[NVPTX] add support for encoding PTX registers for DWARF (#109495)William G Hatch
This patch adds support for encoding PTX registers for DWARF, using the encoding supported by nvcc and cuda-gcc. There are some other features still needed for proper register debugging that this patch does not address, such as DW_AT_address_class. This PR is stacked on: https://github.com/llvm/llvm-project/pull/109494
2024-09-26[llvm] use 64-bit types for result of getDwarfRegNum (NFC) (#109494)William G Hatch
The register encoding used by NVPTX and cuda-gdb basically use strings encoded as numbers. They are always within 64-bits, but typically outside of 32-bits, since they often need at least 5 characters. This patch changes the signature of `MCRegisterInfo::getDwarfRegNum` and some related data structures to use 64-bit numbers to accommodate encodings like this. Additionally, `MCRegisterInfo::getDwarfRegNum` is marked as virtual, so that targets with peculiar dwarf register mapping schemes (such as NVPTX) can override its behavior. I originally tried to do a broader switch to 64-bit types for registers, but it caused many problems. There are various places in code generation where registers are not just treated as 32-bit numbers, but also treat certain bit offsets as flags. So I limited the change as much as possible to just the output of `getDwarfRegNum`. Keeping the types used by `DwarfLLVMRegPair` as unsigned preserves the current behaviors. The only way to give a 64-bit output from `getDwarfRegNum` that actually needs more than 32-bits is to override `getDwarfRegNum` and provide an implementation that sidesteps the use of the `DwarfLLVMRegPair` maps defined in tablegen files. First layer of stack supporting: https://github.com/llvm/llvm-project/pull/109495
2024-07-11[DebugInfo] Use DW_OP_deref_size for DW_OP_LLVM_extract_bits (#97609)John Brawn
Using DW_OP_deref can result in the debugger reading past the end of an object into inaccessible memory, causing an error. Instead use DW_OP_deref_size to make sure we don't read any bytes beyond what we need to.
2024-06-07[DebugInfo] Add DW_OP_LLVM_extract_bits (#93990)John Brawn
This operation extracts a number of bits at a given offset and sign or zero extends them, which is done by emitting it as a left shift followed by a right shift. This is being added for use in clang for C++ structured bindings of bitfields that have offset or size that aren't a byte multiple. A new operation is being added, instead of shifts being used directly, as it makes correctly handling it in optimisations (which will be done in a later patch) much easier.
2023-08-23[AsmPrinter][DebugInfo] Create EntryValue mode for DbgVariableFelipe de Azevedo Piovezan
With D149881, we converted EntryValue MachineFunction table entries into `DbgVariables` initialized by a "DbgValue" intrinsic, which can only handle a single, non-fragment DIExpression. However, it is desirable to handle variables with multiple fragments and DIExpressions. To do this, we expand the `DbgVariable` class to handle the EntryValue case. This class can already operate under three different "modes" (stack slot, unchanging location described by a dbg value, changing location described by a loc list). A fourth case is added as a separate class entirely, but a subsequent patch should redesign `DbgVariable` with four subclasses in order to make the code more readable. This patch also exposed a bug in the `beginEntryValueExpression` function, which was not initializing the `LocationFlags` properly. Note how the `finalizeEntryValue` function resets that flag. We fix this bug here, as testing this changing in isolation would be tricky. Differential Revision: https://reviews.llvm.org/D158458
2023-05-23Add support for salvaging debug info from icmp instrcuctions.Shubham Sandeep Rastogi
salvageDebugInfo is a function that allows us to reatin debug info for instructions that have been optimized out. Currently, it doesn't support salvaging the debug information from icmp instrcutions, but DWARF expressions can emulate an icmp by using the DWARF conditional expressions. This patch adds support for salvaging debug information from icmp instructions. Differential Revision: https://reviews.llvm.org/D150216
2023-04-18[MC] Use subregs/superregs instead of MCSubRegIterator/MCSuperRegIterator. NFC.Jay Foad
Differential Revision: https://reviews.llvm.org/D148613
2023-01-13[CodeGen] Remove uses of Register::isPhysicalRegister/isVirtualRegister. NFCCraig Topper
Use isPhysical/isVirtual methods. Reviewed By: foad Differential Revision: https://reviews.llvm.org/D141715
2022-12-13[CodeGen] llvm::Optional => std::optionalFangrui Song
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-08-20Remove redundant initialization of Optional (NFC)Kazu Hirata
2022-04-15[DWARF][FIX] Handle the use of multiple registers gracefullyJohannes Doerfert
Certain applications crashed for us with the AMDGPU backend. While this is not a proper fix it allows us to compile the code for now. I left a TODO for someone that understands DWARF. Differential Revision: https://reviews.llvm.org/D123717
2022-01-31Fix a fragment overflow problem when composing super-registers.Adrian Prantl
Addresses https://github.com/llvm/llvm-project/issues/53342 Differential Revision: https://reviews.llvm.org/D118412
2022-01-26Fix UB in DwarfExpression::emitLegacyZExt()Adrian Prantl
A shift-left > 63 triggers a UBSAN failure. This patch kicks the can down the road (to the consumer) by emitting a more compact representation of the shift computation in DWARF expressions. Relanding (I accidentally pushed an earlier version of the patch previously). Differential Revision: https://reviews.llvm.org/D118183
2022-01-26Revert "Fix UB in DwarfExpression::emitLegacyZExt()"Adrian Prantl
This reverts commit 216002c4bb708e6d6fd1895c8ea636470961f824 while investigating bot breakage.
2022-01-26Fix UB in DwarfExpression::emitLegacyZExt()Adrian Prantl
A shift-left > 63 triggers a UBSAN failure. This patch kicks the can down the road (to the consumer) by emitting a more compact representation of the shift computation in DWARF expressions. Differential Revision: https://reviews.llvm.org/D118183
2022-01-25Revert accidentally pushed commit. It was not yet reviewed.Adrian Prantl
"Fix UB in DwarfExpression::emitLegacyZExt()" This reverts commit e37de5d36e3190283916604342b029859129e2a4.
2022-01-25Fix UB in DwarfExpression::emitLegacyZExt()Adrian Prantl
A shift-left > 63 triggers a UBSAN failure. This patch kicks the can down the road (to the consumer) by emitting a more compact representation of the shift computation in DWARF expressions. Differential Revision: https://reviews.llvm.org/D118183
2021-12-10[DwarfDebug] Refuse to emit DW_OP_LLVM_arg values wider than 64 bitsAdrian Prantl
DwarfExpression::addUnsignedConstant(const APInt &Value) only supports wider-than-64-bit values when it is used to emit a top-level DWARF expression representing the location of a variable. Before this change, it was possible to call addUnsignedConstant on >64 bit values within a subexpression when substituting DW_OP_LLVM_arg values. This can trigger an assertion failure (e.g. PR52584, PR52333) when it happens in a fragment (DW_OP_LLVM_fragment) expression, as addUnsignedConstant on >64 bit values splits the constant into separate DW_OP_pieces, which modifies DwarfExpression::OffsetInBits. This change papers over the assertion errors by bailing on overly wide DW_OP_LLVM_arg values. A more comprehensive fix might be to be to split wide values into pointer-sized fragments. [0] https://github.com/llvm/llvm-project/blob/e71fa03/llvm/lib/CodeGen/AsmPrinter/DwarfCompileUnit.cpp#L799-L805 Patch by Ricky Zhou! Differential Revision: https://reviews.llvm.org/D115343
2021-03-11Fix unused lambda capture in a non-asserts buildDavid Blaikie
For locally scoped lambdas like this there's no particular benefit to explicitly listing captures - or avoiding capturing this. Switch to [&] and make it all easier to maintain. (& driveby change std::function to llvm::function_ref)
2021-03-10Reapply "[DebugInfo] Add DWARF emission for DBG_VALUE_LIST"Stephen Tozer
This reverts commit 429c6ecbb302e2beedd8694378ae5be456206209.
2021-03-10Revert "[DebugInfo] Add DWARF emission for DBG_VALUE_LIST"Stephen Tozer
This reverts commit 0da27ba56c9f5e3f534a65401962301189eac342. This revision was causing an error on the sanitizer-x86_64-linux-autoconf build.
2021-03-10[DebugInfo] Add DWARF emission for DBG_VALUE_LISTgbtozers
This patch allows DBG_VALUE_LIST instructions to be emitted to DWARF with valid DW_AT_locations. This change mainly affects DbgEntityHistoryCalculator, which now tracks multiple registers per value, and DwarfDebug+DwarfExpression, which can now emit multiple machine locations as part of a DWARF expression. Differential Revision: https://reviews.llvm.org/D83495
2021-02-18Reset the EntryValue location flag in finalizeEntryValue.Adrian Prantl
This fixes an assertion error when entry values are combined with DW_OP_LLVM_fragment.
2021-02-15Support emitting complex expressions that include entry valuesAdrian Prantl
This patch enables AsmPrinter support for complex expression with entry values. It shouldn't AsmPrinter's call whether these are safe or not but the pass who introduces the DW_OP_LLVM_entry_value. This patch on its own has no effect on clang. Differential Revision: https://reviews.llvm.org/D96559
2021-02-12Store the LocationKind of an entry value buffer independently from the main ↵Adrian Prantl
LocationKind (NFC) This patch hides the logic for setting the location kind of an entry value inside the begin/finalize/cancel functions. This way we get rid the strange workaround that is currently in setLocation(). In the future, this will allow us to set the location kind of the entry value independently from the location kind of the main expression. Differential Revision: https://reviews.llvm.org/D96554
2021-02-05[WebAssembly] locals can now be indirect in DWARFWouter van Oortmerssen
This for example to indicate that byval args are represented by a pointer to a struct. Followup to https://reviews.llvm.org/D94140 Differential Revision: https://reviews.llvm.org/D94347
2020-11-24Revert "[DebugInfo] Refactor code for emitting DWARF expressions for FP ↵Pavel Labath
constants" The commit introduced a crash when emitting (debug info for) complex floats (pr48277).
2020-11-23[DebugInfo] Refactor code for emitting DWARF expressions for FP constantsPavel Labath
This patch moves the selection of the style used to emit the numbers (DW_OP_implicit_value vs. DW_OP_const+DW_OP_stack_value) into DwarfExpression::addUnsignedConstant. This logic is not FP-specific, and it will be needed for large integers too. The refactor also makes DW_OP_implicit_value (DW_OP_stack_value worked already) be used for floating point constants other than float and double, so I've added a _Float16 test for it. Split off from D90916. Differential Revision: https://reviews.llvm.org/D91058
2020-11-06AsmPrinter/Dwarf*: Use llvm::Register instead of unsignedFangrui Song
2020-10-29[DebugInfo] [NFCI] Adding a missed out line in support for ↵Alok Kumar Sharma
DW_TAG_generic_subrange. This commit adds a missed out line in earlier commit for DW_TAG_generic_subrange. Previous commit ID: a6dd01afa3d5902203d04a72e0b478078f796a35 Differential Revision: https://reviews.llvm.org/D89218 Thanks markus for pointing this out.
2020-10-28Revert "[DebugInfo] Fix legacy ZExt emission when FromBits >= 64 (PR47927)"Vedant Kumar
This reverts commit 99053462216cf835eb3ae063942c618d9609de87. It breaks the compiler-rt build, see https://reviews.llvm.org/D89838
2020-10-28Revert "[DebugInfo] Shorten legacy [s|z]ext dwarf expressions"Vedant Kumar
This reverts commit 2ce36ebca544dd71075a7818ff4070da5667603b. It depends on https://reviews.llvm.org/D89838, which needs to be reverted.
2020-10-29[DebugInfo] Support for DW_TAG_generic_subrangeAlok Kumar Sharma
This is needed to support fortran assumed rank arrays which have runtime rank. Summary: Fortran assumed rank arrays have dynamic rank. DWARF TAG DW_TAG_generic_subrange is needed to support that. Testing: unit test cases added (hand-written) check llvm check debug-info Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D89218
2020-10-28[DebugInfo] Shorten legacy [s|z]ext dwarf expressionsVedant Kumar
Take advantage of the emitConstu helper to emit slightly shorter dwarf expressions to implement legacy [s|z]ext operations.
2020-10-28[DebugInfo] Fix legacy ZExt emission when FromBits >= 64 (PR47927)Vedant Kumar
Fix an out-of-bounds shift in emitLegacyZExt by using a slightly more complicated dwarf expression to create the zext mask. This addresses a UBSan diagnostic seen when compiling compiler-rt (llvm.org/PR47927). rdar://70307714 Differential Revision: https://reviews.llvm.org/D89838
2020-10-22DWARFv5: Disable DW_OP_convert for configurations that don't yet support itDavid Blaikie
Testing reveals that lldb and gdb have some problems with supporting DW_OP_convert - gdb with Split DWARF tries to resolve the CU-relative DIE offset relative to the skeleton DIE. lldb tries to treat the offset as absolute, which judging by the llvm-dsymutil support for DW_OP_convert, I guess works OK in MachO? (though probably llvm-dsymutil is producing invalid DWARF by resolving the relative reference to an absolute one?). Specifically this disables DW_OP_convert usage in DWARFv5 if: * Tuning for GDB and using Split DWARF * Tuning for LLDB and not targeting MachO
2020-10-17[DebugInfo] Support for DWARF operator DW_OP_overAlok Kumar Sharma
LLVM rejects DWARF operator DW_OP_over. This DWARF operator is needed for Flang to support assumed rank array. Summary: Currently LLVM rejects DWARF operator DW_OP_over. Below error is produced when llvm finds this operator. [..] invalid expression !DIExpression(151, 20, 16, 48, 30, 35, 80, 34, 6) warning: ignoring invalid debug info in over.ll [..] There were some parts missing in support of this operator, which are now completed. Testing -added a unit testcase -check-debuginfo -check-llvm Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D89208
2020-09-17DwarfExpression.cpp - remove unnecessary includes. NFCI.Simon Pilgrim
Already included in DwarfExpression.h
2020-08-20[DebugInfo] Fix DwarfExpression::addConstantFP for float on big-endianBjorn Pettersson
The byte swapping, when dealing with 4 byte (float) FP constants in DwarfExpression::addConstantFP, added in commit ef8992b9f0189005 was not correct. It always performed byte swapping using an uint64_t value. When dealing with 4 byte values the 4 interesting bytes ended up in the big end of the uint64_t, but later we emitted the 4 bytes at the little end. So we ended up with zeroes being emitted and faulty debug information. This patch simplifies things a bit, IMHO. Using the APInt representation throughout the function, instead of looking at the internal representation using getRawBytes and without using reinterpret_cast etc. And using API.byteSwap() should result in correct byte swapping independent of APInt being 4 or 8 bytes. Differential Revision: https://reviews.llvm.org/D86272
2020-08-20Re-apply "[DebugInfo] Emit DW_OP_implicit_value for Floating point constants"Sourabh Singh Tomar
This patch was reverted in 7c182663a857fc87 due to some failures observed on PCC based machines. Failures were due to Endianness issue and long double representation issues. Patch is revised to address Endianness issue. Furthermore, support for emission of `DW_OP_implicit_value` for `long double` has been removed (since it was unclean at the moment). Planning to handle this in a clean way soon! For more context, please refer to following review link. Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D83560
2020-08-20Revert "[DebugInfo] Emit DW_OP_implicit_value for Floating point constants"Sourabh Singh Tomar
This reverts commit 15801f16194a3d. arc's land messed up! It removed the new commit message and took it from revision.
2020-08-20[DebugInfo] Emit DW_OP_implicit_value for Floating point constantsSourabh Singh Tomar
llvm is missing support for DW_OP_implicit_value operation. DW_OP_implicit_value op is indispensable for cases such as optimized out long double variables. For intro refer: DWARFv5 Spec Pg: 40 2.6.1.1.4 Implicit Location Descriptions Consider the following example: ``` int main() { long double ld = 3.14; printf("dummy\n"); ld *= ld; return 0; } ``` when compiled with tunk `clang` as `clang test.c -g -O1` produces following location description of variable `ld`: ``` DW_AT_location (0x00000000: [0x0000000000201691, 0x000000000020169b): DW_OP_constu 0xc8f5c28f5c28f800, DW_OP_stack_value, DW_OP_piece 0x8, DW_OP_constu 0x4000, DW_OP_stack_value, DW_OP_bit_piece 0x10 0x40, DW_OP_stack_value) DW_AT_name ("ld") ``` Here one may notice that this representation is incorrect(DWARF4 stack could only hold integers(and only up to the size of address)). Here the variable size itself is `128` bit. GDB and LLDB confirms this: ``` (gdb) p ld $1 = <invalid float value> (lldb) frame variable ld (long double) ld = <extracting data from value failed> ``` GCC represents/uses DW_OP_implicit_value in these sort of situations. Based on the discussion with Jakub Jelinek regarding GCC's motivation for using this, I concluded that DW_OP_implicit_value is most appropriate in this case. Link: https://gcc.gnu.org/pipermail/gcc/2020-July/233057.html GDB seems happy after this patch:(LLDB doesn't have support for DW_OP_implicit_value) ``` (gdb) p ld p ld $1 = 3.14000000000000012434 ``` Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D83560
2020-07-27Revert "Re-apply:" Emit DW_OP_implicit_value for Floating point constants""Amy Kwan
This patch reverts commit `59a76d957a26` as it has caused failure on the big endian PowerPC buildbots (as well as the SystemZ buildbots).
2020-07-23Re-apply:" Emit DW_OP_implicit_value for Floating point constants"Sourabh Singh Tomar
This patch was reverted in 9d2da6759b4d due to assertion failure seen in `test/DebugInfo/Sparc/subreg.ll`. Assertion failure was happening due to malformed/unhandeled DwarfExpression. Differential Revision: https://reviews.llvm.org/D83560
2020-07-23Revert "[DebugInfo] Emit DW_OP_implicit_value for Floating point constants"Sourabh Singh Tomar
This reverts commit 6b55a95898e98664164caae4aba7c5e24fd1a05e. Temporal revert due to a failing/assertion in test case in Sparc backend. `test/DebugInfo/Sparc/subreg.ll` Seen in lot of bots, for instance in: `http://lab.llvm.org:8011/builders/llvm-clang-x86_64-expensive-checks-win/builds/24679`
2020-07-23[DebugInfo] Emit DW_OP_implicit_value for Floating point constantsSourabh Singh Tomar
Summary: llvm is missing support for DW_OP_implicit_value operation. DW_OP_implicit_value op is indispensable for cases such as optimized out long double variables. For intro refer: DWARFv5 Spec Pg: 40 2.6.1.1.4 Implicit Location Descriptions Consider the following example: ``` int main() { long double ld = 3.14; printf("dummy\n"); ld *= ld; return 0; } ``` when compiled with tunk `clang` as `clang test.c -g -O1` produces following location description of variable `ld`: ``` DW_AT_location (0x00000000: [0x0000000000201691, 0x000000000020169b): DW_OP_constu 0xc8f5c28f5c28f800, DW_OP_stack_value, DW_OP_piece 0x8, DW_OP_constu 0x4000, DW_OP_stack_value, DW_OP_bit_piece 0x10 0x40, DW_OP_stack_value) DW_AT_name ("ld") ``` Here one may notice that this representation is incorrect(DWARF4 stack could only hold integers(and only up to the size of address)). Here the variable size itself is `128` bit. GDB and LLDB confirms this: ``` (gdb) p ld $1 = <invalid float value> (lldb) frame variable ld (long double) ld = <extracting data from value failed> ``` GCC represents/uses DW_OP_implicit_value in these sort of situations. Based on the discussion with Jakub Jelinek regarding GCC's motivation for using this, I concluded that DW_OP_implicit_value is most appropriate in this case. Link: https://gcc.gnu.org/pipermail/gcc/2020-July/233057.html GDB seems happy after this patch:(LLDB doesn't have support for DW_OP_implicit_value) ``` (gdb) p ld p ld $1 = 3.14000000000000012434 ``` Reviewed By: aprantl Differential Revision: https://reviews.llvm.org/D83560
2020-07-01[DebugInfo] Do not emit entry values for composite locationsDavid Stenberg
Summary: This is a fix for PR45009. When working on D67492 I made DwarfExpression emit a single DW_OP_entry_value operation covering the whole composite location description that is produced if a register does not have a valid DWARF number, and is instead composed of multiple register pieces. Looking closer at the standard, this appears to not be valid DWARF. A DW_OP_entry_value operation's block can only be a DWARF expression or a register location description, so it appears to not be valid for it to hold a composite location description like that. See DWARFv5 sec. 2.5.1.7: "The DW_OP_entry_value operation pushes the value that the described location held upon entering the current subprogram. It has two operands: an unsigned LEB128 length, followed by a block containing a DWARF expression or a register location description (see Section 2.6.1.1.3 on page 39)." Here is a dwarf-discuss mail thread regarding this: http://lists.dwarfstd.org/pipermail/dwarf-discuss-dwarfstd.org/2020-March/004610.html There was not a strong consensus reached there, but people seem to lean towards that operations specified under 2.6 (e.g. DW_OP_piece) may not be part of a DWARF expression, and thus the DW_OP_entry_value operation can't contain those. Perhaps we instead want to emit a entry value operation per each DW_OP_reg* operation, e.g.: - DW_OP_entry_value(DW_OP_regx sub_reg0), DW_OP_stack_value, DW_OP_piece 8, - DW_OP_entry_value(DW_OP_regx sub_reg1), DW_OP_stack_value, DW_OP_piece 8, [...] The question then becomes how the call site should look; should a composite location description be emitted there, and we then leave it up to the debugger to match those two composite location descriptions? Another alternative could be to emit a call site parameter entry for each sub-register, but firstly I'm unsure if that is even valid DWARF, and secondly it seems like that would complicate the collection of call site values quite a bit. As far as I can tell GCC does not emit any entry values / call sites in these cases, so we do not have something to compare with, but the former seems like the more reasonable approach. Currently when trying to emit a call site entry for a parameter composed of multiple DWARF registers a (DwarfRegs.size() == 1) assert is triggered in addMachineRegExpression(). Until the call site representation is figured out, and until there is use for these entry values in practice, this commit simply stops the invalid DWARF from being emitted. Reviewers: djtodoro, vsk, aprantl Reviewed By: djtodoro, vsk Subscribers: jyknight, hiraditya, fedor.sergeev, jrtc27, llvm-commits Tags: #debug-info, #llvm Differential Revision: https://reviews.llvm.org/D75270
2020-05-26[DwarfExpression] Support entry values for indirect parametersVedant Kumar
Summary: A struct argument can be passed-by-value to a callee via a pointer to a temporary stack copy. Add support for emitting an entry value DBG_VALUE when an indirect parameter DBG_VALUE becomes unavailable. This is done by omitting DW_OP_stack_value from the entry value expression, to make the expression describe the location of an object. rdar://63373691 Reviewers: djtodoro, aprantl, dstenb Subscribers: hiraditya, lldb-commits, llvm-commits Tags: #lldb, #llvm Differential Revision: https://reviews.llvm.org/D80345