diff options
author | Tobias Hieta <tobias@hieta.se> | 2022-11-22 10:10:36 +0100 |
---|---|---|
committer | Tobias Hieta <tobias@hieta.se> | 2022-12-06 10:34:01 +0100 |
commit | 2298a44ccdc1a9babcb2712a0019d064b3cecd5a (patch) | |
tree | 8d5a4e706d7c3dc6a7b9642eab0eb1f556a81156 /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | |
parent | 5b22c5129c11f5c762c5092d7c52e1ac3d536903 (diff) | |
download | llvm-2298a44ccdc1a9babcb2712a0019d064b3cecd5a.zip llvm-2298a44ccdc1a9babcb2712a0019d064b3cecd5a.tar.gz llvm-2298a44ccdc1a9babcb2712a0019d064b3cecd5a.tar.bz2 |
[CodeView] Add support for local S_CONSTANT records
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
Diffstat (limited to 'llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp')
-rw-r--r-- | llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp | 26 |
1 files changed, 23 insertions, 3 deletions
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp index a3777438..2cf31ca 100644 --- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp @@ -1343,7 +1343,17 @@ void CodeViewDebug::calculateRanges( Optional<DbgVariableLocation> Location = DbgVariableLocation::extractFromMachineInstruction(*DVInst); if (!Location) + { + // When we don't have a location this is usually because LLVM has + // transformed it into a constant and we only have an llvm.dbg.value. We + // can't represent these well in CodeView since S_LOCAL only works on + // registers and memory locations. Instead, we will pretend this to be a + // constant value to at least have it show up in the debugger. + auto Op = DVInst->getDebugOperand(0); + if (Op.isImm()) + Var.ConstantValue = APSInt(APInt(64, Op.getImm()), false); continue; + } // CodeView can only express variables in register and variables in memory // at a constant offset from a register. However, for variables passed @@ -2788,9 +2798,19 @@ void CodeViewDebug::emitLocalVariableList(const FunctionInfo &FI, emitLocalVariable(FI, *L); // Next emit all non-parameters in the order that we found them. - for (const LocalVariable &L : Locals) - if (!L.DIVar->isParameter()) - emitLocalVariable(FI, L); + for (const LocalVariable &L : Locals) { + if (!L.DIVar->isParameter()) { + if (L.ConstantValue) { + // If ConstantValue is set we will emit it as a S_CONSTANT instead of a + // S_LOCAL in order to be able to represent it at all. + const DIType *Ty = L.DIVar->getType(); + APSInt Val(L.ConstantValue.value()); + emitConstantSymbolRecord(Ty, Val, std::string(L.DIVar->getName())); + } else { + emitLocalVariable(FI, L); + } + } + } } void CodeViewDebug::emitLocalVariable(const FunctionInfo &FI, |