aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
diff options
context:
space:
mode:
authorTobias Hieta <tobias@hieta.se>2022-11-22 10:10:36 +0100
committerTobias Hieta <tobias@hieta.se>2022-12-06 10:34:01 +0100
commit2298a44ccdc1a9babcb2712a0019d064b3cecd5a (patch)
tree8d5a4e706d7c3dc6a7b9642eab0eb1f556a81156 /llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
parent5b22c5129c11f5c762c5092d7c52e1ac3d536903 (diff)
downloadllvm-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.cpp26
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,