At this stage I'm just opportunistically deleting any code using
debug-intrinsic types, largely adjacent to calls to findDbgUsers. I'll
get to deleting that in probably one or more two commits.
This change adds some support to the C DebugInfo capability to create set types,
subrange types, dynamic array types and the ability to replace arrays.
RFC on discourse:
https://discourse.llvm.org/t/rfc-debug-info-for-coroutine-suspension-locations-take-2/86606
With this commit, we add `DILabel` debug infos to the resume points of a
coroutine. Those labels can be used by debugging scripts to figure out
the exact line and column at which a coroutine was suspended by looking
up current `__coro_index` value inside the coroutines frame, and then
searching for the corresponding label inside the coroutine's resume
function.
The DWARF information generated for such a label looks like:
```
0x00000f71: DW_TAG_label
DW_AT_name ("__coro_resume_1")
DW_AT_decl_file ("generator-example.cpp")
DW_AT_decl_line (5)
DW_AT_decl_column (3)
DW_AT_artificial (true)
DW_AT_LLVM_coro_suspend_idx (0x01)
DW_AT_low_pc (0x00000000000019be)
```
The labels can be mapped to their corresponding `__coro_idx` values
either via their naming convention `__coro_resume_<N>` or using the new
`DW_AT_LLVM_coro_suspend_idx` attribute. In gdb, those line numebrs can
be looked up using `info line -function my_coroutine -label
__coro_resume_1`. LLDB unfortunately does not understand DW_TAG_label
debug information, yet.
Given this is an artificial compiler-generated label, I did apply the
DW_AT_artificial tag to it. The DWARFv5 standard only allows that tag on
type and variable definitions, but this is a natural extension and was
also blessed in the RFC on discourse.
Also, this commit adds `DW_AT_decl_column` to labels, not only for
coroutines but also for normal C and C++ labels. While not strictly
necessary, I am doing so now because it would be harder to do so later
without breaking the binary LLVM-IR format
Drive-by fixes: While reading the existing test cases to understand how
to write my own test case, I did a couple of small typo fixes and
comment improvements
The C API does not provide a way to replace the subroutine type after
creating a subprogram. This functionality is useful for creating a
subroutine type composed of types which have the subprogram as scope
Seeing how we can't generate any debug intrinsics any more: delete a
variety of codepaths where they're handled. For the most part these are
plain deletions, in others I've tweaked comments to remain coherent, or
added a type to (what was) type-generic-lambdas.
This isn't all the DbgInfoIntrinsic call sites but it's most of the
simple scenarios.
Co-authored-by: Nikita Popov <github@npopov.com>
Part of the coverage-tracking feature, following #107279.
In order for DebugLoc coverage testing to work, we firstly have to set
annotations for intentionally-empty DebugLocs, and secondly we have to
ensure that we do not drop these annotations as we propagate DebugLocs
throughout compilation. As the annotations exist as part of the DebugLoc
class, and not the underlying DILocation, they will not survive a
DebugLoc->DILocation->DebugLoc roundtrip. Therefore this patch modifies
a number of places in the compiler to propagate DebugLocs directly
rather than via the underlying DILocation. This has no effect on the
output of normal builds; it only ensures that during coverage builds, we
do not drop incorrectly annotations and therefore create false
positives.
The bulk of these changes are in replacing
DILocation::getMergedLocation(s) with a DebugLoc equivalent, and in
changing the IRBuilder to store a DebugLoc directly rather than storing
DILocations in its general Metadata array. We also use a new function,
`DebugLoc::orElse`, which selects the "best" DebugLoc out of a pair
(valid location > annotated > empty), preferring the current DebugLoc on
a tie - this encapsulates the existing behaviour at a few sites where we
_may_ assign a DebugLoc to an existing instruction, while extending the
logic to handle annotation DebugLocs at the same time.
Specifically this is the assertion in BasicBlock.cpp. Now that we're not
examining or setting that flag consistently (because it'll be deleted in
about an hour) there's no need to keep this assertion.
Original commit title:
[DebugInfo][RemoveDIs] Remove some debug intrinsic-only codepaths (#143451)
This reverts commit c71a2e688828ab3ede4fb54168a674ff68396f61.
/me squints -- this is hitting an assertion I thought had been deleted,
will revert and investigate for a bit.
These are opportunistic deletions as more places that make use of the
IsNewDbgInfoFormat flag are removed. It should (TM)(R) all be dead code
now that `IsNewDbgInfoFormat` should be true everywhere.
FastISel: we don't need to do debug-aware instruction counting any more,
because there are no debug instructions,
Autoupgrade: you can no-longer avoid autoupgrading of intrinsics to
records
DIBuilder: Delete the code for creating debug intrinsics (!)
LoopUtils: No need to handle debug instructions, they don't exist
Since https://reviews.llvm.org/D144004, DISubprogram's retainedNodes
field is used to track DIImportedEntities, in addition to local
variables and labels.
However, the corresponding update for DebugInfoFinder, to make it visit
DISubprogram's retainedNodes, was missing.
This is the fix for it.
This change is separated from
https://github.com/llvm/llvm-project/pull/119001 to simplify it.
Reapplied after fixing the config issue that was causing issues following
the previous merge.
This reverts commit fdbf073a86573c9ac4d595fac8e06d252ce1469f.
Since `LLVMDIBuilderCreateEnumerator` only supports up to 64 bits, this
PR adds a new `LLVMDIBuilderCreateEnumeratorOfArbitraryPrecision`
function that takes an arbitrary number of words, based on
`LLVMConstIntOfArbitraryPrecision`. This allows even larger enumeration
types to represent their values exactly. (It seems LLVM should already
support i128 enums since 13.0.0.)
This reverts commit a9d93ecf1f8d2cfe3f77851e0df179b386cff353.
Reverted due to the commit including a config in LLVM headers that is not
available outside of the llvm source tree.
This is part of a series of patches that tries to improve DILocation bug
detection in Debugify; see the review for more details. This is the patch
that adds the main feature, adding a set of `DebugLoc::get<Kind>`
functions that can be used for instructions with intentionally empty
DebugLocs to prevent Debugify from treating them as bugs, removing the
currently-pervasive false positives and allowing us to use Debugify (in
its original DI preservation mode) to reliably detect existing bugs and
regressions. This patch does not add uses of these functions, except for
once in Clang before optimizations, and in
`Instruction::dropLocation()`, since that is an obvious case that
immediately removes a set of false positives.
After #124287 updated several functions to return iterators rather than
Instruction *, it was no longer straightforward to pass their result to
DIBuilder. This commit updates DIBuilder methods to accept an
InsertPosition instead, so that they can be called with an iterator
(preferred), or with a deprecation warning an Instruction *, or a
BasicBlock *. This commit also updates the existing calls to the
DIBuilder methods to pass in iterators.
As a special exception, DIBuilder::insertDeclare() keeps a separate
overload accepting a BasicBlock *InsertAtEnd. This is because despite
the name, this method does not insert at the end of the block, therefore
this cannot be handled implicitly by using InsertPosition.
After #124287 updated several functions to return iterators rather than
Instruction *, it was no longer straightforward to pass their result to
DIBuilder. This commit updates DIBuilder methods to accept an
InsertPosition instead, so that they can be called with an iterator
(preferred), or with a deprecation warning an Instruction *, or a
BasicBlock *. This commit also updates the existing calls to the
DIBuilder methods to pass in iterators.
This is an upstream proposal from
e60884cb98
We observed malfunctioning StripNonLineTableDebugInfo during debugging
and it's caused by out-of-order evaluation, this is a C++ level semantic
ambiguity issue, refer
https://en.cppreference.com/w/cpp/language/eval_order
Solution is simply separating one line into two.
This reverts commit c3a935e3f967f8f22f5db240d145459ee621c1e0.
The only change to the reverted commit is that this also updates
the OCaml bindings according to the C debug-info API changes.
The build failure originally introduced was:
```
FAILED: bindings/ocaml/debuginfo/debuginfo_ocaml.o /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bindings/ocaml/debuginfo/debuginfo_ocaml.o
cd /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bindings/ocaml/debuginfo && /usr/bin/ocamlfind ocamlc -c /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bindings/ocaml/debuginfo/debuginfo_ocaml.c -ccopt "-I/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/bindings/ocaml/debuginfo/../llvm -D_GNU_SOURCE -D_DEBUG -D_GLIBCXX_ASSERTIONS -DEXPENSIVE_CHECKS -D_GLIBCXX_DEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS -I/b/1/llvm-clang-x86_64-expensive-checks-debian/build/include -I/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/include -DNDEBUG "
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bindings/ocaml/debuginfo/debuginfo_ocaml.c: In function ‘llvm_dibuild_create_object_pointer_type’:
/b/1/llvm-clang-x86_64-expensive-checks-debian/build/bindings/ocaml/debuginfo/debuginfo_ocaml.c:620:30: error: too few arguments to function ‘LLVMDIBuilderCreateObjectPointerType’
620 | LLVMMetadataRef Metadata = LLVMDIBuilderCreateObjectPointerType(
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
In file included from /b/1/llvm-clang-x86_64-expensive-checks-debian/build/bindings/ocaml/debuginfo/debuginfo_ocaml.c:23:
/b/1/llvm-clang-x86_64-expensive-checks-debian/llvm-project/llvm/include/llvm-c/DebugInfo.h:880:17: note: declared here
880 | LLVMMetadataRef LLVMDIBuilderCreateObjectPointerType(LLVMDIBuilderRef Builder,
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
```
Note that PointerUnion::{is,get,dyn_cast} have been soft deprecated in
PointerUnion.h:
// FIXME: Replace the uses of is(), get() and dyn_cast() with
// isa<T>, cast<T> and the llvm::dyn_cast<T>
It is almost always simpler to use {} instead of std::nullopt to
initialize an empty ArrayRef. This patch changes all occurrences I could
find in LLVM itself. In future the ArrayRef(std::nullopt_t) constructor
could be deprecated or removed.
Patch [3/x] to fix structured bindings debug info in SROA.
This function computes a fragment, bit-extract operation if needed, and new
constant offset to describe a part of a variable covered by some memory.
This generalises, simplifies, and replaces at::calculateFragmentIntersect. That
version is still used as a wrapper for now though to keep this change NFC.
The new version takes doesn't have a DbgRecord parameter, instead using an
explicit address and address offset. The old version only operates on
dbg_assigns and this change means it can also operate on dbg_declare records
easily, which it will do in a subsequent patch.
The new version has a new out-param OffsetFromLocationInBits which is set to
the difference between the first bit of the variable location and the first
bit of the memory slice. This will be used in a subsequent patch in SROA to
determine the new offset to use in the address expression after splitting an
alloca.
Fix#91814
When instructions are extracted into a new function the `DIAssignID` metadata
uses and attachments need to be remapped so that the stores and assignment
markers don't link to stores and assignment markers in the original function.
This matches existing inlining behaviour for DIAssignIDs.
In the debug intrinsic class heirachy, a dbg.assign is a (inherits from)
dbg.value, so `findDbgValues` returns dbg.values and dbg.assigns (by
design). That hierarchy doesn't exist for DbgRecords - fix findDbgValues
to return dbg_assign records as well as dbg_values and add unittest.
Follow on from #84915 which adds the DbgRecord function variants. The C API
changes were reviewed in #85657.
# C API
Update the LLVMDIBuilderInsert... functions to insert DbgRecords instead
of debug intrinsics.
LLVMDIBuilderInsertDeclareBefore
LLVMDIBuilderInsertDeclareAtEnd
LLVMDIBuilderInsertDbgValueBefore
LLVMDIBuilderInsertDbgValueAtEnd
Calling these functions will now cause an assertion if the module is in the
wrong debug info format. They should only be used when the module is in "new
debug format".
Use LLVMIsNewDbgInfoFormat to query and LLVMSetIsNewDbgInfoFormat to change the
debug info format of a module.
Please see https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-change
(RemoveDIsDebugInfo.md) for more info.
# OCaml bindings
Add set_is_new_dbg_info_format and is_new_dbg_info_format to the OCaml bindings.
These can be used to set and query the current debug info mode. These will
eventually be removed, but are useful while we're transitioning between old and
new debug info formats.
Add string_of_lldbgrecord, like string_of_llvalue but prints DbgRecords.
In test dbginfo.ml, unconditionally set the module debug info to the new mode
and update CHECK lines to check for DbgRecords. Without this change the test
crashes because it attempts to insert DbgRecords (new default behaviour of
llvm_dibuild_insert_declare_...) into a module that is in the old debug info
mode.
Follow on from #84915 which adds the DbgRecord function variants.
Update the LLVMDIBuilderInsert... functions to insert DbgRecords instead
of debug intrinsics.
LLVMDIBuilderInsertDeclareBefore
LLVMDIBuilderInsertDeclareAtEnd
LLVMDIBuilderInsertDbgValueBefore
LLVMDIBuilderInsertDbgValueAtEnd
Calling these functions will now cause an assertion if the module is in the
wrong debug info format. They should only be used when the module is in "new
debug format".
Use LLVMIsNewDbgInfoFormat to query and LLVMSetIsNewDbgInfoFormat to change the
debug info format of a module.
Please see https://llvm.org/docs/RemoveDIsDebugInfo.html#c-api-change
(RemoveDIsDebugInfo.md) for more info.
This is the major rename patch that prior patches have built towards.
The DPValue class is being renamed to DbgVariableRecord, which reflects
the updated terminology for the "final" implementation of the RemoveDI
feature. This is a pure string substitution + clang-format patch. The
only manual component of this patch was determining where to perform
these string substitutions: `DPValue` and `DPV` are almost exclusively
used for DbgRecords, *except* for:
- llvm/lib/target, where 'DP' is used to mean double-precision, and so
appears as part of .td files and in variable names. NB: There is a
single existing use of `DPValue` here that refers to debug info, which
I've manually updated.
- llvm/tools/gold, where 'LDPV' is used as a prefix for symbol
visibility enums.
Outside of these places, I've applied several basic string
substitutions, with the intent that they only affect DbgRecord-related
identifiers; I've checked them as I went through to verify this, with
reasonable confidence that there are no unintended changes that slipped
through the cracks. The substitutions applied are all case-sensitive,
and are applied in the order shown:
```
DPValue -> DbgVariableRecord
DPVal -> DbgVarRec
DPV -> DVR
```
Following the previous rename patches, it should be the case that there
are no instances of any of these strings that are meant to refer to the
general case of DbgRecords, or anything other than the DPValue class.
The idea behind this patch is therefore that pure string substitution is
correct in all cases as long as these assumptions hold.
Reland #82363 after fixing build failure
https://lab.llvm.org/buildbot/#/builders/5/builds/41428.
Memory sanitizer detects usage of `RawData` union member which is not
filled directly. Instead, the code relies on filling `Data` union
member, which is a struct consisting of signing schema parameters.
According to https://en.cppreference.com/w/cpp/language/union, this is
UB:
"It is undefined behavior to read from the member of the union that
wasn't most recently written".
Instead of relying on compiler allowing us to do dirty things, do not
use union and only store `RawData`. Particular ptrauth parameters are
obtained on demand via bit operations.
Original PR description below.
Emit `__ptrauth`-qualified types as `DIDerivedType` metadata nodes in IR
with tag `DW_TAG_LLVM_ptrauth_type`, baseType referring to the type
which has the qualifier applied, and the following parameters
representing the signing schema:
- `ptrAuthKey` (integer)
- `ptrAuthIsAddressDiscriminated` (boolean)
- `ptrAuthExtraDiscriminator` (integer)
- `ptrAuthIsaPointer` (boolean)
- `ptrAuthAuthenticatesNullValues` (boolean)
Co-authored-by: Ahmed Bougacha <ahmed@bougacha.org>
Follow on from #84739, which updates the DIBuilder class.
All the functions that have been added are temporary and will be
deprecated in the future. The intention is that they'll help downstream
projects adapt during the transition period.
```
New functions (all to be deprecated)
------------------------------------
LLVMIsNewDbgInfoFormat # Returns true if the module is in the new non-instruction mode.
LLVMSetIsNewDbgInfoFormat # Convert to the requested debug info format.
LLVMDIBuilderInsertDeclareIntrinsicBefore # Insert a debug intrinsic (old debug info format).
LLVMDIBuilderInsertDeclareIntrinsicAtEnd # Same as above.
LLVMDIBuilderInsertDbgValueIntrinsicBefore # Same as above.
LLVMDIBuilderInsertDbgValueIntrinsicAtEnd # Same as above.
LLVMDIBuilderInsertDeclareRecordBefore # Insert a debug record (new debug info format).
LLVMDIBuilderInsertDeclareRecordAtEnd # Same as above.
LLVMDIBuilderInsertDbgValueRecordBefore # Same as above.
LLVMDIBuilderInsertDbgValueRecordAtEnd # Same as above.
```
The existing `LLVMDIBuilderInsert...` functions call through to the
intrinsic versions (old debug info format) currently.
In the next patch, I'll swap them to call the debug records versions
(new debug info format). Downstream users of this API can query and
change the current format using the first two functions above, or can
instead opt to temporarily use intrinsics or records explicitly.
This patch changes DPValue::filter to be a non-member method
filterDbgVars. There are two reasons for this: firstly, the name of
DPValue is about to change to DbgVariableRecord, which will result in
every `for` loop that uses DPValue::filter to require a line break. This
is a small thing, but it makes the rename patch more difficult to
review, and is just generally more awkward for what is a fairly common
loop. Secondly, the intent is to later break up the DPValue class into
subclasses, at which point it would be better to have a non-member
function that allows template arguments for the cases we want to filter
with greater specificity.
This patch continues the ongoing rename work, replacing DPValue with
DbgRecord in comments and the names of variables, both members and
fn-local. This is the most labour-intensive part of the rename, as it is
where the most decisions have to be made about whether a given comment
or variable is referring to DPValues (equivalent to debug variable
intrinsics) or DbgRecords (a catch-all for all debug intrinsics); these
decisions are not individually difficult, but comprise a fairly large
amount of text to review.
This patch still largely performs basic string substitutions followed by
clang-format; there are almost* no places where, for example, a comment
has been expanded or modified to reflect the semantic difference between
DPValues and DbgRecords. I don't believe such a change is generally
necessary in LLVM, but it may be useful in the docs, and so I'll be
submitting docs changes as a separate patch.
*In a few places, `dbg.values` was replaced with `debug intrinsics`.
As part of the effort to rename the DbgRecord classes, this patch
renames the widely-used functions that operate on DbgRecords but refer
to DbgValues or DPValues in their names to refer to DbgRecords instead;
all such functions are defined in one of `BasicBlock.h`,
`Instruction.h`, and `DebugProgramInstruction.h`.
This patch explicitly does not change the names of any comments or
variables, except for where they use the exact name of one of the
renamed functions. The reason for this is reviewability; this patch can
be trivially examined to determine that the only changes are direct
string substitutions and any results from clang-format responding to the
changed line lengths. Future patches will cover renaming variables and
comments, and then renaming the classes themselves.
Have DIBuilder conditionally insert either debug intrinsics or DbgRecord
depending on the module's IsNewDbgInfoFormat flag. The insertion methods
now return a `DbgInstPtr` (a `PointerUnion<Instruction *, DbgRecord
*>`).
Add a unittest for both modes (I couldn't find an existing test testing
insertion behaviours specifically).
This patch changes the existing assumption that DbgRecords are only ever
inserted if there's an instruction to insert-before because clang
currently inserts debug intrinsics while CodeGening (like any other
instruction) meaning it'll try inserting to the end of a block without a
terminator. We already have machinery in place to maintain the
DbgRecords when a terminator is removed - these become "trailing
DbgRecords" which are re-attached when a new instruction is inserted.
All I've done is allow this state to occur while inserting DbgRecords
too, i.e., it's not only removing terminators that causes this valid
transient state, but inserting DbgRecords into incomplete blocks too.
The C API will be updated in follow up patches.
---
Note: this doesn't mean clang is emitting DbgRecords yet, because the
modules it creates are still always in the old debug mode. That will
come in a future patch.