aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/DebugInfoMetadata.cpp
AgeCommit message (Collapse)AuthorFilesLines
2023-11-02[DebugInfo][RemoveDIs] Add prototype storage classes for "new" debug-infoJeremy Morse1-2/+8
This patch adds a variety of classes needed to record variable location debug-info without using the existing intrinsic approach, see the rationale at [0]. The two added files and corresponding unit tests are the majority of the plumbing required for this, but at this point isn't accessible from the rest of LLVM as we need to stage it into the repo gently. An overview is that classes are added for recording variable information attached to Real (TM) instructions, in the form of DPValues and DPMarker objects. The metadata-uses of DPValues is plumbed into the metadata hierachy, and a field added to class Instruction, which are all stimulated in the unit tests. The next few patches in this series add utilities to convert to/from this new debug-info format and add instruction/block utilities to have debug-info automatically updated in the background when various operations occur. This patch was reviewed in Phab in D153990 and D154080, I've squashed them together into this commit as there are dependencies between the two patches, and there's little profit in landing them separately. [0] https://discourse.llvm.org/t/rfc-instruction-api-changes-needed-to-eliminate-debug-intrinsics-from-ir/68939
2023-09-15[DebugInfo] Process single-location debug values in variadic form when ↵Stephen Tozer1-35/+66
producing DWARF Revision c383f4d6550e enabled using variadic-form debug values to represent single-location, non-stack-value debug values, and a further patch made all DBG_INSTR_REFs use variadic form. Not all code paths were updated correctly to handle the new syntax however, with entry values in still expecting an expression that begins exactly DW_OP_LLVM_entry_value, 1. A function already exists to select non-variadic-like expressions; this patch adds an extra function to cheaply simplify such cases to non-variadic form, which we use prior to any entry-value processing to put DBG_INSTR_REFs and DBG_VALUEs down the same code path. We also use it for a few DIExpression functions that check for whether the first element(s) of a DIExpression match a particular pattern, so that they will return the same result for DIExpression(DW_OP_LLVM_arg, 0, <ops>) as for DIExpression(<ops>). Differential Revision: https://reviews.llvm.org/D158185
2023-06-14[DebugInfo] Always emit `.debug_names` with DWARF 5 for Apple platformsJonas Devlieghere1-0/+3
On Apple platforms, we generate .apple_names, .apple_types, .apple_namespaces and .apple_objc Apple accelerator tables for DWARF 4 and earlier. For DWARF 5 we should generate .debug_names, but instead we get no accelerator tables at all. In the backend we are correctly determining that we should be emitting .debug_names instead of .apple_names. However, when we get to the point of emitting the section, if the CU debug name table kind is not "default", the accelerator table emission is skipped. This patch sets the DebugNameTableKind to Apple in the frontend when target an Apple target. That way we know that the CU was compiled with the intent of emitting accelerator tables. For DWARF 4 and earlier, that means Apple accelerator tables. For DWARF 5 and later, that means .debug names. Differential revision: https://reviews.llvm.org/D118754
2023-06-14Revert "[DebugInfo] Always emit `.debug_names` with DWARF 5 for Apple platforms"Jonas Devlieghere1-3/+0
This reverts commit e0d57295bf6a3c04f2901d9c70f529d570f48b65 because the accel-tables-apple.ll test is failing on a few buildbots.
2023-06-14[DebugInfo] Always emit `.debug_names` with DWARF 5 for Apple platformsJonas Devlieghere1-0/+3
On Apple platforms, we generate .apple_names, .apple_types, .apple_namespaces and .apple_objc Apple accelerator tables for DWARF 4 and earlier. For DWARF 5 we should generate .debug_names, but instead we get no accelerator tables at all. In the backend we are correctly determining that we should be emitting .debug_names instead of .apple_names. However, when we get to the point of emitting the section, if the CU debug name table kind is not "default", the accelerator table emission is skipped. This patch sets the DebugNameTableKind to Apple in the frontend when target an Apple target. That way we know that the CU was compiled with the intent of emitting accelerator tables. For DWARF 4 and earlier, that means Apple accelerator tables. For DWARF 5 and later, that means .debug names. Differential revision: https://reviews.llvm.org/D118754
2023-05-23Add support for salvaging debug info from icmp instrcuctions.Shubham Sandeep Rastogi1-0/+6
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-05-15[IR] Drop const in DILocation::getMergedLocationChristian Ulmann1-5/+3
This commit removes constness from DILocation::getMergedLocation and fixes all its users accordingly. Having constness on the parameters forced the return type to be const as well, which does force usage of `const_cast` when the location needs to be used in metadata nodes. Reviewed By: ftynse Differential Revision: https://reviews.llvm.org/D149942
2023-04-25[DebugInfo] Replace UndefValue with PoisonValue in ↵OCHyams1-1/+1
DIArgList::handleChangedOperand This helps towards the effort to remove UndefValue from LLVM. Related to https://discourse.llvm.org/t/auto-undef-debug-uses-of-a-deleted-value Reviewed By: nlopes Differential Revision: https://reviews.llvm.org/D140991
2023-03-22[NFC] Add DebugVariableAggregate classOCHyams1-0/+4
A DebugVariableAggregate is a DebugVariable that discards FragmentInfo; it represents a whole variable instance. Reviewed By: StephenTozer Differential Revision: https://reviews.llvm.org/D146298
2023-03-15Use *{Map,Set}::contains (NFC)Kazu Hirata1-1/+1
Differential Revision: https://reviews.llvm.org/D146104
2023-03-06[DebugInfo] Merge partially matching chains of inlined locationsDavid Stenberg1-50/+110
For example, if you have a chain of inlined funtions like this: 1 #include <stdlib.h> 2 int g1 = 4, g2 = 6; 3 4 static inline void bar(int q) { 5 if (q > 5) 6 abort(); 7 } 8 9 static inline void foo(int q) { 10 bar(q); 11 } 12 13 int main() { 14 foo(g1); 15 foo(g2); 16 return 0; 17 } with optimizations you could end up with a single abort call for the two inlined instances of foo(). When merging the locations for those inlined instances you would previously end up with a 0:0 location in main(). Leaving out that inlined chain from the location for the abort call could make troubleshooting difficult in some cases. This patch changes DILocation::getMergedLocation() to try to handle such cases. The function is rewritten to first find a common starting point for the two locations (same subprogram and inlined-at location), and then in reverse traverses the inlined-at chain looking for matches in each subprogram. For each subprogram, the merge function will find the nearest common scope for the two locations, and matching line and column (or set them to 0 if not matching). In the example above, you will for the abort call get a location in bar() at 6:5, inlined in foo() at 10:3, inlined in main() at 0:0 (since the two inlined functions are on different lines, but in the same scope). I have not seen anything in the DWARF standard that would disallow inlining a non-zero location at 0:0 in the inlined-at function, and both LLDB and GDB seem to accept these locations (with D142552 needed for LLDB to handle cases where the file, line and column number are all 0). One incompatibility with GDB is that it seems to ignore 0-line locations in some cases, but I am not aware of any specific issue that this patch produces related to that. With x86-64 LLDB (trunk) you previously got: frame #0: 0x00007ffff7a44930 libc.so.6`abort frame #1: 0x00005555555546ec a.out`main at merge.c:0 and will now get: frame #0: 0x[...] libc.so.6`abort frame #1: 0x[...] a.out`main [inlined] bar(q=<unavailable>) at merge.c:6:5 frame #2: 0x[...] a.out`main [inlined] foo(q=<unavailable>) at merge.c:10:3 frame #3: 0x[...] a.out`main at merge.c:0 and with x86-64 GDB (11.1) you will get: (gdb) bt #0 0x00007ffff7a44930 in abort () from /lib64/libc.so.6 #1 0x00005555555546ec in bar (q=<optimized out>) at merge.c:6 #2 foo (q=<optimized out>) at merge.c:10 #3 0x00005555555546ec in main () Reviewed By: aprantl, dblaikie Differential Revision: https://reviews.llvm.org/D142556
2023-01-30[mem2reg][debuginfo] Handle op_deref when converting dbg.declareFelipe de Azevedo Piovezan1-0/+3
The conversion of dbg.declare into dbg.values doesn't take into account the DIExpression attached to the intrinsic. In particular, when converting: ``` store %val, ptr %alloca dbg.declare(ptr %alloca, !SomeVar, !DIExpression()) ``` Mem2Reg will try to figure out if `%val` has the size of `!SomeVar`. If it does, then a non-undef dbg.value is inserted: ``` dbg.value(%val, !SomeVar, !DIExpression()) ``` This makes sense: the alloca is _the_ address of the variable. So a store to the alloca is a store to the variable. However, if the expression in the original intrinsic is a `DW_OP_deref`, this logic is not applicable: ``` store ptr %val, ptr %alloca dbg.declare(ptr %alloca, !SomeVar, !DIExpression(DW_OP_deref)) ``` Here, the alloca is *not* the address of the variable. A store to the alloca is *not* a store to the variable. As such, querying whether `%val` has the same size as `!SomeVar` is meaningless. This patch addresses the issue by: 1. Allowing the conversion when the expression is _only_ a `DW_OP_deref` without any other expressions (see code comment). 2. Checking that the expression does not start with a `DW_OP_deref` before applying the logic that checks whether the value being stored and the variable have the same length. Differential Revision: https://reviews.llvm.org/D142160
2023-01-09[DebugInfo] Produce variadic DBG_INSTR_REFs from ISelStephen Tozer1-0/+10
This patch modifies SelectionDAG and FastISel to produce DBG_INSTR_REFs with variadic expressions, and produce DBG_INSTR_REFs for debug values with variadic location expressions. The former essentially means just prepending DW_OP_LLVM_arg, 0 to the existing expression. The latter is achieved in MachineFunction::finalizeDebugInstrRefs and InstrEmitter::EmitDbgInstrRef. Reviewed By: jmorse, Orlando Differential Revision: https://reviews.llvm.org/D133929
2023-01-06[DebugInfo] Add support for variadic DBG_INSTR_REFs in LiveDebugValuesStephen Tozer1-0/+21
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] Allow non-stack_value variadic expressions and use in DBG_INSTR_REFStephen Tozer1-6/+51
Prior to this patch, variadic DIExpressions (i.e. ones that contain DW_OP_LLVM_arg) could only be created by salvaging debug values to create stack value expressions, resulting in a DBG_VALUE_LIST being created. As of the previous patch in this patch stack, DBG_INSTR_REF's syntax has been changed to match DBG_VALUE_LIST in preparation for supporting variadic expressions. This patch adds some minor changes needed to allow variadic expressions that aren't stack values to exist, and allows variadic expressions that are trivially reduceable to non-variadic expressions to be handled similarly to non-variadic expressions. Reviewed by: jmorse Differential Revision: https://reviews.llvm.org/D133926
2023-01-05Move from llvm::makeArrayRef to ArrayRef deduction guides - llvm/ partserge-sans-paille1-2/+2
Use deduction guides instead of helper functions. The only non-automatic changes have been: 1. ArrayRef(some_uint8_pointer, 0) needs to be changed into ArrayRef(some_uint8_pointer, (size_t)0) to avoid an ambiguous call with ArrayRef((uint8_t*), (uint8_t*)) 2. CVSymbol sym(makeArrayRef(symStorage)); needed to be rewritten as CVSymbol sym{ArrayRef(symStorage)}; otherwise the compiler is confused and thinks we have a (bad) function prototype. There was a few similar situation across the codebase. 3. ADL doesn't seem to work the same for deduction-guides and functions, so at some point the llvm namespace must be explicitly stated. 4. The "reference mode" of makeArrayRef(ArrayRef<T> &) that acts as no-op is not supported (a constructor cannot achieve that). Per reviewers' comment, some useless makeArrayRef have been removed in the process. This is a follow-up to https://reviews.llvm.org/D140896 that introduced the deduction guides. Differential Revision: https://reviews.llvm.org/D140955
2022-12-19[DebugInfo] Add function to test debug values for equivalenceStephen Tozer1-0/+42
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-12[nfc][DebugInfo] Move subprogram rewriting utility to headerFelipe de Azevedo Piovezan1-0/+29
This utility will be useful in subsequent patches, as such we expose it in the DebugInfoMetadata header. Depends on D139669 Differential Revision: https://reviews.llvm.org/D139670
2022-12-08[DebugInfo] Store optional DIFile::Source as pointerJonas Hahnfeld1-6/+6
getCanonicalMDString() also returns a nullptr for empty strings, which tripped over the getSource() method. Solve the ambiguity of no source versus an optional containing a nullptr by simply storing a pointer. Differential Revision: https://reviews.llvm.org/D138658
2022-12-04DebugInfoMetadata: convert Optional to std::optionalKrzysztof Parzyszek1-24/+28
2022-12-02[IR] Use std::nullopt instead of None (NFC)Kazu Hirata1-11/+11
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-11-07[Assignment Tracking][3/*] Add DIAssignID metadata boilerplateOCHyams1-0/+7
The Assignment Tracking debug-info feature is outlined in this RFC: https://discourse.llvm.org/t/ rfc-assignment-tracking-a-better-way-of-specifying-variable-locations-in-ir Add the DIAssignID metadata attachment boilerplate. Includes a textual-bitcode roundtrip test and tests that the verifier and parser catch badly formed IR. This piece of metadata links together stores (used as an attachment) and the yet-to-be-added llvm.dbg.assign debug intrinsic (used as an operand). Reviewed By: jmorse Differential Revision: https://reviews.llvm.org/D132222
2022-11-03Revert "[Assignment Tracking][3/*] Add DIAssignID metadata boilerplate"OCHyams1-7/+0
This reverts commit c285df77e9b78f971f9cd9d025248c20b030cc2a. A sanitizer bot found an issue: https://lab.llvm.org/buildbot/#/builders/5/builds/28809/steps/13/logs/stdio
2022-11-03[Assignment Tracking][3/*] Add DIAssignID metadata boilerplateOCHyams1-0/+7
The Assignment Tracking debug-info feature is outlined in this RFC: https://discourse.llvm.org/t/ rfc-assignment-tracking-a-better-way-of-specifying-variable-locations-in-ir Add the DIAssignID metadata attachment boilerplate. Includes a textual-bitcode roundtrip test and tests that the verifier and parser catch badly formed IR. This piece of metadata links together stores (used as an attachment) and the yet-to-be-added llvm.dbg.assign debug intrinsic (used as an operand). Reviewed By: jmorse Differential Revision: https://reviews.llvm.org/D132222
2022-10-27Account for memory locations in DIExpression::createFragmentExpressionOCHyams1-1/+21
createFragmentExpression rejects expressions containing certain ops, like DW_OP_plus, that may cause the expression to compute a value that can't be split. Teach createFragmentExpression that the value loaded from an address computed using those ops is safe to split. Update a unittest to account for and test this change. Reviewed By: StephenTozer Differential Revision: https://reviews.llvm.org/D136243
2022-10-25[DebugInfo] getMergedLocation: Maintain the line number if they matchJuan Manuel MARTINEZ CAAMAÑO1-13/+43
getMergedLocation returns a 'line 0' DILocaiton if the two locations being merged don't perfecly match, even if they are in the same line but a different column. This commit adds support to keep the line number if it matches (but only the column differs). The merged column number is the leftmost between the two. Reviewed By: dblaikie, orlando Differential Revision: https://reviews.llvm.org/D135166
2022-10-20[NFC] Add DebugVariable constructor that takes DbgVariableIntrinsic pointerOCHyams1-0/+6
Note: The constructor definition cannot be inline without some refactoring as it introduces a circular dependency between the headers llvm/IR/DebugInfoMetadata.h (this file) and llvm/IR/IntrinsicInst.h (where DbgVariableIntrinsic is defined). Reviewed By: jryans Differential Revision: https://reviews.llvm.org/D133286
2022-09-22[NFC] Remove unused set construction from DILocation::getMergedLocationJuan Manuel MARTINEZ CAAMAÑO1-5/+1
Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D134357
2022-09-08[llvm] Use std::size instead of llvm::array_lengthofJoe Loser1-4/+3
LLVM contains a helpful function for getting the size of a C-style array: `llvm::array_lengthof`. This is useful prior to C++17, but not as helpful for C++17 or later: `std::size` already has support for C-style arrays. Change call sites to use `std::size` instead. Differential Revision: https://reviews.llvm.org/D133429
2022-08-19Fix UB in DIExpression::appendOffset()Adrian Prantl1-1/+4
The absolute value of 0x8000000000000000 does not fit into an int64_t and UBSan tells us that by crashing. rdar://98799670 Differential Revision: https://reviews.llvm.org/D132194
2022-06-20Don't use Optional::hasValue (NFC)Kazu Hirata1-1/+1
2022-06-18[llvm] Use value_or instead of getValueOr (NFC)Kazu Hirata1-1/+1
2022-06-03[llvm] Remove unneeded cl::ZeroOrMore for cl::opt options. NFCFangrui Song1-1/+1
Some cl::ZeroOrMore were added to avoid the `may only occur zero or one times!` error. More were added due to cargo cult. Since the error has been removed, cl::ZeroOrMore is unneeded. Also remove cl::init(false) while touching the lines.
2022-05-13[NFC][Metadata] Refactor allocation, initalization and deletion of MDNodes.Wolfgang Pieb1-8/+10
This patch is refactoring the allocation, initialization and deletion of MDNodes. It is intended as a preparatory patch for the upcoming addition of dynamic resizability of MDNodes. It is fundamentally NFC, but removes the necessity for suppressing the memory sanitizer for MDNode's operator delete. Reviewers: dexonsmith Differential Revision: https://reviews.llvm.org/D125489
2022-04-15[DebugInfo] Add a TargetFuncName field in DISubprogram forChih-Ping Chen1-9/+15
specifying DW_AT_trampoline as a string. Also update the signature of DIBuilder::createFunction to reflect this addition. Differential Revision: https://reviews.llvm.org/D123697
2022-03-08[SampleFDO] Allow multiple of --enable-fs-discrimintor option [NFC]Rong Xu1-1/+1
Allow users to use multiple of --enable-fs-discriminator option. When this option is specified multiple times, the last instance wins.
2022-02-04Reduce dependencies on llvm/BinaryFormat/Dwarf.hserge-sans-paille1-0/+140
This header is very large (3M Lines once expended) and was included in location where dwarf-specific information were not needed. More specifically, this commit suppresses the dependencies on llvm/BinaryFormat/Dwarf.h in two headers: llvm/IR/IRBuilder.h and llvm/IR/DebugInfoMetadata.h. As these headers (esp. the former) are widely used, this has a decent impact on number of preprocessed lines generated during compilation of LLVM, as showcased below. This is achieved by moving some definitions back to the .cpp file, no performance impact implied[0]. As a consequence of that patch, downstream user may need to manually some extra files: llvm/IR/IRBuilder.h no longer includes llvm/BinaryFormat/Dwarf.h llvm/IR/DebugInfoMetadata.h no longer includes llvm/BinaryFormat/Dwarf.h In some situations, codes maybe relying on the fact that llvm/BinaryFormat/Dwarf.h was including llvm/ADT/Triple.h, this hidden dependency now needs to be explicit. $ clang++ -E -Iinclude -I../llvm/include ../llvm/lib/Transforms/Scalar/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l after: 10978519 before: 11245451 Related Discourse thread: https://llvm.discourse.group/t/include-what-you-use-include-cleanup [0] https://llvm-compile-time-tracker.com/compare.php?from=fa7145dfbf94cb93b1c3e610582c495cb806569b&to=995d3e326ee1d9489145e20762c65465a9caeab4&stat=instructions Differential Revision: https://reviews.llvm.org/D118781
2022-02-02Cleanup header dependencies in LLVMCoreserge-sans-paille1-2/+2
Based on the output of include-what-you-use. This is a big chunk of changes. It is very likely to break downstream code unless they took a lot of care in avoiding hidden ehader dependencies, something the LLVM codebase doesn't do that well :-/ I've tried to summarize the biggest change below: - llvm/include/llvm-c/Core.h: no longer includes llvm-c/ErrorHandling.h - llvm/IR/DIBuilder.h no longer includes llvm/IR/DebugInfo.h - llvm/IR/IRBuilder.h no longer includes llvm/IR/IntrinsicInst.h - llvm/IR/LLVMRemarkStreamer.h no longer includes llvm/Support/ToolOutputFile.h - llvm/IR/LegacyPassManager.h no longer include llvm/Pass.h - llvm/IR/Type.h no longer includes llvm/ADT/SmallPtrSet.h - llvm/IR/PassManager.h no longer includes llvm/Pass.h nor llvm/Support/Debug.h And the usual count of preprocessed lines: $ clang++ -E -Iinclude -I../llvm/include ../llvm/lib/IR/*.cpp -std=c++14 -fno-rtti -fno-exceptions | wc -l before: 6400831 after: 6189948 200k lines less to process is no that bad ;-) Discourse thread on the topic: https://llvm.discourse.group/t/include-what-you-use-include-cleanup Differential Revision: https://reviews.llvm.org/D118652
2022-01-26[DebugInfo] Add stringLocationExp field to DIStringTypeChih-Ping Chen1-3/+6
DIStringType is used to encode the debug info of a character object in Fortran. A Fortran deferred-length character object is typically implemented as a pair of the following two pieces of info: An address of the raw storage of the characters, and the length of the object. The stringLocationExp field contains the DIExpression to get to the raw storage. This patch also enables the emission of DW_AT_data_location attribute in a DW_TAG_string_type debug info entry based on stringLocationExp in DIStringType. A test is also added to ensure that the bitcode reader is backward compatible with the old DIStringType format. Differential Revision: https://reviews.llvm.org/D117586
2022-01-26Revert "Rename llvm::array_lengthof into llvm::size to match std::size from ↵Benjamin Kramer1-3/+3
C++17" This reverts commit ef8206320769ad31422a803a0d6de6077fd231d2. - It conflicts with the existing llvm::size in STLExtras, which will now never be called. - Calling it without llvm:: breaks C++17 compat
2022-01-26Rename llvm::array_lengthof into llvm::size to match std::size from C++17serge-sans-paille1-3/+3
As a conquence move llvm::array_lengthof from STLExtras.h to STLForwardCompat.h (which is included by STLExtras.h so no build breakage expected).
2021-11-11[DebugInfo] run clang-format on some unformatted filesLuís Ferreira1-55/+56
This trivial patch runs clang-format on some unformatted files before doing logic changes and prevent hard to review diffs. Differential Revision: https://reviews.llvm.org/D113572
2021-11-09Revert "[DebugInfo] Enforce implicit constraints on `distinct` MDNodes"Arthur Eubanks1-2/+0
This reverts commit ee7652569854af567ba83e5255d70e80cc8619a1. Causes crashes, see comments in D104827.
2021-11-09[DebugInfo] Enforce implicit constraints on `distinct` MDNodesScott Linder1-0/+2
Add UNIQUED and DISTINCT properties in Metadata.def and use them to implement restrictions on the `distinct` property of MDNodes: * DIExpression can currently be parsed from IR or read from bitcode as `distinct`, but this property is silently dropped when printing to IR. This causes accepted IR to fail to round-trip. As DIExpression appears inline at each use in the canonical form of IR, it cannot actually be `distinct` anyway, as there is no syntax to describe it. * Similarly, DIArgList is conceptually always uniqued. It is currently restricted to only appearing in contexts where there is no syntax for `distinct`, but for consistency it is treated equivalently to DIExpression in this patch. * DICompileUnit is already restricted to always being `distinct`, but along with adding general support for the inverse restriction I went ahead and described this in Metadata.def and updated the parser to be general. Future nodes which have this restriction can share this support. The new UNIQUED property applies to DIExpression and DIArgList, and forbids them to be `distinct`. It also implies they are canonically printed inline at each use, rather than via MDNode ID. The new DISTINCT property applies to DICompileUnit, and requires it to be `distinct`. A potential alternative change is to forbid the non-inline syntax for DIExpression entirely, as is done with DIArgList implicitly by requiring it appear in the context of a function. For example, we would forbid: !named = !{!0} !0 = !DIExpression() Instead we would only accept the equivalent inlined version: !named = !{!DIExpression()} This essentially removes the ability to create a `distinct` DIExpression by construction, as there is no syntax for `distinct` inline. If this patch is accepted as-is, the result would be that the non-canonical version is accepted, but the following would be an error and produce a diagnostic: !named = !{!0} ; error: 'distinct' not allowed for !DIExpression() !0 = distinct !DIExpression() Also update some documentation to consistently use the inline syntax for DIExpression, and to describe the restrictions on `distinct` for nodes where applicable. Reviewed By: StephenTozer, t-tye Differential Revision: https://reviews.llvm.org/D104827
2021-10-26[DebugInfo] Skip ODRUniquing for mismatched tagsYuanfang Chen1-1/+8
Otherwise, ODRUniquing would map some member method/variable MDNodes to have enum type DIScope, resulting in invalid debug info and bad DWARF. - Add a Verifier check that when a 'scope:' operand is an ODR type that is not an enum. - Makes ODRUniquing apply to only ODR types with the same tag so that the debuginfo/DWARF is well-formed. Reviewed By: probinson, aprantl Differential Revision: https://reviews.llvm.org/D111770
2021-09-16[DebugInfo] Enhance DIImportedEntity to accept children entitiesAlok Kumar Sharma1-3/+4
New field `elements` is added to '!DIImportedEntity', representing list of aliased entities. This is needed to dump optimized debugging information where all names in a module are imported, but a few names are imported with overriding aliases. Reviewed By: dblaikie Differential Revision: https://reviews.llvm.org/D109343
2021-09-01[DIArgList] Re-unique after changing operands to fix non-determinismTeresa Johnson1-0/+10
We have a large compile showing occasional non-deterministic behavior that is due to DIArgList not being properly uniqued in some cases. I tracked this down to handleChangedOperands, for which there is a custom implementation for DIArgList, that does not take care of re-uniquing after updating the DIArgList Args, unlike the default version of handleChangedOperands for MDNode. Since the Args in the DIArgList form the key for the store, this seems to be occasionally breaking the lookup in that DenseSet. Specifically, when invoking DIArgList::get() from replaceVariableLocationOp, very occasionally it returns a new DIArgList object, when one already exists having the same exact Args pointers. This in turn causes a subsequent call to Instruction::isIdenticalToWhenDefined on those two otherwise identical DIArgList objects during a later pass to return false, leading to different IR in those rare cases. I modified DIArgList::handleChangedOperands to perform similar re-uniquing as the MDNode version used by other metadata node types. This also necessitated a change to the context destructor, since in some cases we end up with DIArgList as distinct nodes: DIArgList is the only metadata node type to have a custom dropAllReferences, so we need to invoke that version on DIArgList in the DistinctMDNodes store to clean it up properly. Differential Revision: https://reviews.llvm.org/D108968
2021-08-26[DebugInfo] generate btf_tag annotations for func parametersYonghong Song1-2/+3
Generate btf_tag annotations for function parameters. A field "annotations" is introduced to DILocalVariable, and annotations are represented as an DINodeArray, similar to DIComposite elements. The following example illustrates how annotations are encoded in IR: distinct !DILocalVariable(name: "info",, arg: 1, ..., annotations: !10) !10 = !{!11, !12} !11 = !{!"btf_tag", !"a"} !12 = !{!"btf_tag", !"b"} Differential Revision: https://reviews.llvm.org/D106620
2021-08-26[DebugInfo] generate btf_tag annotations for DIGlobalVariableYonghong Song1-3/+6
Generate btf_tag annotations for DIGlobalVariable. A field "annotations" is introduced to DIGlobalVariable, and annotations are represented as an DINodeArray, similar to DIComposite elements. The following example illustrates how annotations are encoded in IR: distinct !DIGlobalVariable(..., annotations: !10) !10 = !{!11, !12} !11 = !{!"btf_tag", !"a"} !12 = !{!"btf_tag", !"b"} Differential Revision: https://reviews.llvm.org/D106619
2021-08-26[DebugInfo] generate btf_tag annotations for DISubprogram typesYonghong Song1-7/+12
Generate btf_tag annotations for DISubprogram types. A field "annotations" is introduced to DISubprogram, and annotations are represented as an DINodeArray, similar to DIComposite elements. The following example illustrates how annotations are encoded in IR: distinct !DISubprogram(..., annotations: !10) !10 = !{!11, !12} !11 = !{!"btf_tag", !"a"} !12 = !{!"btf_tag", !"b"} Differential Revision: https://reviews.llvm.org/D106618