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
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
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
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
This error was introduced in 1d1de7467c (by me)
about 1 month ago. Found while testing the D140901 patch stack.
Reviewed By: jryans
Differential Revision: https://reviews.llvm.org/D141052
This patch fixes a simple bug where `DbgValueHistoryMap::hasNonEmptyLocation` was incorrectly handling DBG_VALUE_LIST instructions, treating empty values as non-empty, causing empty variables to be emitted into DWARF.
Reviewed By: Orlando
Differential Revision: https://reviews.llvm.org/D133925
Currently the instruction referencing live debug values has 3 separate
places where we iterate over all known locations to find the best machine
location for a set of values at a given point in the program. Each of these
places has an implementation of this check, and one of them has slightly
different logic to the others. This patch moves the check for the "quality"
of a machine location into a separate function, which also avoids repeatedly
calling expensive functions, giving a slight performance improvement.
Differential Revision: https://reviews.llvm.org/D140412
This patch fixes a simple bug in DbgValueHistoryMap::hasNonEmptyLocation
that caused it to treat empty DBG_VALUE_LIST instructions as non-empty
when determining whether to emit a variable or not.
Differential Revision: https://reviews.llvm.org/D133925
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
* This is a recommit of 3c4d2a0396,
* which was reverted in 25f01d593c,
because it exposed a miscompile in PPC backend, which was resolved
in https://reviews.llvm.org/D140089 / cb3f415cd2.
* which was a recommit of cf624b23bc,
* which was reverted in 5cfc22cafe,
because the cut-off on the number of vector elements was not low enough,
and it triggered both SDAG SDNode operand number assertions,
5and caused compile time explosions in some cases.
Let's try with something really *REALLY* conservative first,
just to get somewhere, and try to bump it later.
FIXME: should this respect TTI reg width * num vec regs?
Original commit message:
Now, there's a big caveat here - these bytes
are abstract bytes, not the i8 we have in LLVM,
so strictly speaking this is not exactly legal,
see e.g. https://github.com/AliveToolkit/alive2/issues/860
^ the "bytes" "could" have been a pointer,
and loading it as an integer inserts an implicit ptrtoint.
But at the same time,
InstCombine's `InstCombinerImpl::SimplifyAnyMemTransfer()`
would expand a memtransfer of 1/2/4/8 bytes
into integer-typed load+store,
so this isn't exactly a new problem.
Note that in memory, poison is byte-wise,
so we really can't widen elements,
but SROA seems to be inconsistent here.
Fixes#59116.
As per post-commit feedback, DebugInfo owners are not receptive of the
idea of having a single source of truth instead of relying on everyone
to know how to update these tests manually.
This reverts commit 4ff8d1e315.
This reverts commit a33b40d61c.
Alignment of an alloca in IR can be lower than the preferred alignment
on purpose, but this override essentially treats the preferred
alignment as the minimum alignment.
The patch changes this behavior to always use the specified
alignment. If alignment is not set explicitly in LLVM IR, it is set to
DL.getPrefTypeAlign(Ty) in computeAllocaDefaultAlign.
Tests are changed as well: explicit alignment is increased to match
the preferred alignment if it changes output, or omitted when it is
hard to determine the right value (e.g. for pointers, some structs, or
weird types).
Differential Revision: https://reviews.llvm.org/D135462
Two tests checked 'ppc64be' which appears not to exist; the tests
pass on clang-ppc64be-linux-multistage so I assume they are fine
and just removed those UNSUPPORTED lines. All others were converted
to the new target= format, and get the same results on ppc bots as
before.
Part of the project to eliminate special handling for triples in lit
expressions.
Differential Revision: https://reviews.llvm.org/D138954
This reverts commit 28edf3349b.
This is because:
The Buildbot has detected a failed build on builder llvm-clang-x86_64-sie-ubuntu-fast while building llvm.
Full details are available at:
https://lab.llvm.org/buildbot#builders/139/builds/32856
Worker for this Build: sie-linux-worker
Blamelist:
Shubham Sandeep Rastogi <srastogi22@apple.com>
BUILD FAILED: 40459 expected passes 83 expected failures 26251 unsupported tests 1 unexpected failures (failure)
Step 6 (test-build-unified-tree-check-all) failure: 40459 expected passes 83 expected failures 26251 unsupported tests 1 unexpected failures (failure)
******************** TEST 'LLVM :: DebugInfo/debugframeinfo.s' FAILED ********************
Script:
--
: 'RUN: at line 1'; /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/llvm-mc -filetype=obj -triple=arm64-apple-darwin22.1.0 /home/buildbot/buildbot-root/llvm-project/llvm/test/DebugInfo/debugframeinfo.s -o /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/test/DebugInfo/Output/debugframeinfo.s.tmp.o
: 'RUN: at line 2'; /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/llvm-dwarfdump -debug-frame /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/test/DebugInfo/Output/debugframeinfo.s.tmp.o | /home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/FileCheck /home/buildbot/buildbot-root/llvm-project/llvm/test/DebugInfo/debugframeinfo.s
--
Exit Code: 1
Command Output (stderr):
--
/home/buildbot/buildbot-root/llvm-clang-x86_64-sie-ubuntu-fast/build/bin/llvm-mc: error: unable to get target for 'arm64-apple-darwin22.1.0', see --version and --triple.
This patch adds lowering for function calls with variadic number of
arguments as well as enables support for the following
instructions/intrinsics:
- va_arg
- va_start
- va_end
- va_copy
Note that this patch doesn't intent to include clang's support for
variadic functions for CUDA.
According to the docs:
PTX version 6.0 supports passing unsized array parameter to a
function which can be used to implement variadic functions. [0]
The last parameter in the parameter list may be a .param array of
type .b8 with no size specified. It is used to pass an arbitrary
number of parameters to the function packed into a single array
object.
When calling a function with such an unsized last argument, the last
argument may be omitted from the call instruction if no parameter is
passed through it. Accesses to this array parameter must be within
the bounds of the array. The result of an access is undefined if no
array was passed, or if the access was outside the bounds of the
actual array being passed. [1]
Note that aggregates passed by value as variadic arguments are not
currently supported.
[0] https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#variadic-functions
[1] https://docs.nvidia.com/cuda/parallel-thread-execution/index.html#kernel-and-function-directives-func
Differential Revision: https://reviews.llvm.org/D138531
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
Split dbg.assign intrinsics into fragments similarly to what SROA already does
for dbg.declares, except that there's many more intrinsics to split. The
function migrateDebugInfo generates new dbg.assigns intrinsic for each part of
a split store.
Reviewed By: jmorse
Differential Revision: https://reviews.llvm.org/D133296
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
Split dbg.assign intrinsics into fragments similarly to what SROA already does
for dbg.declares, except that there's many more intrinsics to split. The
function migrateDebugInfo generates new dbg.assigns intrinsic for each part of
a split store.
Reviewed By: jmorse
Differential Revision: https://reviews.llvm.org/D133296
We identify epilogue code by looking for instructions tagged
with FrameDestroy.
A function may have more than one epilogue, e.g., because of early
returns or code duplicated during optimization. We need only track
the current block, and emit epilogie_begin at most once per block.
We reduce the number of entries in the line table by combining
epilogue_begin with other flags instead of emitting a separate
entry just for epilogue_begin.
Reviewed By: dblaikie, aprantl
Differential Revision: https://reviews.llvm.org/D133376
Register-based `DBG_VALUE` should have been
converted into either local-based or stack-operand-based, so at this
point they don't contain any information.
This CL nullifies them, i.e., turning them info
`DBG_VALUE $noreg, $noreg, ...`, which makes the variable appear as
"optimized out". It is not safe to simply remove these instruction
because at this point, because the fact that there is a `DBG_VALUE` here
means the location this variable resides has changed to somewhere else;
we've lost that information where that was.
---
The below is not really about the CL itself, but a pre-existing bug in
`llvm-locstats` variable coverage we are going to be affected after this
CL. Feel free to skip if you don't have time.
This CL has an unexpected side effect of increasing variable coverage
reported by `llvm-locstats`, due to a bug mentioned in
https://lists.llvm.org/pipermail/llvm-dev/2021-January/148139.html.
Currently inlined functions' formal parameters that don't have any
coverage, including those who only have `DBG_VALUE $noreg, $noreg`s
associated with them, don't generate `DW_TAG_formal_parameter` DIEs, and
they don't get into consideration in `llvm-dwarf --statistics` and
`llvm-locstats`. This is a known bug mentioned in
https://lists.llvm.org/pipermail/llvm-dev/2021-January/148139.html. For
example, this is a snippet of `llvm-dwarfdump` output of `wc`, where
`isword` is inlined into another function. `isword` has a formal
parameter `c`, which doesn't have any coverage in this inlined area, so
its `DW_TAG_formal_parameter` was not generated:
```
0x0000018d: DW_TAG_inlined_subroutine
DW_AT_abstract_origin (0x0000012c "isword")
DW_AT_low_pc (0x00000166)
DW_AT_high_pc (0x0000016d)
DW_AT_call_file ("/usr/local/google/home/aheejin/test/dwarf-verify/wc/wc.c")
DW_AT_call_line (100)
DW_AT_call_column (0x0a)
```
But our dangling-register-based formal parameters currently generate
`DW_TAG_formal_parameter` DIEs, even though they don't have any
meaningful coverage, and this happened to generate correct statistics,
because it correctly sees this `c` doesn't have any coverage in this
inlined area. So our current `llvm-dwarfdump` (before this CL) is like:
```
0x0000018d: DW_TAG_inlined_subroutine
DW_AT_abstract_origin (0x0000012c "isword")
DW_AT_low_pc (0x00000166)
DW_AT_high_pc (0x0000016d)
DW_AT_call_file ("/usr/local/google/home/aheejin/test/dwarf-verify/wc/wc.c")
DW_AT_call_line (100)
DW_AT_call_column (0x0a)
0x0000019a: DW_TAG_formal_parameter
DW_AT_abstract_origin (0x00000134 "c")
```
Note that this `DW_TAG_formal_parameter` doesn't have any
`DW_AT_location` attribute under it, meaning it doesn't have any
coverage.
On the other hand, if the `DW_TAG_formal_parameter` is not generated,
`llvm-dwarfdump --statistics` wouldn't even know about the parameter's
existence, and doesn't include it in the coverage computation, making
the overall coverage (incorrectly) go up.
`DBG_VALUE $noreg, $noreg` used to generate this empty
`DW_TAG_formal_parameter`, but it changed for consistency in D95617.
It looks this bug in `llvm-dwarf --statistics` (and `llvm-locstats`,
which uses `llvm-dwarf --statistics`) has not been fixed so far. So we
get the coverage that's little incorrectly higher than our actual
coverage. But this bug apparently affects every target in LLVM.
Reviewed By: dschuff
Differential Revision: https://reviews.llvm.org/D139675
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 initial revision of assignment tracking analysis pass
---------------------------------------------------------
This patch squashes five individually reviewed patches into one:
#1https://reviews.llvm.org/D136320#2https://reviews.llvm.org/D136321#3https://reviews.llvm.org/D136325#4https://reviews.llvm.org/D136331#5https://reviews.llvm.org/D136335
Patch #1 introduces 2 new files: AssignmentTrackingAnalysis.h and .cpp. The
two subsequent patches modify those files only. Patch #4 plumbs the analysis
into SelectionDAG, and patch #5 is a collection of tests for the analysis as
a whole.
The analysis was broken up into smaller chunks for review purposes but for the
most part the tests were written using the whole analysis. It would be possible
to break up the tests for patches #1 through #3 for the purpose of landing the
patches seperately. However, most them would require an update for each
patch. In addition, patch #4 - which connects the analysis to SelectionDAG - is
required by all of the tests.
If there is build-bot trouble, we might try a different landing sequence.
Analysis problem and goal
-------------------------
Variables values can be stored in memory, or available as SSA values, or both.
Using the Assignment Tracking metadata, it's not possible to determine a
variable location just by looking at a debug intrinsic in
isolation. Instructions without any metadata can change the location of a
variable. The meaning of dbg.assign intrinsics changes depending on whether
there are linked instructions, and where they are relative to those
instructions. So we need to analyse the IR and convert the embedded information
into a form that SelectionDAG can consume to produce debug variable locations
in MIR.
The solution is a dataflow analysis which, aiming to maximise the memory
location coverage for variables, outputs a mapping of instruction positions to
variable location definitions.
API usage
---------
The analysis is named `AssignmentTrackingAnalysis`. It is added as a required
pass for SelectionDAGISel when assignment tracking is enabled.
The results of the analysis are exposed via `getResults` using the returned
`const FunctionVarLocs *`'s const methods:
const VarLocInfo *single_locs_begin() const;
const VarLocInfo *single_locs_end() const;
const VarLocInfo *locs_begin(const Instruction *Before) const;
const VarLocInfo *locs_end(const Instruction *Before) const;
void print(raw_ostream &OS, const Function &Fn) const;
Debug intrinsics can be ignored after running the analysis. Instead, variable
location definitions that occur between an instruction `Inst` and its
predecessor (or block start) can be found by looping over the range:
locs_begin(Inst), locs_end(Inst)
Similarly, variables with a memory location that is valid for their lifetime
can be iterated over using the range:
single_locs_begin(), single_locs_end()
Further detail
--------------
For an explanation of the dataflow implementation and the integration with
SelectionDAG, please see the reviews linked at the top of this commit message.
Reviewed By: jmorse
Over the past day or so, i've took a large swing at our tests,
and reduced the number of tests that were still using the old syntax
from ~1800 to just 200.
Left to handle: (as it is seen in this patch)
* Transforms/LSR
* Transforms/CGP
* Transforms/TypePromotion
* Transforms/HardwareLoops
* Analysis/*
* some misc.
I think this is the right point to start actively refusing
to honor the old syntax, except for the old tests,
to prevent the old syntax from creeping back in.
Thus, let's add temporary default-off flag,
and if it is not passed refuse to accept old syntax.
The tests that still need porting are annotated with this flag.
Reviewed By: aeubanks
Differential Revision: https://reviews.llvm.org/D139647
Summary:
Changed contribution data structure to 64 bit. I added the 32bit and 64bit
accessors to make it explicit where we use 32bit and where we use 64bit. Also to
make sure sure we catch all the cases where this data structure is used.
CodeView doesn't have the ability to represent variables
in other ways than as in registers or memory values, but
LLVM very often transforms simple values into constants,
consider this program:
int f () { int i = 123; return i; }
LLVM will transform `i` into a constant value and just
leave behind a llvm.dbg.value, this can't be represented
as a S_LOCAL record in CodeView. But we can represent it
as a S_CONSTANT record.
This patch checks if the location of a debug value is null,
then we will insert a S_CONSTANT record instead of a S_LOCAL
value with the flag "OptimizedAway".
In lld we then output the S_CONSTANT in the right scope, before
they where always inserted in the global stream, now we check
the scope before inserting it.
This has shown to improve debugging for our developers
internally.
Fixes to llvm/llvm-project#55958
Reviewed By: aganea
Differential Revision: https://reviews.llvm.org/D138995