llvm.org GIT mirror llvm / b560ea7
PR32382: Fix emitting complex DWARF expressions. The DWARF specification knows 3 kinds of non-empty simple location descriptions: 1. Register location descriptions - describe a variable in a register - consist of only a DW_OP_reg 2. Memory location descriptions - describe the address of a variable 3. Implicit location descriptions - describe the value of a variable - end with DW_OP_stack_value & friends The existing DwarfExpression code is pretty much ignorant of these restrictions. This used to not matter because we only emitted very short expressions that we happened to get right by accident. This patch makes DwarfExpression aware of the rules defined by the DWARF standard and now chooses the right kind of location description for each expression being emitted. This would have been an NFC commit (for the existing testsuite) if not for the way that clang describes captured block variables. Based on how the previous code in LLVM emitted locations, DW_OP_deref operations that should have come at the end of the expression are put at its beginning. Fixing this means changing the semantics of DIExpression, so this patch bumps the version number of DIExpression and implements a bitcode upgrade. There are two major changes in this patch: I had to fix the semantics of dbg.declare for describing function arguments. After this patch a dbg.declare always takes the *address* of a variable as the first argument, even if the argument is not an alloca. When lowering a DBG_VALUE, the decision of whether to emit a register location description or a memory location description depends on the MachineLocation — register machine locations may get promoted to memory locations based on their DIExpression. (Future) optimization passes that want to salvage implicit debug location for variables may do so by appending a DW_OP_stack_value. For example: DBG_VALUE, [RBP-8] --> DW_OP_fbreg -8 DBG_VALUE, RAX --> DW_OP_reg0 +0 DBG_VALUE, RAX, DIExpression(DW_OP_deref) --> DW_OP_reg0 +0 All testcases that were modified were regenerated from clang. I also added source-based testcases for each of these to the debuginfo-tests repository over the last week to make sure that no synchronized bugs slip in. The debuginfo-tests compile from source and run the debugger. https://bugs.llvm.org/show_bug.cgi?id=32382 <rdar://problem/31205000> Differential Revision: https://reviews.llvm.org/D31439 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@300522 91177308-0d34-0410-b5e6-96231b3b80d8 Adrian Prantl 2 years ago
37 changed file(s) with 386 addition(s) and 183 deletion(s). Raw diff Collapse all Expand all
43794379
43804380 The current supported vocabulary is limited:
43814381
4382 - ``DW_OP_deref`` dereferences the working expression.
4382 - ``DW_OP_deref`` dereferences the top of the expression stack.
43834383 - ``DW_OP_plus, 93`` adds ``93`` to the working expression.
43844384 - ``DW_OP_LLVM_fragment, 16, 8`` specifies the offset and size (``16`` and ``8``
43854385 here, respectively) of the variable fragment from the working expression. Note
43954395 location descriptions that describe constant values. This form is used to
43964396 describe global constants that have been optimized away. All other expressions
43974397 are modifiers to another location: A debug intrinsic ties a location and a
4398 DIExpression together. Contrary to DWARF expressions, a DIExpression always
4399 describes the *value* of a source variable and never its *address*. In DWARF
4400 terminology, a DIExpression can always be considered an implicit location
4401 description regardless whether it contains a ``DW_OP_stack_value`` or not.
4402
4403 .. code-block:: text
4398 DIExpression together.
4399
4400 DWARF specifies three kinds of simple location descriptions: Register, memory,
4401 and implicit location descriptions. Register and memory location descriptions
4402 describe the *location* of a source variable (in the sense that a debugger might
4403 modify its value), whereas implicit locations describe merely the *value* of a
4404 source variable. DIExpressions also follow this model: A DIExpression that
4405 doesn't have a trailing ``DW_OP_stack_value`` will describe an *address* when
4406 combined with a concrete location.
4407
4408 .. code-block:: llvm
44044409
44054410 !0 = !DIExpression(DW_OP_deref)
44064411 !1 = !DIExpression(DW_OP_plus, 3)
179179
180180 void @llvm.dbg.declare(metadata, metadata, metadata)
181181
182 This intrinsic provides information about a local element (e.g., variable).
183 The first argument is metadata holding the alloca for the variable. The second
182 This intrinsic provides information about a local element (e.g., variable). The
183 first argument is metadata holding the alloca for the variable. The second
184184 argument is a `local variable `_ containing a
185185 description of the variable. The third argument is a `complex expression
186 `_.
186 `_. An `llvm.dbg.declare` instrinsic describes the
187 *location* of a source variable.
188
189 .. code-block:: llvm
190
191 %i.addr = alloca i32, align 4
192 call void @llvm.dbg.declare(metadata i32* %i.addr, metadata !1, metadata !2), !dbg !3
193 !1 = !DILocalVariable(name: "i", ...) ; int i
194 !2 = !DIExpression()
195 !3 = !DILocation(...)
196 ...
197 %buffer = alloca [256 x i8], align 8
198 ; The address of i is buffer+64.
199 call void @llvm.dbg.declare(metadata [256 x i8]* %buffer, metadata !1, metadata !2)
200 !1 = !DILocalVariable(name: "i", ...) ; int i
201 !2 = !DIExpression(DW_OP_plus, 64)
202
187203
188204 ``llvm.dbg.value``
189205 ^^^^^^^^^^^^^^^^^^
411411 const MCInstrDesc &MCID, bool IsIndirect,
412412 unsigned Reg, unsigned Offset,
413413 const MDNode *Variable, const MDNode *Expr);
414
415 /// Clone a DBG_VALUE whose value has been spilled to FrameIndex.
416 MachineInstr *buildDbgValueForSpill(MachineBasicBlock &BB,
417 MachineBasicBlock::iterator I,
418 const MachineInstr &Orig, int FrameIndex);
414419
415420 inline unsigned getDefRegState(bool B) {
416421 return B ? RegState::Define : 0;
22312231 expr_op_iterator expr_op_end() const {
22322232 return expr_op_iterator(elements_end());
22332233 }
2234 iterator_range expr_ops() const {
2235 return {expr_op_begin(), expr_op_end()};
2236 }
22342237 /// @}
22352238
22362239 bool isValid() const;
22392242 return MD->getMetadataID() == DIExpressionKind;
22402243 }
22412244
2242 /// Is the first element a DW_OP_deref?.
2245 /// Return whether the first element a DW_OP_deref.
22432246 bool startsWithDeref() const {
22442247 return getNumElements() > 0 && getElement(0) == dwarf::DW_OP_deref;
22452248 }
26302630
26312631 // Look for intrinsic functions which need to be upgraded at some point
26322632 for (Function &F : *TheModule) {
2633 MDLoader->upgradeDebugIntrinsics(F);
26332634 Function *NewFn;
26342635 if (UpgradeIntrinsicFunction(&F, NewFn))
26352636 UpgradedIntrinsics[&F] = NewFn;
5353 #include "llvm/IR/Instruction.h"
5454 #include "llvm/IR/Instructions.h"
5555 #include "llvm/IR/Intrinsics.h"
56 #include "llvm/IR/IntrinsicInst.h"
5657 #include "llvm/IR/LLVMContext.h"
5758 #include "llvm/IR/Module.h"
5859 #include "llvm/IR/ModuleSummaryIndex.h"
451452 bool StripTBAA = false;
452453 bool HasSeenOldLoopTags = false;
453454 bool NeedUpgradeToDIGlobalVariableExpression = false;
455 bool NeedDeclareExpressionUpgrade = false;
454456
455457 /// True if metadata is being parsed for a module being ThinLTO imported.
456458 bool IsImporting = false;
510512 }
511513 }
512514
515 /// Remove a leading DW_OP_deref from DIExpressions in a dbg.declare that
516 /// describes a function argument.
517 void upgradeDeclareExpressions(Function &F) {
518 if (!NeedDeclareExpressionUpgrade)
519 return;
520
521 for (auto &BB : F)
522 for (auto &I : BB)
523 if (auto *DDI = dyn_cast(&I))
524 if (auto *DIExpr = DDI->getExpression())
525 if (DIExpr->startsWithDeref() &&
526 dyn_cast_or_null(DDI->getAddress())) {
527 SmallVector Ops;
528 Ops.append(std::next(DIExpr->elements_begin()),
529 DIExpr->elements_end());
530 auto *E = DIExpression::get(Context, Ops);
531 DDI->setOperand(2, MetadataAsValue::get(Context, E));
532 }
533 }
534
513535 void upgradeDebugInfo() {
514536 upgradeCUSubprograms();
515537 upgradeCUVariables();
564586
565587 unsigned size() const { return MetadataList.size(); }
566588 void shrinkTo(unsigned N) { MetadataList.shrinkTo(N); }
589 void upgradeDebugIntrinsics(Function &F) { upgradeDeclareExpressions(F); }
567590 };
568591
569592 static Error error(const Twine &Message) {
15191542 return error("Invalid record");
15201543
15211544 IsDistinct = Record[0] & 1;
1522 bool HasOpFragment = Record[0] & 2;
1545 uint64_t Version = Record[0] >> 1;
15231546 auto Elts = MutableArrayRef(Record).slice(1);
1524 if (!HasOpFragment)
1525 if (unsigned N = Elts.size())
1526 if (N >= 3 && Elts[N - 3] == dwarf::DW_OP_bit_piece)
1527 Elts[N - 3] = dwarf::DW_OP_LLVM_fragment;
1547 unsigned N = Elts.size();
1548 // Perform various upgrades.
1549 switch (Version) {
1550 case 0:
1551 if (N >= 3 && Elts[N - 3] == dwarf::DW_OP_bit_piece)
1552 Elts[N - 3] = dwarf::DW_OP_LLVM_fragment;
1553 LLVM_FALLTHROUGH;
1554 case 1:
1555 // Move DW_OP_deref to the end.
1556 if (N && Elts[0] == dwarf::DW_OP_deref) {
1557 auto End = Elts.end();
1558 if (Elts.size() >= 3 && *std::prev(End, 3) == dwarf::DW_OP_LLVM_fragment)
1559 End = std::prev(End, 3);
1560 std::move(std::next(Elts.begin()), End, Elts.begin());
1561 *std::prev(End) = dwarf::DW_OP_deref;
1562 }
1563 NeedDeclareExpressionUpgrade = true;
1564 LLVM_FALLTHROUGH;
1565 case 2:
1566 // Up-to-date!
1567 break;
1568 default:
1569 return error("Invalid record");
1570 }
15281571
15291572 MetadataList.assignValue(
15301573 GET_OR_DISTINCT(DIExpression, (Context, makeArrayRef(Record).slice(1))),
18571900
18581901 unsigned MetadataLoader::size() const { return Pimpl->size(); }
18591902 void MetadataLoader::shrinkTo(unsigned N) { return Pimpl->shrinkTo(N); }
1903
1904 void MetadataLoader::upgradeDebugIntrinsics(Function &F) {
1905 return Pimpl->upgradeDebugIntrinsics(F);
1906 }
7878
7979 unsigned size() const;
8080 void shrinkTo(unsigned N);
81
82 /// Perform bitcode upgrades on llvm.dbg.* calls.
83 void upgradeDebugIntrinsics(Function &F);
8184 };
8285 }
8386
17701770 SmallVectorImpl &Record,
17711771 unsigned Abbrev) {
17721772 Record.reserve(N->getElements().size() + 1);
1773
1774 const uint64_t HasOpFragmentFlag = 1 << 1;
1775 Record.push_back((uint64_t)N->isDistinct() | HasOpFragmentFlag);
1773 const uint64_t Version = 2 << 1;
1774 Record.push_back((uint64_t)N->isDistinct() | Version);
17761775 Record.append(N->elements_begin(), N->elements_end());
17771776
17781777 Stream.EmitRecord(bitc::METADATA_EXPRESSION, Record, Abbrev);
833833 OS << " <- ";
834834
835835 // The second operand is only an offset if it's an immediate.
836 bool Deref = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
837 int64_t Offset = Deref ? MI->getOperand(1).getImm() : 0;
838
836 bool Deref = false;
837 bool MemLoc = MI->getOperand(0).isReg() && MI->getOperand(1).isImm();
838 int64_t Offset = MemLoc ? MI->getOperand(1).getImm() : 0;
839839 for (unsigned i = 0; i < Expr->getNumElements(); ++i) {
840840 uint64_t Op = Expr->getElement(i);
841841 if (Op == dwarf::DW_OP_LLVM_fragment) {
843843 break;
844844 } else if (Deref) {
845845 // We currently don't support extra Offsets or derefs after the first
846 // one. Bail out early instead of emitting an incorrect comment
846 // one. Bail out early instead of emitting an incorrect comment.
847847 OS << " [complex expression]";
848848 AP.OutStreamer->emitRawComment(OS.str());
849849 return true;
898898 AP.OutStreamer->emitRawComment(OS.str());
899899 return true;
900900 }
901 if (Deref)
901 if (MemLoc || Deref)
902902 OS << '[';
903903 OS << PrintReg(Reg, AP.MF->getSubtarget().getRegisterInfo());
904904 }
905905
906 if (Deref)
906 if (MemLoc || Deref)
907907 OS << '+' << Offset << ']';
908908
909909 // NOTE: Want this comment at start of line, don't emit with AddComment.
546546 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
547547 for (auto &Fragment : DV.getFrameIndexExprs()) {
548548 unsigned FrameReg = 0;
549 const DIExpression *Expr = Fragment.Expr;
549550 const TargetFrameLowering *TFI = Asm->MF->getSubtarget().getFrameLowering();
550551 int Offset = TFI->getFrameIndexReference(*Asm->MF, Fragment.FI, FrameReg);
551 DwarfExpr.addFragmentOffset(Fragment.Expr);
552 DwarfExpr.addFragmentOffset(Expr);
552553 SmallVector Ops;
553554 Ops.push_back(dwarf::DW_OP_plus);
554555 Ops.push_back(Offset);
555 Ops.push_back(dwarf::DW_OP_deref);
556 Ops.append(Fragment.Expr->elements_begin(), Fragment.Expr->elements_end());
557 DIExpressionCursor Expr(Ops);
558 DwarfExpr.addMachineRegExpression(
559 *Asm->MF->getSubtarget().getRegisterInfo(), Expr, FrameReg);
560 DwarfExpr.addExpression(std::move(Expr));
556 Ops.append(Expr->elements_begin(), Expr->elements_end());
557 DIExpressionCursor Cursor(Ops);
558 DwarfExpr.addMachineLocExpression(
559 *Asm->MF->getSubtarget().getRegisterInfo(), Cursor,
560 MachineLocation(FrameReg));
561 DwarfExpr.addExpression(std::move(Cursor));
561562 }
562563 addBlock(*VariableDie, dwarf::DW_AT_location, DwarfExpr.finalize());
563564
780781 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
781782
782783 SmallVector Ops;
783 if (Location.isIndirect()) {
784 if (Location.isIndirect() && Location.getOffset()) {
784785 Ops.push_back(dwarf::DW_OP_plus);
785786 Ops.push_back(Location.getOffset());
786 Ops.push_back(dwarf::DW_OP_deref);
787787 }
788788 DIExpressionCursor Cursor(Ops);
789789 const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
790 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
790 if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
791791 return;
792792 DwarfExpr.addExpression(std::move(Cursor));
793793
808808 DwarfExpr.addFragmentOffset(DIExpr);
809809
810810 SmallVector Ops;
811 if (Location.isIndirect()) {
811 if (Location.isIndirect() && Location.getOffset()) {
812812 Ops.push_back(dwarf::DW_OP_plus);
813813 Ops.push_back(Location.getOffset());
814 Ops.push_back(dwarf::DW_OP_deref);
815814 }
816815 Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
817816 DIExpressionCursor Cursor(Ops);
818817 const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
819 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
818 if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
820819 return;
821820 DwarfExpr.addExpression(std::move(Cursor));
822821
15161516 DwarfExpr.addUnsignedConstant(Value.getInt());
15171517 } else if (Value.isLocation()) {
15181518 MachineLocation Location = Value.getLoc();
1519
15201519 SmallVector Ops;
1521 // FIXME: Should this condition be Location.isIndirect() instead?
1522 if (Location.getOffset()) {
1520 if (Location.isIndirect() && Location.getOffset()) {
15231521 Ops.push_back(dwarf::DW_OP_plus);
15241522 Ops.push_back(Location.getOffset());
1525 Ops.push_back(dwarf::DW_OP_deref);
15261523 }
15271524 Ops.append(DIExpr->elements_begin(), DIExpr->elements_end());
15281525 DIExpressionCursor Cursor(Ops);
15291526 const TargetRegisterInfo &TRI = *AP.MF->getSubtarget().getRegisterInfo();
1530 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
1527 if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
15311528 return;
15321529 return DwarfExpr.addExpression(std::move(Cursor));
15331530 } else if (Value.isConstantFP()) {
2222 using namespace llvm;
2323
2424 void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
25 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
26 if (DwarfReg < 32) {
27 emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
25 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
26 assert((LocationKind == Unknown || LocationKind == Register) &&
27 "location description already locked down");
28 LocationKind = Register;
29 if (DwarfReg < 32) {
30 emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
2831 } else {
2932 emitOp(dwarf::DW_OP_regx, Comment);
3033 emitUnsigned(DwarfReg);
3336
3437 void DwarfExpression::addBReg(int DwarfReg, int Offset) {
3538 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
39 assert(LocationKind != Register && "location description already locked down");
3640 if (DwarfReg < 32) {
3741 emitOp(dwarf::DW_OP_breg0 + DwarfReg);
3842 } else {
155159 }
156160
157161 void DwarfExpression::addSignedConstant(int64_t Value) {
162 assert(LocationKind == Implicit || LocationKind == Unknown);
163 LocationKind = Implicit;
158164 emitOp(dwarf::DW_OP_consts);
159165 emitSigned(Value);
160 addStackValue();
161166 }
162167
163168 void DwarfExpression::addUnsignedConstant(uint64_t Value) {
169 assert(LocationKind == Implicit || LocationKind == Unknown);
170 LocationKind = Implicit;
164171 emitOp(dwarf::DW_OP_constu);
165172 emitUnsigned(Value);
166 addStackValue();
167173 }
168174
169175 void DwarfExpression::addUnsignedConstant(const APInt &Value) {
176 assert(LocationKind == Implicit || LocationKind == Unknown);
177 LocationKind = Implicit;
178
170179 unsigned Size = Value.getBitWidth();
171180 const uint64_t *Data = Value.getRawData();
172181
177186 addUnsignedConstant(*Data++);
178187 if (Offset == 0 && Size <= 64)
179188 break;
180 addOpPiece(std::min(Size-Offset, 64u), Offset);
189 addStackValue();
190 addOpPiece(std::min(Size - Offset, 64u), Offset);
181191 Offset += 64;
182192 }
183193 }
184194
185 bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
195 bool DwarfExpression::addMachineLocExpression(const TargetRegisterInfo &TRI,
186196 DIExpressionCursor &ExprCursor,
187 unsigned MachineReg,
197 MachineLocation Loc,
188198 unsigned FragmentOffsetInBits) {
199 if (Loc.isIndirect())
200 LocationKind = Memory;
201
202 unsigned MachineReg = Loc.getReg();
189203 auto Fragment = ExprCursor.getFragmentInfo();
190204 if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U))
191205 return false;
205219 }
206220
207221 // Handle simple register locations.
208 if (!HasComplexExpression) {
222 if (LocationKind != Memory && !HasComplexExpression) {
209223 for (auto &Reg : DwarfRegs) {
210224 if (Reg.DwarfRegNo >= 0)
211225 addReg(Reg.DwarfRegNo, Reg.Comment);
215229 return true;
216230 }
217231
232 // FIXME:
233 // Don't emit locations that cannot be expressed without DW_OP_stack_value.
234
218235 assert(DwarfRegs.size() == 1);
219236 auto Reg = DwarfRegs[0];
220 bool FBReg = isFrameRegister(TRI, MachineReg);
237 bool FBReg = isFrameRegister(TRI, MachineReg);
238 int SignedOffset = 0;
221239 assert(Reg.Size == 0 && "subregister has same size as superregister");
222240
223241 // Pattern-match combinations for which more efficient representations exist.
224 switch (Op->getOp()) {
225 default: {
226 if (FBReg)
227 addFBReg(0);
228 else
229 addReg(Reg.DwarfRegNo, 0);
230 break;
231 }
232 case dwarf::DW_OP_plus:
233 case dwarf::DW_OP_minus: {
234 // [DW_OP_reg,Offset,DW_OP_plus, DW_OP_deref] --> [DW_OP_breg, Offset].
235 // [DW_OP_reg,Offset,DW_OP_minus,DW_OP_deref] --> [DW_OP_breg,-Offset].
236 auto N = ExprCursor.peekNext();
237 if (N && N->getOp() == dwarf::DW_OP_deref) {
238 int Offset = Op->getArg(0);
239 int SignedOffset = (Op->getOp() == dwarf::DW_OP_plus) ? Offset : -Offset;
240 if (FBReg)
241 addFBReg(SignedOffset);
242 else
243 addBReg(Reg.DwarfRegNo, SignedOffset);
244
245 ExprCursor.consume(2);
246 break;
247 }
248 addReg(Reg.DwarfRegNo, 0);
249 break;
250 }
251 case dwarf::DW_OP_deref:
252 // [DW_OP_reg,DW_OP_deref] --> [DW_OP_breg].
253 if (FBReg)
254 addFBReg(0);
255 else
256 addBReg(Reg.DwarfRegNo, 0);
242 // [Reg, Offset, DW_OP_plus] --> [DW_OP_breg, Offset].
243 // [Reg, Offset, DW_OP_minus] --> [DW_OP_breg, -Offset].
244 // If Reg is a subregister we need to mask it out before subtracting.
245 if (Op && ((Op->getOp() == dwarf::DW_OP_plus) ||
246 (Op->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
247 int Offset = Op->getArg(0);
248 SignedOffset = (Op->getOp() == dwarf::DW_OP_plus) ? Offset : -Offset;
257249 ExprCursor.take();
258 break;
259 }
250 }
251 if (FBReg)
252 addFBReg(SignedOffset);
253 else
254 addBReg(Reg.DwarfRegNo, SignedOffset);
260255 DwarfRegs.clear();
261256 return true;
262257 }
263258
259 /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
260 static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
261 while (ExprCursor) {
262 auto Op = ExprCursor.take();
263 switch (Op->getOp()) {
264 case dwarf::DW_OP_deref:
265 case dwarf::DW_OP_LLVM_fragment:
266 break;
267 default:
268 return false;
269 }
270 }
271 return true;
272 }
273
264274 void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
265275 unsigned FragmentOffsetInBits) {
276 // If we need to mask out a subregister, do it now, unless the next
277 // operation would emit an OpPiece anyway.
278 auto N = ExprCursor.peek();
279 if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
280 maskSubRegister();
281
266282 while (ExprCursor) {
267283 auto Op = ExprCursor.take();
268
269 // If we need to mask out a subregister, do it now, unless the next
270 // operation would emit an OpPiece anyway.
271 if (SubRegisterSizeInBits && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
272 maskSubRegister();
273
274284 switch (Op->getOp()) {
275285 case dwarf::DW_OP_LLVM_fragment: {
276286 unsigned SizeInBits = Op->getArg(1);
280290 // location.
281291 assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
282292
283 // If \a addMachineReg already emitted DW_OP_piece operations to represent
293 // If addMachineReg already emitted DW_OP_piece operations to represent
284294 // a super-register by splicing together sub-registers, subtract the size
285295 // of the pieces that was already emitted.
286296 SizeInBits -= OffsetInBits - FragmentOffset;
287297
288 // If \a addMachineReg requested a DW_OP_bit_piece to stencil out a
298 // If addMachineReg requested a DW_OP_bit_piece to stencil out a
289299 // sub-register that is smaller than the current fragment's size, use it.
290300 if (SubRegisterSizeInBits)
291301 SizeInBits = std::min(SizeInBits, SubRegisterSizeInBits);
292
302
303 // Emit a DW_OP_stack_value for implicit location descriptions.
304 if (LocationKind == Implicit)
305 addStackValue();
306
307 // Emit the DW_OP_piece.
293308 addOpPiece(SizeInBits, SubRegisterOffsetInBits);
294309 setSubRegisterPiece(0, 0);
295 break;
310 // Reset the location description kind.
311 LocationKind = Unknown;
312 return;
296313 }
297314 case dwarf::DW_OP_plus:
315 assert(LocationKind != Register);
298316 emitOp(dwarf::DW_OP_plus_uconst);
299317 emitUnsigned(Op->getArg(0));
300318 break;
301319 case dwarf::DW_OP_minus:
302 // There is no OP_minus_uconst.
320 assert(LocationKind != Register);
321 // There is no DW_OP_minus_uconst.
303322 emitOp(dwarf::DW_OP_constu);
304323 emitUnsigned(Op->getArg(0));
305324 emitOp(dwarf::DW_OP_minus);
306325 break;
307 case dwarf::DW_OP_deref:
308 emitOp(dwarf::DW_OP_deref);
309 break;
326 case dwarf::DW_OP_deref: {
327 assert(LocationKind != Register);
328 if (LocationKind != Memory && isMemoryLocation(ExprCursor))
329 // Turning this into a memory location description makes the deref
330 // implicit.
331 LocationKind = Memory;
332 else
333 emitOp(dwarf::DW_OP_deref);
334 break;
335 }
310336 case dwarf::DW_OP_constu:
337 assert(LocationKind != Register);
311338 emitOp(dwarf::DW_OP_constu);
312339 emitUnsigned(Op->getArg(0));
313340 break;
314341 case dwarf::DW_OP_stack_value:
315 addStackValue();
342 assert(LocationKind == Unknown || LocationKind == Implicit);
343 LocationKind = Implicit;
316344 break;
317345 case dwarf::DW_OP_swap:
346 assert(LocationKind != Register);
318347 emitOp(dwarf::DW_OP_swap);
319348 break;
320349 case dwarf::DW_OP_xderef:
350 assert(LocationKind != Register);
321351 emitOp(dwarf::DW_OP_xderef);
322352 break;
323353 default:
324354 llvm_unreachable("unhandled opcode found in expression");
325355 }
326356 }
357
358 if (LocationKind == Implicit)
359 // Turn this into an implicit location description.
360 addStackValue();
327361 }
328362
329363 /// add masking operations to stencil out a subregister.
1515
1616 #include "llvm/IR/DebugInfo.h"
1717 #include "llvm/Support/DataTypes.h"
18 #include "llvm/MC/MachineLocation.h"
1819
1920 namespace llvm {
2021
101102 unsigned SubRegisterSizeInBits = 0;
102103 unsigned SubRegisterOffsetInBits = 0;
103104
105 /// The kind of location description being produced.
106 enum { Unknown = 0, Register, Memory, Implicit } LocationKind = Unknown;
107
104108 /// Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed
105109 /// to represent a subregister.
106110 void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits) {
107111 SubRegisterSizeInBits = SizeInBits;
108112 SubRegisterOffsetInBits = OffsetInBits;
109113 }
114
115 void setMemoryLocationKind();
110116
111117 /// Add masking operations to stencil out a subregister.
112118 void maskSubRegister();
121127 /// current function.
122128 virtual bool isFrameRegister(const TargetRegisterInfo &TRI, unsigned MachineReg) = 0;
123129
124 /// Emit a DW_OP_reg operation.
130 /// Emit a DW_OP_reg operation. Note that this is only legal inside a DWARF
131 /// register location description.
125132 void addReg(int DwarfReg, const char *Comment = nullptr);
126133 /// Emit a DW_OP_breg operation.
127134 void addBReg(int DwarfReg, int Offset);
193200 /// fragment inside the entire variable.
194201 /// \return false if no DWARF register exists
195202 /// for MachineReg.
196 bool addMachineRegExpression(const TargetRegisterInfo &TRI,
197 DIExpressionCursor &Expr, unsigned MachineReg,
203 bool addMachineLocExpression(const TargetRegisterInfo &TRI,
204 DIExpressionCursor &Expr, MachineLocation Loc,
198205 unsigned FragmentOffsetInBits = 0);
199206 /// Emit all remaining operations in the DIExpressionCursor.
200207 ///
473473 DIEDwarfExpression DwarfExpr(*Asm, *this, *Loc);
474474
475475 SmallVector Ops;
476 if (Location.isIndirect()) {
476 if (Location.isIndirect() && Location.getOffset()) {
477477 Ops.push_back(dwarf::DW_OP_plus);
478478 Ops.push_back(Location.getOffset());
479 Ops.push_back(dwarf::DW_OP_deref);
480479 }
481480 // If we started with a pointer to the __Block_byref... struct, then
482481 // the first thing we need to do is dereference the pointer (DW_OP_deref).
505504
506505 DIExpressionCursor Cursor(Ops);
507506 const TargetRegisterInfo &TRI = *Asm->MF->getSubtarget().getRegisterInfo();
508 if (!DwarfExpr.addMachineRegExpression(TRI, Cursor, Location.getReg()))
507 if (!DwarfExpr.addMachineLocExpression(TRI, Cursor, Location))
509508 return;
510509 DwarfExpr.addExpression(std::move(Cursor));
511510
887887 // Debug values are not allowed to affect codegen.
888888 if (MI->isDebugValue()) {
889889 // Modify DBG_VALUE now that the value is in a spill slot.
890 bool IsIndirect = MI->isIndirectDebugValue();
891 uint64_t Offset = IsIndirect ? MI->getOperand(1).getImm() : 0;
892 const MDNode *Var = MI->getDebugVariable();
893 const MDNode *Expr = MI->getDebugExpression();
894 DebugLoc DL = MI->getDebugLoc();
895 DEBUG(dbgs() << "Modifying debug info due to spill:" << "\t" << *MI);
896890 MachineBasicBlock *MBB = MI->getParent();
897 assert(cast(Var)->isValidLocationForIntrinsic(DL) &&
898 "Expected inlined-at fields to agree");
899 BuildMI(*MBB, MBB->erase(MI), DL, TII.get(TargetOpcode::DBG_VALUE))
900 .addFrameIndex(StackSlot)
901 .addImm(Offset)
902 .addMetadata(Var)
903 .addMetadata(Expr);
891 DEBUG(dbgs() << "Modifying debug info due to spill:\t" << *MI);
892 buildDbgValueForSpill(*MBB, MI, *MI, StackSlot);
893 MBB->erase(MI);
904894 continue;
905895 }
906896
23502350 BB.insert(I, MI);
23512351 return MachineInstrBuilder(MF, MI);
23522352 }
2353
2354 MachineInstr *llvm::buildDbgValueForSpill(MachineBasicBlock &BB,
2355 MachineBasicBlock::iterator I,
2356 const MachineInstr &Orig,
2357 int FrameIndex) {
2358 const MDNode *Var = Orig.getDebugVariable();
2359 auto *Expr = cast_or_null(Orig.getDebugExpression());
2360 bool IsIndirect = Orig.isIndirectDebugValue();
2361 uint64_t Offset = IsIndirect ? Orig.getOperand(1).getImm() : 0;
2362 DebugLoc DL = Orig.getDebugLoc();
2363 assert(cast(Var)->isValidLocationForIntrinsic(DL) &&
2364 "Expected inlined-at fields to agree");
2365 // If the DBG_VALUE already was a memory location, add an extra
2366 // DW_OP_deref. Otherwise just turning this from a register into a
2367 // memory/indirect location is sufficient.
2368 if (IsIndirect) {
2369 SmallVector Ops;
2370 Ops.push_back(dwarf::DW_OP_deref);
2371 if (Expr)
2372 Ops.append(Expr->elements_begin(), Expr->elements_end());
2373 Expr = DIExpression::get(Expr->getContext(), Ops);
2374 }
2375 return BuildMI(BB, I, DL, Orig.getDesc())
2376 .addFrameIndex(FrameIndex)
2377 .addImm(Offset)
2378 .addMetadata(Var)
2379 .addMetadata(Expr);
2380 }
303303 LiveDbgValueMap[LRI->VirtReg];
304304 for (unsigned li = 0, le = LRIDbgValues.size(); li != le; ++li) {
305305 MachineInstr *DBG = LRIDbgValues[li];
306 const MDNode *Var = DBG->getDebugVariable();
307 const MDNode *Expr = DBG->getDebugExpression();
308 bool IsIndirect = DBG->isIndirectDebugValue();
309 uint64_t Offset = IsIndirect ? DBG->getOperand(1).getImm() : 0;
310 DebugLoc DL = DBG->getDebugLoc();
311 assert(cast(Var)->isValidLocationForIntrinsic(DL) &&
312 "Expected inlined-at fields to agree");
313 MachineInstr *NewDV =
314 BuildMI(*MBB, MI, DL, TII->get(TargetOpcode::DBG_VALUE))
315 .addFrameIndex(FI)
316 .addImm(Offset)
317 .addMetadata(Var)
318 .addMetadata(Expr);
306 MachineInstr *NewDV = buildDbgValueForSpill(*MBB, MI, *DBG, FI);
319307 assert(NewDV->getParent() == MBB && "dangling parent pointer");
320308 (void)NewDV;
321309 DEBUG(dbgs() << "Inserting debug info due to spill:" << "\n" << *NewDV);
549549
550550 // Replace alloc with the new location.
551551 replaceDbgDeclare(Arg, BasePointer, BasePointer->getNextNode(), DIB,
552 /*Deref=*/true, -Offset);
552 /*Deref=*/false, -Offset);
553553 Arg->replaceAllUsesWith(NewArg);
554554 IRB.SetInsertPoint(cast(NewArg)->getNextNode());
555555 IRB.CreateMemCpy(Off, Arg, Size, Arg->getParamAlignment());
564564 if (Size == 0)
565565 Size = 1; // Don't create zero-sized stack objects.
566566
567 replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/true, -Offset);
567 replaceDbgDeclareForAlloca(AI, BasePointer, DIB, /*Deref=*/false, -Offset);
568568 replaceDbgValueForAlloca(AI, BasePointer, DIB, -Offset);
569569
570570 // Replace uses of the alloca with the new location.
654654 if (AI->hasName() && isa(NewAI))
655655 NewAI->takeName(AI);
656656
657 replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/true);
657 replaceDbgDeclareForAlloca(AI, NewAI, DIB, /*Deref=*/false);
658658 AI->replaceAllUsesWith(NewAI);
659659 AI->eraseFromParent();
660660 }
11631163 "Expected inlined-at fields to agree");
11641164 if (Op->isReg()) {
11651165 Op->setIsDebug(true);
1166 // A dbg.declare describes the address of a source variable, so lower it
1167 // into an indirect DBG_VALUE.
11661168 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
1167 TII.get(TargetOpcode::DBG_VALUE), false, Op->getReg(), 0,
1168 DI->getVariable(), DI->getExpression());
1169 TII.get(TargetOpcode::DBG_VALUE), /*IsIndirect*/ true,
1170 Op->getReg(), 0, DI->getVariable(), DI->getExpression());
11691171 } else
11701172 BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc,
11711173 TII.get(TargetOpcode::DBG_VALUE))
46734673 /// At the end of instruction selection, they will be inserted to the entry BB.
46744674 bool SelectionDAGBuilder::EmitFuncArgumentDbgValue(
46754675 const Value *V, DILocalVariable *Variable, DIExpression *Expr,
4676 DILocation *DL, int64_t Offset, bool IsIndirect, const SDValue &N) {
4676 DILocation *DL, int64_t Offset, bool IsDbgDeclare, const SDValue &N) {
46774677 const Argument *Arg = dyn_cast(V);
46784678 if (!Arg)
46794679 return false;
46874687 if (!Variable->getScope()->getSubprogram()->describes(MF.getFunction()))
46884688 return false;
46894689
4690 bool IsIndirect = false;
46904691 Optional Op;
46914692 // Some arguments' frame index is recorded during argument lowering.
46924693 if (int FI = FuncInfo.getArgumentFrameIndex(Arg))
47004701 if (PR)
47014702 Reg = PR;
47024703 }
4703 if (Reg)
4704 if (Reg) {
47044705 Op = MachineOperand::CreateReg(Reg, false);
4706 IsIndirect = IsDbgDeclare;
4707 }
47054708 }
47064709
47074710 if (!Op) {
47084711 // Check if ValueMap has reg number.
47094712 DenseMap::iterator VMI = FuncInfo.ValueMap.find(V);
4710 if (VMI != FuncInfo.ValueMap.end())
4713 if (VMI != FuncInfo.ValueMap.end()) {
47114714 Op = MachineOperand::CreateReg(VMI->second, false);
4715 IsIndirect = IsDbgDeclare;
4716 }
47124717 }
47134718
47144719 if (!Op && N.getNode())
49544959 } else if (isa(Address)) {
49554960 // Address is an argument, so try to emit its dbg value using
49564961 // virtual register info from the FuncInfo.ValueMap.
4957 EmitFuncArgumentDbgValue(Address, Variable, Expression, dl, 0, false,
4958 N);
4962 EmitFuncArgumentDbgValue(Address, Variable, Expression, dl, 0, true, N);
49594963 return nullptr;
49604964 } else {
49614965 SDV = DAG.getDbgValue(Variable, Expression, N.getNode(), N.getResNo(),
49654969 } else {
49664970 // If Address is an argument then try to emit its dbg value using
49674971 // virtual register info from the FuncInfo.ValueMap.
4968 if (!EmitFuncArgumentDbgValue(Address, Variable, Expression, dl, 0, false,
4972 if (!EmitFuncArgumentDbgValue(Address, Variable, Expression, dl, 0, true,
49694973 N)) {
49704974 // If variable is pinned by a alloca in dominating bb then
49714975 // use StaticAllocaMap.
927927 /// instruction selection, they will be inserted to the entry BB.
928928 bool EmitFuncArgumentDbgValue(const Value *V, DILocalVariable *Variable,
929929 DIExpression *Expr, DILocation *DL,
930 int64_t Offset, bool IsIndirect,
930 int64_t Offset, bool IsDbgDeclare,
931931 const SDValue &N);
932932
933933 /// Return the next block after MBB, or nullptr if there is none.
25852585 Value *NewAllocaPtr = IRB.CreateIntToPtr(
25862586 IRB.CreateAdd(LocalStackBase, ConstantInt::get(IntptrTy, Desc.Offset)),
25872587 AI->getType());
2588 replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB, /*Deref=*/true);
2588 replaceDbgDeclareForAlloca(AI, NewAllocaPtr, DIB, /*Deref=*/false);
25892589 AI->replaceAllUsesWith(NewAllocaPtr);
25902590 }
25912591
12261226 // This is a call by-value or some other instruction that
12271227 // takes a pointer to the variable. Insert a *value*
12281228 // intrinsic that describes the alloca.
1229 SmallVector NewDIExpr;
1230 auto *DIExpr = DDI->getExpression();
1231 NewDIExpr.push_back(dwarf::DW_OP_deref);
1232 NewDIExpr.append(DIExpr->elements_begin(), DIExpr->elements_end());
12331229 DIB.insertDbgValueIntrinsic(AI, 0, DDI->getVariable(),
1234 DIB.createExpression(NewDIExpr),
1235 DDI->getDebugLoc(), CI);
1230 DDI->getExpression(), DDI->getDebugLoc(),
1231 CI);
12361232 }
12371233 }
12381234 DDI->eraseFromParent();
0 ; RUN: llvm-dis -o - %s.bc | FileCheck %s
1 %class.A = type { i32, i32, i32, i32 }
2
3 define void @_Z3fooi(%class.A* sret %agg.result) #0 !dbg !3 {
4 ; CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[EXPR:[0-9]+]]), !dbg
5 ; CHECK: ![[EXPR]] = !DIExpression()
6 call void @llvm.dbg.declare(metadata %class.A* %agg.result, metadata !13, metadata !16), !dbg !17
7 ret void, !dbg !17
8 }
9
10 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1
11
12 attributes #0 = { ssp }
13 attributes #1 = { nounwind readnone }
14
15 !llvm.dbg.cu = !{!0}
16 !llvm.module.flags = !{!2}
17
18 !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug)
19 !1 = !DIFile(filename: "a.cc", directory: "/tmp")
20 !2 = !{i32 1, !"Debug Info Version", i32 3}
21 !3 = distinct !DISubprogram(name: "foo", linkageName: "_Z3fooi", scope: !1, file: !1, line: 4, type: !4, isLocal: false, isDefinition: true, virtualIndex: 6, flags: DIFlagPrototyped, isOptimized: false, unit: !0)
22 !4 = !DISubroutineType(types: !5)
23 !5 = !{!6}
24 !6 = !DICompositeType(tag: DW_TAG_class_type, name: "A", scope: !0, file: !1, line: 2, size: 128, align: 32, elements: !7)
25 !7 = !{!8, !10, !11, !12}
26 !8 = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !1, file: !1, line: 2, baseType: !9, size: 32, align: 32)
27 !9 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed)
28 !10 = !DIDerivedType(tag: DW_TAG_member, name: "y", scope: !1, file: !1, line: 2, baseType: !9, size: 32, align: 32, offset: 32)
29 !11 = !DIDerivedType(tag: DW_TAG_member, name: "z", scope: !1, file: !1, line: 2, baseType: !9, size: 32, align: 32, offset: 64)
30 !12 = !DIDerivedType(tag: DW_TAG_member, name: "o", scope: !1, file: !1, line: 2, baseType: !9, size: 32, align: 32, offset: 96)
31 !13 = !DILocalVariable(name: "my_a", scope: !14, file: !1, line: 9, type: !15)
32 !14 = distinct !DILexicalBlock(scope: !3, file: !1, line: 4, column: 14)
33 !15 = !DIDerivedType(tag: DW_TAG_reference_type, file: !1, baseType: !6)
34 !16 = !DIExpression(DW_OP_deref)
35 !17 = !DILocation(line: 9, column: 5, scope: !3)
0 ; RUN: llvm-dis -o - %s.bc | FileCheck %s
1
2 !llvm.dbg.cu = !{!1}
3 !llvm.module.flags = !{!20, !21}
4
5 !0 = distinct !DIGlobalVariable(name: "g", scope: !1, file: !2, line: 1, type: !5, isLocal: false, isDefinition: true)
6 !1 = distinct !DICompileUnit(language: DW_LANG_C99, file: !2, producer: "clang (llvm/trunk 288154)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !3, globals: !4)
7 !2 = !DIFile(filename: "a.c", directory: "/")
8 !3 = !{}
9 !4 = !{!10, !11, !12, !13}
10 !5 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
11 ; DW_OP_deref should be moved to the back of the expression.
12 ;
13 ; CHECK: !DIExpression(DW_OP_plus, 0, DW_OP_deref, DW_OP_LLVM_fragment, 8, 32)
14 !6 = !DIExpression(DW_OP_deref, DW_OP_plus, 0, DW_OP_LLVM_fragment, 8, 32)
15 ; CHECK: !DIExpression(DW_OP_plus, 0, DW_OP_deref)
16 !7 = !DIExpression(DW_OP_deref, DW_OP_plus, 0)
17 ; CHECK: !DIExpression(DW_OP_plus, 1, DW_OP_deref)
18 !8 = !DIExpression(DW_OP_plus, 1, DW_OP_deref)
19 ; CHECK: !DIExpression(DW_OP_deref)
20 !9 = !DIExpression(DW_OP_deref)
21 !10 = !DIGlobalVariableExpression(var: !0, expr: !6)
22 !11 = !DIGlobalVariableExpression(var: !0, expr: !7)
23 !12 = !DIGlobalVariableExpression(var: !0, expr: !8)
24 !13 = !DIGlobalVariableExpression(var: !0, expr: !9)
25 !20 = !{i32 2, !"Dwarf Version", i32 4}
26 !21 = !{i32 2, !"Debug Info Version", i32 3}
1212 ; and SelectionDAGISel crashes. It should definitely not
1313 ; crash. Drop the dbg_value instead.
1414 ; CHECK-NOT: "matrix"
15 tail call void @llvm.dbg.declare(metadata %class.Matrix3.0.6.10* %agg.result, metadata !45, metadata !DIExpression(DW_OP_deref))
15 tail call void @llvm.dbg.declare(metadata %class.Matrix3.0.6.10* %agg.result, metadata !45, metadata !DIExpression())
1616 %2 = getelementptr inbounds %class.Matrix3.0.6.10, %class.Matrix3.0.6.10* %agg.result, i32 0, i32 0, i32 8
1717 ret void
1818 }
1212
1313 ; Check that the location of the ASAN instrumented __block variable is
1414 ; correct.
15 ; CHECK: !DIExpression(DW_OP_deref, DW_OP_plus, 8, DW_OP_deref, DW_OP_plus, 24)
15 ; CHECK: !DIExpression(DW_OP_plus, 8, DW_OP_deref, DW_OP_plus, 24)
1616
1717 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1818
None ; RUN: llc -O0 -fast-isel=false < %s | FileCheck %s
0 ; RUN: llc -O0 -fast-isel=true -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
11 target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
22 target triple = "x86_64-apple-macosx10.6.7"
3 ;Radar 9321650
4
5 ;CHECK: ##DEBUG_VALUE: my_a
3 ; rdar://problem/9321650
4 ;
5 ; CHECK: DW_AT_name {{.*}}"j"
6 ; CHECK: DW_TAG_variable
7 ; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x00000000)
8 ; CHECK-NEXT: DW_AT_name {{.*}}"my_a"
9 ; CHECK: .debug_loc contents:
10 ; CHECK: 0x00000000: Beginning address offset:
11 ; CHECK-NEXT: Ending address offset:
12 ; CHECK-NEXT: Location description: 77 08
13 ; rsp+8
614
715 %class.A = type { i32, i32, i32, i32 }
816
6969
7070 ;
7171 store i32 %0, i32* %3, align 4
72 call void @llvm.dbg.declare(metadata %struct.A* %agg.result, metadata !24, metadata !DIExpression(DW_OP_deref)), !dbg !25
72 call void @llvm.dbg.declare(metadata %struct.A* %agg.result, metadata !24, metadata !DIExpression()), !dbg !25
7373 call void @_ZN1AC1Ev(%struct.A* %agg.result), !dbg !25
7474 store i64 1172321806, i64* %4, !dbg !26
7575 %29 = inttoptr i64 %10 to i32*, !dbg !26
106106 !106 = !DILocation(line: 40, scope: !42)
107107 !107 = !DIFile(filename: "llvm/tools/clang/test/CodeGenObjC/debug-info-block-captured-self.m", directory: "")
108108 !108 = !{i32 1, !"Debug Info Version", i32 3}
109 !109 = !DIExpression(DW_OP_deref, DW_OP_plus, 32)
110 !110 = !DIExpression(DW_OP_deref, DW_OP_plus, 32)
109 !109 = !DIExpression(DW_OP_plus, 32, DW_OP_deref)
110 !110 = !DIExpression(DW_OP_plus, 32, DW_OP_deref)
99 ; Capture(buf);
1010 ; }
1111 ; }
12 ; The interesting part is !DIExpression(DW_OP_deref, DW_OP_minus, 400)
12 ; The interesting part is !DIExpression(DW_OP_minus, 400)
1313
1414 target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
1515 target triple = "x86_64-unknown-linux-gnu"
5555 !14 = !{i32 2, !"Debug Info Version", i32 3}
5656 !15 = !{!"clang version 3.8.0 (trunk 248518) (llvm/trunk 248512)"}
5757 !16 = !DILocation(line: 5, column: 3, scope: !4)
58 !17 = !DIExpression(DW_OP_deref, DW_OP_minus, 400)
58 !17 = !DIExpression(DW_OP_minus, 400)
5959 !18 = !DILocation(line: 5, column: 7, scope: !4)
6060 !19 = !DILocation(line: 6, column: 11, scope: !4)
6161 !20 = !DILocation(line: 6, column: 3, scope: !4)
6262 !21 = !DILocation(line: 7, column: 1, scope: !4)
6363
6464 ; RCX - 400
65 ; CHECK: .short 6 # Loc expr size
65 ; CHECK: .short 3 # Loc expr size
6666 ; CHECK-NEXT: .byte 114 # DW_OP_breg2
67 ; CHECK-NEXT: .byte 0 # 0
68 ; CHECK-NEXT: .byte 16 # DW_OP_constu
69 ; CHECK-NEXT: .byte 144 # 400
70 ; CHECK-NEXT: .byte 3 # DW_OP_minus
71 ; CHECK-NEXT: .byte 28
67 ; CHECK-NEXT: .byte 240 # -400
68 ; CHECK-NEXT: .byte 124
7269
7370 ; RCX is clobbered in call @Capture, but there is a spilled copy.
7471 ; *(RSP + 8) - 400
77
88 ; CHECK: Beginning address offset: 0x0000000000000000
99 ; CHECK: Ending address offset: 0x0000000000000004
10 ; CHECK: Location description: 50 10 ff ff ff ff 0f 1a 10 01 1c
11 ; rax, constu 0xffffffff, and, constu 0x00000001, minus
10 ; CHECK: Location description: 70 00 10 ff ff ff ff 0f 1a 10 01 1c 9f
11 ; rax+0, constu 0xffffffff, and, constu 0x00000001, minus, stack-value
1212 source_filename = "minus.c"
1313 target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
1414 target triple = "x86_64-apple-macosx10.12.0"
4141 !10 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
4242 !11 = !{!12}
4343 !12 = !DILocalVariable(name: "i", arg: 1, scope: !7, file: !1, line: 1, type: !10)
44 !13 = !DIExpression(DW_OP_minus, 1)
44 !13 = !DIExpression(DW_OP_minus, 1, DW_OP_stack_value)
4545 !14 = !DILocation(line: 1, column: 13, scope: !7)
4646 !15 = !DILocation(line: 2, column: 11, scope: !7)
4747 !16 = !DILocation(line: 2, column: 3, scope: !7)
0 ; RUN: llc -split-dwarf=Enable -O0 %s -mtriple=x86_64-unknown-linux-gnu -filetype=obj -o %t
1 ; RUN: llvm-dwarfdump -debug-dump=all %t | FileCheck %s
1 ; RUN: llvm-dwarfdump -debug-dump=all %t | FileCheck %s --check-prefix=CHECK-DWO
22
33 ; Based on the debuginfo-tests/sret.cpp code.
44
5 ; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x51ac5644b1937aa1)
6 ; CHECK: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x51ac5644b1937aa1)
5 ; CHECK-DWO: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x51ac5644b1937aa1)
6 ; CHECK-DWO: DW_AT_GNU_dwo_id [DW_FORM_data8] (0x51ac5644b1937aa1)
7
8 ; RUN: llc -O0 -fast-isel=true -mtriple=x86_64-apple-darwin -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
9 ; RUN: llc -O0 -fast-isel=false -mtriple=x86_64-apple-darwin -filetype=obj -o - %s | llvm-dwarfdump - | FileCheck %s
10 ; CHECK: _ZN1B9AInstanceEv
11 ; CHECK: DW_TAG_variable
12 ; CHECK-NEXT: DW_AT_location [DW_FORM_sec_offset] (0x00000000)
13 ; CHECK-NEXT: DW_AT_name {{.*}}"a"
14 ; CHECK: .debug_loc contents:
15 ; CHECK: 0x00000000: Beginning address offset:
16 ; CHECK-NEXT: Ending address offset:
17 ; CHECK-NEXT: Location description: 75 00
18 ; rdi+0
719
820 %class.A = type { i32 (...)**, i32 }
921 %class.B = type { i8 }
97109 call void @llvm.dbg.declare(metadata %class.B** %this.addr, metadata !89, metadata !DIExpression()), !dbg !91
98110 %this1 = load %class.B*, %class.B** %this.addr
99111 store i1 false, i1* %nrvo, !dbg !92
100 call void @llvm.dbg.declare(metadata %class.A* %agg.result, metadata !93, metadata !DIExpression(DW_OP_deref)), !dbg !92
112 call void @llvm.dbg.declare(metadata %class.A* %agg.result, metadata !93, metadata !DIExpression()), !dbg !92
101113 call void @_ZN1AC1Ei(%class.A* %agg.result, i32 12), !dbg !92
102114 store i1 true, i1* %nrvo, !dbg !94
103115 store i32 1, i32* %cleanup.dest.slot
2323 ; CHECK: entry:
2424 ; Verify that llvm.dbg.declare calls are in the entry basic block.
2525 ; CHECK-NOT: %entry
26 ; CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[ARG_ID:[0-9]+]], metadata ![[OPDEREF:[0-9]+]])
26 ; CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[ARG_ID:[0-9]+]], metadata ![[EMPTY:[0-9]+]])
2727 ; CHECK-NOT: %entry
28 ; CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[VAR_ID:[0-9]+]], metadata ![[OPDEREF:[0-9]+]])
28 ; CHECK: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[VAR_ID:[0-9]+]], metadata ![[EMPTY:[0-9]+]])
2929
3030 declare void @llvm.dbg.declare(metadata, metadata, metadata) nounwind readnone
3131
4646 ; Verify that debug descriptors for argument and local variable will be replaced
4747 ; with descriptors that end with OpDeref (encoded as 2).
4848 ; CHECK: ![[ARG_ID]] = !DILocalVariable(name: "p", arg: 1,{{.*}} line: 1
49 ; CHECK: ![[OPDEREF]] = !DIExpression(DW_OP_deref)
49 ; CHECK: ![[EMPTY]] = !DIExpression()
5050 ; CHECK: ![[VAR_ID]] = !DILocalVariable(name: "r",{{.*}} line: 2
5151 ; Verify that there are no more variable descriptors.
5252 ; CHECK-NOT: !DILocalVariable(tag: DW_TAG_arg_variable
3636
3737 ; CHECK-DAG: ![[VAR_ARG]] = !DILocalVariable(name: "zzz"
3838 ; 100 aligned up to 8
39 ; CHECK-DAG: ![[EXPR_ARG]] = !DIExpression(DW_OP_deref, DW_OP_minus, 104
39 ; CHECK-DAG: ![[EXPR_ARG]] = !DIExpression(DW_OP_minus, 104)
4040
4141 ; CHECK-DAG: ![[VAR_LOCAL]] = !DILocalVariable(name: "xxx"
42 ; CHECK-DAG: ![[EXPR_LOCAL]] = !DIExpression(DW_OP_deref, DW_OP_minus, 208
42 ; CHECK-DAG: ![[EXPR_LOCAL]] = !DIExpression(DW_OP_minus, 208)
4343
4444 ; Function Attrs: nounwind readnone
4545 declare void @llvm.dbg.declare(metadata, metadata, metadata) #1