From 223303c5a39b232bd3d6f4b207e6e0b01febf4c5 Mon Sep 17 00:00:00 2001 From: Bob Haarman Date: Tue, 29 Aug 2017 20:59:25 +0000 Subject: Reland r311957 [codeview] support more DW_OPs for more complete debug info Summary: Some variables show up in Visual Studio as "optimized out" even in -O0 -Od builds. This change fixes two issues that would cause this to happen. The first issue is that not all DIExpressions we generate were recognized by the CodeView writer. This has been addressed by adding support for DW_OP_constu, DW_OP_minus, and DW_OP_plus. The second issue is that we had no way to encode DW_OP_deref in CodeView. We get around that by changinge the type we encode in the debug info to be a reference to the type in the source code. This fixes PR34261. The reland adds two extra checks to the original: It checks if the DbgVariableLocation is valid before checking any of its fields, and it only emits ranges with nonzero registers. Reviewers: aprantl, rnk, zturner Reviewed By: rnk Subscribers: mgorny, llvm-commits, aprantl, hiraditya Differential Revision: https://reviews.llvm.org/D36907 llvm-svn: 312034 --- llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp | 51 ++++++++++++++++++++++++ 1 file changed, 51 insertions(+) (limited to 'llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp') diff --git a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp index 0971c594220..4f647de1ed2 100644 --- a/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp +++ b/llvm/lib/CodeGen/AsmPrinter/DebugHandlerBase.cpp @@ -23,6 +23,57 @@ using namespace llvm; +bool DbgVariableLocation::extractFromMachineInstruction( + DbgVariableLocation &Location, const MachineInstr &Instruction) { + if (!Instruction.isDebugValue()) + return false; + if (!Instruction.getOperand(0).isReg()) + return false; + Location.Register = Instruction.getOperand(0).getReg(); + Location.InMemory = Instruction.getOperand(1).isImm(); + Location.Deref = false; + Location.FragmentInfo.reset(); + // We only handle expressions generated by DIExpression::appendOffset, + // which doesn't require a full stack machine. + int64_t Offset = 0; + const DIExpression *DIExpr = Instruction.getDebugExpression(); + auto Op = DIExpr->expr_op_begin(); + while (Op != DIExpr->expr_op_end()) { + switch (Op->getOp()) { + case dwarf::DW_OP_constu: { + int Value = Op->getArg(0); + ++Op; + if (Op != DIExpr->expr_op_end()) { + switch (Op->getOp()) { + case dwarf::DW_OP_minus: + Offset -= Value; + break; + case dwarf::DW_OP_plus: + Offset += Value; + default: + continue; + } + } + } break; + case dwarf::DW_OP_plus_uconst: + Offset += Op->getArg(0); + break; + case dwarf::DW_OP_LLVM_fragment: + Location.FragmentInfo = {Op->getArg(1), Op->getArg(0)}; + break; + case dwarf::DW_OP_deref: + Location.Deref = true; + break; + default: + return false; + } + ++Op; + } + + Location.Offset = Offset; + return true; +} + DebugHandlerBase::DebugHandlerBase(AsmPrinter *A) : Asm(A), MMI(Asm->MMI) {} // Each LexicalScope has first instruction and last instruction to mark -- cgit v1.2.3