summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorReid Kleckner <rnk@google.com>2017-05-09 19:59:29 +0000
committerReid Kleckner <rnk@google.com>2017-05-09 19:59:29 +0000
commitb5fced732416c1d9a2ffa1980ca1af88c06edd83 (patch)
treebe7f854f4fcb5399e43b0ae77e0a09b625dfbb66
parentdfa7f613ed7ca025d6d4d2ea85073f6ddaa9f712 (diff)
downloadbcm5719-llvm-b5fced732416c1d9a2ffa1980ca1af88c06edd83.tar.gz
bcm5719-llvm-b5fced732416c1d9a2ffa1980ca1af88c06edd83.zip
[codeview] Check for a DIExpression offset for local variables
Fixes inalloca parameters, which previously all pointed to the same offset. Extend the test to use llvm-readobj so that we can test the offset in a readable way. llvm-svn: 302578
-rw-r--r--llvm/include/llvm/IR/DebugInfoMetadata.h4
-rw-r--r--llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp10
-rw-r--r--llvm/lib/IR/DebugInfoMetadata.cpp18
-rw-r--r--llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll41
4 files changed, 72 insertions, 1 deletions
diff --git a/llvm/include/llvm/IR/DebugInfoMetadata.h b/llvm/include/llvm/IR/DebugInfoMetadata.h
index 0331d5229e7..36bc5ce91b6 100644
--- a/llvm/include/llvm/IR/DebugInfoMetadata.h
+++ b/llvm/include/llvm/IR/DebugInfoMetadata.h
@@ -2276,6 +2276,10 @@ public:
/// Append \p Ops with operations to apply the \p Offset.
static void appendOffset(SmallVectorImpl<uint64_t> &Ops, int64_t Offset);
+ /// If this is a constant offset, extract it. If there is no expression,
+ /// return true with an offset of zero.
+ bool extractIfOffset(int64_t &Offset) const;
+
/// Constants for DIExpression::prepend.
enum { NoDeref = false, WithDeref = true, WithStackValue = true };
diff --git a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
index 87b45c001de..9d60fff3bcc 100644
--- a/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
+++ b/llvm/lib/CodeGen/AsmPrinter/CodeViewDebug.cpp
@@ -888,13 +888,21 @@ void CodeViewDebug::collectVariableInfoFromMFTable(
if (!Scope)
continue;
+ // If the variable has an attached offset expression, extract it.
+ // FIXME: Try to handle DW_OP_deref as well.
+ int64_t ExprOffset = 0;
+ if (VI.Expr)
+ if (!VI.Expr->extractIfOffset(ExprOffset))
+ continue;
+
// Get the frame register used and the offset.
unsigned FrameReg = 0;
int FrameOffset = TFI->getFrameIndexReference(*Asm->MF, VI.Slot, FrameReg);
uint16_t CVReg = TRI->getCodeViewRegNum(FrameReg);
// Calculate the label ranges.
- LocalVarDefRange DefRange = createDefRangeMem(CVReg, FrameOffset);
+ LocalVarDefRange DefRange =
+ createDefRangeMem(CVReg, FrameOffset + ExprOffset);
for (const InsnRange &Range : Scope->getRanges()) {
const MCSymbol *Begin = getLabelBeforeInsn(Range.first);
const MCSymbol *End = getLabelAfterInsn(Range.second);
diff --git a/llvm/lib/IR/DebugInfoMetadata.cpp b/llvm/lib/IR/DebugInfoMetadata.cpp
index cdbe237766a..e6c49cad072 100644
--- a/llvm/lib/IR/DebugInfoMetadata.cpp
+++ b/llvm/lib/IR/DebugInfoMetadata.cpp
@@ -672,6 +672,24 @@ void DIExpression::appendOffset(SmallVectorImpl<uint64_t> &Ops,
}
}
+bool DIExpression::extractIfOffset(int64_t &Offset) const {
+ if (getNumElements() == 0) {
+ Offset = 0;
+ return true;
+ }
+ if (getNumElements() != 2)
+ return false;
+ if (Elements[0] == dwarf::DW_OP_plus) {
+ Offset = Elements[1];
+ return true;
+ }
+ if (Elements[0] == dwarf::DW_OP_minus) {
+ Offset = -Elements[1];
+ return true;
+ }
+ return false;
+}
+
DIExpression *DIExpression::prepend(const DIExpression *Expr, bool Deref,
int64_t Offset, bool StackValue) {
SmallVector<uint64_t, 8> Ops;
diff --git a/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll b/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll
index 5301cd66146..e3f5c7e629b 100644
--- a/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll
+++ b/llvm/test/DebugInfo/X86/dbg-declare-inalloca.ll
@@ -1,5 +1,6 @@
; RUN: llc -O0 < %s | FileCheck %s --check-prefix=CHECK --check-prefix=DEBUG
; RUN: llc < %s | FileCheck %s
+; RUN: llc -filetype=obj -O0 < %s | llvm-readobj -codeview - | FileCheck %s --check-prefix=OBJ
; IR generated by the following source:
; struct NonTrivial {
@@ -54,6 +55,46 @@
; CHECK: .asciz "c"
; CHECK: .cv_def_range [[start]] [[end]]
+; OBJ-LABEL: ProcStart {
+; OBJ: Kind: S_GPROC32_ID (0x1147)
+; OBJ: DisplayName: f
+; OBJ: }
+; OBJ: Local {
+; OBJ: Type: NonTrivial (0x1007)
+; OBJ: Flags [ (0x1)
+; OBJ: IsParameter (0x1)
+; OBJ: ]
+; OBJ: VarName: a
+; OBJ: }
+; OBJ: DefRangeRegisterRel {
+; OBJ: BaseRegister: 21
+; OBJ: BasePointerOffset: 12
+; OBJ: }
+; OBJ: Local {
+; OBJ: Type: int (0x74)
+; OBJ: Flags [ (0x1)
+; OBJ: IsParameter (0x1)
+; OBJ: ]
+; OBJ: VarName: b
+; OBJ: }
+; OBJ: DefRangeRegisterRel {
+; OBJ: BaseRegister: 21
+; OBJ: BasePointerOffset: 16
+; OBJ: }
+; FIXME: Retain unused.
+; OBJ: Local {
+; OBJ: Type: int (0x74)
+; OBJ: Flags [ (0x1)
+; OBJ: IsParameter (0x1)
+; OBJ: ]
+; OBJ: VarName: c
+; OBJ: }
+; OBJ: DefRangeRegisterRel {
+; OBJ: BaseRegister: 21
+; OBJ: BasePointerOffset: 24
+; OBJ: }
+; OBJ-LABEL: ProcEnd {
+; OBJ: }
; ModuleID = 't.cpp'
OpenPOWER on IntegriCloud