LLVM 23.0.0git
DwarfExpression.cpp
Go to the documentation of this file.
1//===- llvm/CodeGen/DwarfExpression.cpp - Dwarf Debug Framework -----------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file contains support for writing dwarf debug info into asm files.
10//
11//===----------------------------------------------------------------------===//
12
13#include "DwarfExpression.h"
14#include "DwarfCompileUnit.h"
15#include "llvm/ADT/APInt.h"
20#include "llvm/IR/DataLayout.h"
21#include "llvm/MC/MCAsmInfo.h"
23#include <algorithm>
24
25using namespace llvm;
26
27#define DEBUG_TYPE "dwarfdebug"
28
30 if (Value < 32)
31 emitOp(dwarf::DW_OP_lit0 + Value);
32 else if (Value == std::numeric_limits<uint64_t>::max()) {
33 // Only do this for 64-bit values as the DWARF expression stack uses
34 // target-address-size values.
35 emitOp(dwarf::DW_OP_lit0);
36 emitOp(dwarf::DW_OP_not);
37 } else {
38 emitOp(dwarf::DW_OP_constu);
40 }
41}
42
43void DwarfExpression::addReg(int64_t DwarfReg, const char *Comment) {
44 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
46 "location description already locked down");
48 if (DwarfReg < 32) {
49 emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
50 } else {
51 emitOp(dwarf::DW_OP_regx, Comment);
52 emitUnsigned(DwarfReg);
53 }
54}
55
56void DwarfExpression::addBReg(int64_t DwarfReg, int64_t Offset) {
57 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
58 assert(!isRegisterLocation() && "location description already locked down");
59 if (DwarfReg < 32) {
60 emitOp(dwarf::DW_OP_breg0 + DwarfReg);
61 } else {
62 emitOp(dwarf::DW_OP_bregx);
63 emitUnsigned(DwarfReg);
64 }
66}
67
69 emitOp(dwarf::DW_OP_fbreg);
71}
72
73void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
74 if (!SizeInBits)
75 return;
76
77 const unsigned SizeOfByte = 8;
78 if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
79 emitOp(dwarf::DW_OP_bit_piece);
80 emitUnsigned(SizeInBits);
82 } else {
83 emitOp(dwarf::DW_OP_piece);
84 unsigned ByteSize = SizeInBits / SizeOfByte;
85 emitUnsigned(ByteSize);
86 }
87 this->OffsetInBits += SizeInBits;
88}
89
90void DwarfExpression::addShr(unsigned ShiftBy) {
91 emitConstu(ShiftBy);
92 emitOp(dwarf::DW_OP_shr);
93}
94
95void DwarfExpression::addAnd(unsigned Mask) {
96 emitConstu(Mask);
97 emitOp(dwarf::DW_OP_and);
98}
99
101 llvm::Register MachineReg,
102 unsigned MaxSize) {
103 if (!MachineReg.isPhysical()) {
104 if (isFrameRegister(TRI, MachineReg)) {
105 DwarfRegs.push_back(Register::createRegister(-1, nullptr));
106 return true;
107 }
108 // Try getting dwarf register for targets that use virtual registers.
109 int64_t Reg = TRI.getDwarfRegNumForVirtReg(MachineReg, false);
110 if (Reg > 0) {
111 DwarfRegs.push_back(Register::createRegister(Reg, nullptr));
112 return true;
113 }
114 return false;
115 }
116
117 int64_t Reg = TRI.getDwarfRegNum(MachineReg, false);
118
119 // If this is a valid register number, emit it.
120 if (Reg >= 0) {
121 DwarfRegs.push_back(Register::createRegister(Reg, nullptr));
122 return true;
123 }
124
125 // Walk up the super-register chain until we find a valid number.
126 // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
127 for (MCPhysReg SR : TRI.superregs(MachineReg)) {
128 Reg = TRI.getDwarfRegNum(SR, false);
129 if (Reg >= 0) {
130 unsigned Idx = TRI.getSubRegIndex(SR, MachineReg);
131 unsigned Size = TRI.getSubRegIdxSize(Idx);
132 unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
133 DwarfRegs.push_back(Register::createRegister(Reg, "super-register"));
134 // Use a DW_OP_bit_piece to describe the sub-register.
135 setSubRegisterPiece(Size, RegOffset);
136 return true;
137 }
138 }
139
140 // Otherwise, attempt to find a covering set of sub-register numbers.
141 // For example, Q0 on ARM is a composition of D0+D1.
142 unsigned CurPos = 0;
143 // The size of the register in bits.
144 const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
145 unsigned RegSize = TRI.getRegSizeInBits(*RC);
146 // Keep track of the bits in the register we already emitted, so we
147 // can avoid emitting redundant aliasing subregs. Because this is
148 // just doing a greedy scan of all subregisters, it is possible that
149 // this doesn't find a combination of subregisters that fully cover
150 // the register (even though one may exist).
151 SmallBitVector Coverage(RegSize, false);
152 for (MCPhysReg SR : TRI.subregs(MachineReg)) {
153 unsigned Idx = TRI.getSubRegIndex(MachineReg, SR);
154 unsigned Size = TRI.getSubRegIdxSize(Idx);
155 unsigned Offset = TRI.getSubRegIdxOffset(Idx);
156 Reg = TRI.getDwarfRegNum(SR, false);
158 continue;
159
160 // Used to build the intersection between the bits we already
161 // emitted and the bits covered by this subregister.
162 SmallBitVector CurSubReg(RegSize, false);
163 CurSubReg.set(Offset, Offset + Size);
164
165 // If this sub-register has a DWARF number and we haven't covered
166 // its range, and its range covers the value, emit a DWARF piece for it.
167 if (Offset < MaxSize && !CurSubReg.subsetOf(Coverage)) {
168 // Emit a piece for any gap in the coverage.
169 if (Offset > CurPos)
171 -1, Offset - CurPos, "no DWARF register encoding"));
172 if (Offset == 0 && Size >= MaxSize)
173 DwarfRegs.push_back(Register::createRegister(Reg, "sub-register"));
174 else
176 Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"));
177 }
178 // Mark it as emitted.
179 Coverage.set(Offset, Offset + Size);
180 CurPos = Offset + Size;
181 }
182 // Failed to find any DWARF encoding.
183 if (CurPos == 0)
184 return false;
185 // Found a partial or complete DWARF encoding.
186 if (CurPos < RegSize)
188 -1, RegSize - CurPos, "no DWARF register encoding"));
189 return true;
190}
191
193 if (DwarfVersion >= 4)
194 emitOp(dwarf::DW_OP_stack_value);
195}
196
200 if (Value == 0)
201 emitOp(dwarf::DW_OP_lit0);
202 else
203 emitOp(dwarf::DW_OP_lit1);
204}
205
212
218
222
223 unsigned Size = Value.getBitWidth();
224 const uint64_t *Data = Value.getRawData();
225
226 // Chop it up into 64-bit pieces, because that's the maximum that
227 // addUnsignedConstant takes.
228 unsigned Offset = 0;
229 while (Offset < Size) {
231 if (Offset == 0 && Size <= 64)
232 break;
234 addOpPiece(std::min(Size - Offset, 64u), Offset);
235 Offset += 64;
236 }
237}
238
240 const AsmPrinter &AP) {
242 assert(DwarfVersion >= 4);
243
244 APInt API = Value;
245 unsigned NumBytes = API.getBitWidth() / 8;
246 assert(API.getBitWidth() == NumBytes * 8 &&
247 "implicit value must be byte-sized");
248
249 emitOp(dwarf::DW_OP_implicit_value);
250 emitUnsigned(NumBytes);
251
252 // The loop below is emitting the value starting at the least significant
253 // byte, so byte-swap first for big-endian targets.
254 if (AP.getDataLayout().isBigEndian())
255 API = API.byteSwap();
256
257 for (unsigned I = 0; I < NumBytes; ++I)
258 emitData1(API.extractBits(8, I * 8).getZExtValue());
259}
260
263 APInt API = APF.bitcastToAPInt();
264 int NumBytes = API.getBitWidth() / 8;
265 if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
266 // FIXME: Add support for `long double`.
267 emitOp(dwarf::DW_OP_implicit_value);
268 emitUnsigned(NumBytes /*Size of the block in bytes*/);
269
270 // The loop below is emitting the value starting at least significant byte,
271 // so we need to perform a byte-swap to get the byte order correct in case
272 // of a big-endian target.
273 if (AP.getDataLayout().isBigEndian())
274 API = API.byteSwap();
275
276 for (int i = 0; i < NumBytes; ++i) {
277 emitData1(API.getZExtValue() & 0xFF);
278 API = API.lshr(8);
279 }
280
281 return;
282 }
284 dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
285 << API.getBitWidth() << " bits\n");
286}
287
289 DIExpressionCursor &ExprCursor,
290 llvm::Register MachineReg,
291 unsigned FragmentOffsetInBits) {
292 auto Fragment = ExprCursor.getFragmentInfo();
293 if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
295 return false;
296 }
297
298 bool HasComplexExpression = false;
299 auto Op = ExprCursor.peek();
300 if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
301 HasComplexExpression = true;
302
303 // If the register can only be described by a complex expression (i.e.,
304 // multiple subregisters) it doesn't safely compose with another complex
305 // expression. For example, it is not possible to apply a DW_OP_deref
306 // operation to multiple DW_OP_pieces, since composite location descriptions
307 // do not push anything on the DWARF stack.
308 //
309 // DW_OP_entry_value operations can only hold a DWARF expression or a
310 // register location description, so we can't emit a single entry value
311 // covering a composite location description. In the future we may want to
312 // emit entry value operations for each register location in the composite
313 // location, but until that is supported do not emit anything.
314 if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {
317 DwarfRegs.clear();
319 return false;
320 }
321
322 // Handle simple register locations. If we are supposed to emit
323 // a call site parameter expression and if that expression is just a register
324 // location, emit it with addBReg and offset 0, because we should emit a DWARF
325 // expression representing a value, rather than a location.
326 if ((!isParameterValue() && !isMemoryLocation() && !HasComplexExpression) ||
327 isEntryValue()) {
328 auto FragmentInfo = ExprCursor.getFragmentInfo();
329 unsigned RegSize = 0;
330 for (auto &Reg : DwarfRegs) {
331 RegSize += Reg.SubRegSize;
332 if (Reg.DwarfRegNo >= 0)
333 addReg(Reg.DwarfRegNo, Reg.Comment);
334 if (FragmentInfo)
335 if (RegSize > FragmentInfo->SizeInBits)
336 // If the register is larger than the current fragment stop
337 // once the fragment is covered.
338 break;
339 addOpPiece(Reg.SubRegSize);
340 }
341
342 if (isEntryValue()) {
344
345 if (!isIndirect() && !isParameterValue() && !HasComplexExpression &&
346 DwarfVersion >= 4)
347 emitOp(dwarf::DW_OP_stack_value);
348 }
349
350 DwarfRegs.clear();
351 // If we need to mask out a subregister, do it now, unless the next
352 // operation would emit an OpPiece anyway.
353 auto NextOp = ExprCursor.peek();
354 if (SubRegisterSizeInBits && NextOp &&
355 (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
357 return true;
358 }
359
360 // Don't emit locations that cannot be expressed without DW_OP_stack_value.
361 if (DwarfVersion < 4)
362 if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
363 return Op.getOp() == dwarf::DW_OP_stack_value;
364 })) {
365 DwarfRegs.clear();
367 return false;
368 }
369
370 // TODO: We should not give up here but the following code needs to be changed
371 // to deal with multiple (sub)registers first.
372 if (DwarfRegs.size() > 1) {
373 LLVM_DEBUG(dbgs() << "TODO: giving up on debug information due to "
374 "multi-register usage.\n");
375 DwarfRegs.clear();
377 return false;
378 }
379
380 auto Reg = DwarfRegs[0];
381 bool FBReg = isFrameRegister(TRI, MachineReg);
382 int SignedOffset = 0;
383 assert(!Reg.isSubRegister() && "full register expected");
384
385 // Pattern-match combinations for which more efficient representations exist.
386 // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
387 if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
388 uint64_t Offset = Op->getArg(0);
389 uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
390 if (Offset <= IntMax) {
391 SignedOffset = Offset;
392 ExprCursor.take();
393 }
394 }
395
396 // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
397 // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
398 // If Reg is a subregister we need to mask it out before subtracting.
399 if (Op && Op->getOp() == dwarf::DW_OP_constu) {
400 uint64_t Offset = Op->getArg(0);
401 uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
402 auto N = ExprCursor.peekNext();
403 if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {
404 SignedOffset = Offset;
405 ExprCursor.consume(2);
406 } else if (N && N->getOp() == dwarf::DW_OP_minus &&
407 !SubRegisterSizeInBits && Offset <= IntMax + 1) {
408 SignedOffset = -static_cast<int64_t>(Offset);
409 ExprCursor.consume(2);
410 }
411 }
412
413 if (FBReg)
414 addFBReg(SignedOffset);
415 else
416 addBReg(Reg.DwarfRegNo, SignedOffset);
417 DwarfRegs.clear();
418
419 // If we need to mask out a subregister, do it now, unless the next
420 // operation would emit an OpPiece anyway.
421 auto NextOp = ExprCursor.peek();
422 if (SubRegisterSizeInBits && NextOp &&
423 (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
425
426 return true;
427}
428
434
436 const DIExpression *DIExpr) {
437 if (Loc.isIndirect())
439
440 if (DIExpr->isEntryValue())
442}
443
445 DIExpressionCursor &ExprCursor) {
446 auto Op = ExprCursor.take();
447 (void)Op;
449 assert(!IsEmittingEntryValue && "Already emitting entry value?");
450 assert(Op->getArg(0) == 1 &&
451 "Can currently only emit entry values covering a single operation");
452
458}
459
461 assert(IsEmittingEntryValue && "Entry value not open?");
463
464 emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
465
466 // Emit the entry value's size operand.
467 unsigned Size = getTemporaryBufferSize();
469
470 // Emit the entry value's DWARF block operand.
472
475 IsEmittingEntryValue = false;
476}
477
479 assert(IsEmittingEntryValue && "Entry value not open?");
481
482 // The temporary buffer can't be emptied, so for now just assert that nothing
483 // has been emitted to it.
485 "Began emitting entry value block before cancelling entry value");
486
488 IsEmittingEntryValue = false;
489}
490
491unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,
492 dwarf::TypeKind Encoding) {
493 // Reuse the base_type if we already have one in this CU otherwise we
494 // create a new one.
495 unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
496 for (; I != E; ++I)
497 if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
498 CU.ExprRefedBaseTypes[I].Encoding == Encoding)
499 break;
500
501 if (I == E)
502 CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
503 return I;
504}
505
506/// Assuming a well-formed expression, match "DW_OP_deref*
507/// DW_OP_LLVM_fragment?".
508static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
509 while (ExprCursor) {
510 auto Op = ExprCursor.take();
511 switch (Op->getOp()) {
512 case dwarf::DW_OP_deref:
514 break;
515 default:
516 return false;
517 }
518 }
519 return true;
520}
521
523 addExpression(std::move(ExprCursor),
524 [](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
525 llvm_unreachable("unhandled opcode found in expression");
526 });
527}
528
530 DIExpressionCursor &&ExprCursor,
531 llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
532 // Entry values can currently only cover the initial register location,
533 // and not any other parts of the following DWARF expression.
534 assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
535
536 std::optional<DIExpression::ExprOperand> PrevConvertOp;
537
538 while (ExprCursor) {
539 auto Op = ExprCursor.take();
540 uint64_t OpNum = Op->getOp();
541
542 if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
543 emitOp(OpNum);
544 continue;
545 } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
546 addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
547 continue;
548 }
549
550 switch (OpNum) {
552 if (!InsertArg(Op->getArg(0), ExprCursor)) {
554 return false;
555 }
556 break;
558 unsigned SizeInBits = Op->getArg(1);
559 unsigned FragmentOffset = Op->getArg(0);
560 // The fragment offset must have already been adjusted by emitting an
561 // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
562 // location.
563 assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
564 assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");
565
566 // If addMachineReg already emitted DW_OP_piece operations to represent
567 // a super-register by splicing together sub-registers, subtract the size
568 // of the pieces that was already emitted.
569 SizeInBits -= OffsetInBits - FragmentOffset;
570
571 // If addMachineReg requested a DW_OP_bit_piece to stencil out a
572 // sub-register that is smaller than the current fragment's size, use it.
574 SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
575
576 // Emit a DW_OP_stack_value for implicit location descriptions.
577 if (isImplicitLocation())
579
580 // Emit the DW_OP_piece.
583 // Reset the location description kind.
585 return true;
586 }
589 unsigned SizeInBits = Op->getArg(1);
590 unsigned BitOffset = Op->getArg(0);
591 unsigned DerefSize = 0;
592 // Operations are done in the DWARF "generic type" whose size
593 // is the size of a pointer.
594 unsigned PtrSizeInBytes = CU.getAsmPrinter()->MAI.getCodePointerSize();
595
596 // If we have a memory location then dereference to get the value, though
597 // we have to make sure we don't dereference any bytes past the end of the
598 // object.
599 if (isMemoryLocation()) {
600 DerefSize = alignTo(BitOffset + SizeInBits, 8) / 8;
601 if (DerefSize == PtrSizeInBytes) {
602 emitOp(dwarf::DW_OP_deref);
603 } else {
604 emitOp(dwarf::DW_OP_deref_size);
605 emitUnsigned(DerefSize);
606 }
607 }
608
609 // If a dereference was emitted for an unsigned value, and
610 // there's no bit offset, then a bit of optimization is
611 // possible.
612 if (OpNum == dwarf::DW_OP_LLVM_extract_bits_zext && BitOffset == 0) {
613 if (8 * DerefSize == SizeInBits) {
614 // The correct value is already on the stack.
615 } else {
616 // No need to shift, we can just mask off the desired bits.
617 emitOp(dwarf::DW_OP_constu);
618 emitUnsigned((1u << SizeInBits) - 1);
619 emitOp(dwarf::DW_OP_and);
620 }
621 } else {
622 // Extract the bits by a shift left (to shift out the bits after what we
623 // want to extract) followed by shift right (to shift the bits to
624 // position 0 and also sign/zero extend).
625 unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset);
626 unsigned RightShift = LeftShift + BitOffset;
627 if (LeftShift) {
628 emitOp(dwarf::DW_OP_constu);
629 emitUnsigned(LeftShift);
630 emitOp(dwarf::DW_OP_shl);
631 }
632 if (RightShift) {
633 emitOp(dwarf::DW_OP_constu);
634 emitUnsigned(RightShift);
636 ? dwarf::DW_OP_shra
637 : dwarf::DW_OP_shr);
638 }
639 }
640
641 // The value is now at the top of the stack, so set the location to
642 // implicit so that we get a stack_value at the end.
644 break;
645 }
646 case dwarf::DW_OP_plus_uconst:
648 emitOp(dwarf::DW_OP_plus_uconst);
649 emitUnsigned(Op->getArg(0));
650 break;
651 case dwarf::DW_OP_plus:
652 case dwarf::DW_OP_minus:
653 case dwarf::DW_OP_mul:
654 case dwarf::DW_OP_div:
655 case dwarf::DW_OP_mod:
656 case dwarf::DW_OP_or:
657 case dwarf::DW_OP_and:
658 case dwarf::DW_OP_xor:
659 case dwarf::DW_OP_shl:
660 case dwarf::DW_OP_shr:
661 case dwarf::DW_OP_shra:
662 case dwarf::DW_OP_lit0:
663 case dwarf::DW_OP_not:
664 case dwarf::DW_OP_dup:
665 case dwarf::DW_OP_push_object_address:
666 case dwarf::DW_OP_over:
667 case dwarf::DW_OP_rot:
668 case dwarf::DW_OP_eq:
669 case dwarf::DW_OP_ne:
670 case dwarf::DW_OP_gt:
671 case dwarf::DW_OP_ge:
672 case dwarf::DW_OP_lt:
673 case dwarf::DW_OP_le:
674 case dwarf::DW_OP_neg:
675 case dwarf::DW_OP_abs:
676 emitOp(OpNum);
677 break;
678 case dwarf::DW_OP_deref:
680 if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))
681 // Turning this into a memory location description makes the deref
682 // implicit.
684 else
685 emitOp(dwarf::DW_OP_deref);
686 break;
687 case dwarf::DW_OP_constu:
689 emitConstu(Op->getArg(0));
690 break;
691 case dwarf::DW_OP_consts:
693 emitOp(dwarf::DW_OP_consts);
694 emitSigned(Op->getArg(0));
695 break;
697 unsigned BitSize = Op->getArg(0);
698 dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
699 if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
700 emitOp(dwarf::DW_OP_convert);
701 // If targeting a location-list; simply emit the index into the raw
702 // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
703 // fitted with means to extract it later.
704 // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
705 // (containing the index and a resolve mechanism during emit) into the
706 // DIE value list.
707 emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));
708 } else {
709 if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
710 if (Encoding == dwarf::DW_ATE_signed)
711 emitLegacySExt(PrevConvertOp->getArg(0));
712 else if (Encoding == dwarf::DW_ATE_unsigned)
713 emitLegacyZExt(PrevConvertOp->getArg(0));
714 PrevConvertOp = std::nullopt;
715 } else {
716 PrevConvertOp = Op;
717 }
718 }
719 break;
720 }
721 case dwarf::DW_OP_stack_value:
723 break;
724 case dwarf::DW_OP_swap:
726 emitOp(dwarf::DW_OP_swap);
727 break;
728 case dwarf::DW_OP_xderef:
730 emitOp(dwarf::DW_OP_xderef);
731 break;
732 case dwarf::DW_OP_deref_size:
733 emitOp(dwarf::DW_OP_deref_size);
734 emitData1(Op->getArg(0));
735 break;
737 TagOffset = Op->getArg(0);
738 break;
739 case dwarf::DW_OP_regx:
740 emitOp(dwarf::DW_OP_regx);
741 emitUnsigned(Op->getArg(0));
742 break;
743 case dwarf::DW_OP_bregx:
744 emitOp(dwarf::DW_OP_bregx);
745 emitUnsigned(Op->getArg(0));
746 emitSigned(Op->getArg(1));
747 break;
749 // Handled in DwarfCompileUnit::emitImplicitPointerLocation for
750 // Loc::Single variables. If we reach here, the variable has a
751 // location list or other unsupported path. Drop the
752 // location rather than crashing.
753 return false;
754 default:
755 llvm_unreachable("unhandled opcode found in expression");
756 }
757 }
758
760 // Turn this into an implicit location description.
762
763 return true;
764}
765
766/// add masking operations to stencil out a subregister.
768 assert(SubRegisterSizeInBits && "no subregister was registered");
771 uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
772 addAnd(Mask);
773}
774
776 assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
777 // Emit any outstanding DW_OP_piece operations to mask out subregisters.
778 if (SubRegisterSizeInBits == 0)
779 return;
780 // Don't emit a DW_OP_piece for a subregister at offset 0.
782 return;
784}
785
787 if (!Expr || !Expr->isFragment())
788 return;
789
790 uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
791 assert(FragmentOffset >= OffsetInBits &&
792 "overlapping or duplicate fragments");
793 if (FragmentOffset > OffsetInBits)
794 addOpPiece(FragmentOffset - OffsetInBits);
795 OffsetInBits = FragmentOffset;
796}
797
798void DwarfExpression::emitLegacySExt(unsigned FromBits) {
799 // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X
800 emitOp(dwarf::DW_OP_dup);
801 emitOp(dwarf::DW_OP_constu);
802 emitUnsigned(FromBits - 1);
803 emitOp(dwarf::DW_OP_shr);
804 emitOp(dwarf::DW_OP_lit0);
805 emitOp(dwarf::DW_OP_not);
806 emitOp(dwarf::DW_OP_mul);
807 emitOp(dwarf::DW_OP_constu);
808 emitUnsigned(FromBits);
809 emitOp(dwarf::DW_OP_shl);
810 emitOp(dwarf::DW_OP_or);
811}
812
813void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
814 // Heuristic to decide the most efficient encoding.
815 // A ULEB can encode 7 1-bits per byte.
816 if (FromBits / 7 < 1+1+1+1+1) {
817 // (X & (1 << FromBits - 1))
818 emitOp(dwarf::DW_OP_constu);
819 emitUnsigned((1ULL << FromBits) - 1);
820 } else {
821 // Note that the DWARF 4 stack consists of pointer-sized elements,
822 // so technically it doesn't make sense to shift left more than 64
823 // bits. We leave that for the consumer to decide though. LLDB for
824 // example uses APInt for the stack elements and can still deal
825 // with this.
826 emitOp(dwarf::DW_OP_lit1);
827 emitOp(dwarf::DW_OP_constu);
828 emitUnsigned(FromBits);
829 emitOp(dwarf::DW_OP_shl);
830 emitOp(dwarf::DW_OP_lit1);
831 emitOp(dwarf::DW_OP_minus);
832 }
833 emitOp(dwarf::DW_OP_and);
834}
835
837 emitOp(dwarf::DW_OP_WASM_location);
838 emitUnsigned(Index == 4/*TI_LOCAL_INDIRECT*/ ? 0/*TI_LOCAL*/ : Index);
840 if (Index == 4 /*TI_LOCAL_INDIRECT*/) {
843 } else {
846 }
847}
unsigned RegSize
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements a class to represent arbitrary precision integral constant values and operations...
static bool isMemoryLocation(DIExpressionCursor ExprCursor)
Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?
This file contains constants used for implementing Dwarf debug support.
#define I(x, y, z)
Definition MD5.cpp:57
Register Reg
Register const TargetRegisterInfo * TRI
This file implements the SmallBitVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:119
APInt bitcastToAPInt() const
Definition APFloat.h:1436
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1563
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1511
LLVM_ABI APInt byteSwap() const
Definition APInt.cpp:768
LLVM_ABI APInt extractBits(unsigned numBits, unsigned bitPosition) const
Return an APInt with the extracted bits [bitPosition,bitPosition+numBits).
Definition APInt.cpp:483
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:858
This class is intended to be used as a driving class for all asm writers.
Definition AsmPrinter.h:91
const DataLayout & getDataLayout() const
Return information about data layout.
Holds a DIExpression and keeps track of how many operands have been consumed so far.
std::optional< DIExpression::ExprOperand > peekNext() const
Return the next operation.
std::optional< DIExpression::FragmentInfo > getFragmentInfo() const
Retrieve the fragment information, if any.
std::optional< DIExpression::ExprOperand > peek() const
Return the current operation.
void consume(unsigned N)
Consume N operations.
std::optional< DIExpression::ExprOperand > take()
Consume one operation.
A lightweight wrapper around an expression operand.
DWARF expression.
LLVM_ABI bool isEntryValue() const
Check if the expression consists of exactly one entry value operand.
bool isFragment() const
Return whether this is a piece of an aggregate variable.
static LLVM_ABI std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
bool isBigEndian() const
Definition DataLayout.h:218
void addAnd(unsigned Mask)
Emit a bitwise and dwarf operation.
void setLocation(const MachineLocation &Loc, const DIExpression *DIExpr)
Set the location (Loc) and DIExpression (DIExpr) to describe.
virtual void emitOp(uint8_t Op, const char *Comment=nullptr)=0
Output a dwarf operand and an optional assembler comment.
virtual void disableTemporaryBuffer()=0
Disable emission to the temporary buffer.
bool isUnknownLocation() const
virtual unsigned getTemporaryBufferSize()=0
Return the emitted size, in number of bytes, for the data stored in the temporary buffer.
uint64_t OffsetInBits
Current Fragment Offset in Bits.
virtual bool isFrameRegister(const TargetRegisterInfo &TRI, llvm::Register MachineReg)=0
Return whether the given machine register is the frame register in the current function.
void finalize()
This needs to be called last to commit any pending changes.
void addFragmentOffset(const DIExpression *Expr)
If applicable, emit an empty DW_OP_piece / DW_OP_bit_piece to advance to the fragment described by Ex...
void emitLegacySExt(unsigned FromBits)
void cancelEntryValue()
Cancel the emission of an entry value.
bool isRegisterLocation() const
void setMemoryLocationKind()
Lock this down to become a memory location description.
virtual void emitBaseTypeRef(uint64_t Idx)=0
virtual void emitData1(uint8_t Value)=0
bool addMachineReg(const TargetRegisterInfo &TRI, llvm::Register MachineReg, unsigned MaxSize=~1U)
Emit a partial DWARF register operation.
std::optional< uint8_t > TagOffset
bool isImplicitLocation() const
virtual void emitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
void addBooleanConstant(int64_t Value)
Emit a boolean constant.
void addConstantFP(const APFloat &Value, const AsmPrinter &AP)
Emit an floating point constant.
void maskSubRegister()
Add masking operations to stencil out a subregister.
SmallVector< Register, 2 > DwarfRegs
The register location, if any.
bool addMachineRegExpression(const TargetRegisterInfo &TRI, DIExpressionCursor &Expr, llvm::Register MachineReg, unsigned FragmentOffsetInBits=0)
Emit a machine register location.
void addStackValue()
Emit a DW_OP_stack_value, if supported.
void finalizeEntryValue()
Finalize an entry value by emitting its size operand, and committing the DWARF block which has been e...
bool isMemoryLocation() const
void addUnsignedConstant(uint64_t Value)
Emit an unsigned constant.
unsigned SubRegisterSizeInBits
Sometimes we need to add a DW_OP_bit_piece to describe a subregister.
void addFBReg(int64_t Offset)
Emit DW_OP_fbreg <Offset>.
void setSubRegisterPiece(unsigned SizeInBits, unsigned OffsetInBits)
Push a DW_OP_piece / DW_OP_bit_piece for emitting later, if one is needed to represent a subregister.
void addExpression(DIExpressionCursor &&Expr)
Emit all remaining operations in the DIExpressionCursor.
unsigned getOrCreateBaseType(unsigned BitSize, dwarf::TypeKind Encoding)
Return the index of a base type with the given properties and create one if necessary.
void addImplicitValue(const APInt &Value, const AsmPrinter &AP)
Emit an implicit value.
void addSignedConstant(int64_t Value)
Emit a signed constant.
void emitLegacyZExt(unsigned FromBits)
bool IsEmittingEntryValue
Whether we are currently emitting an entry value operation.
virtual void emitSigned(int64_t Value)=0
Emit a raw signed value.
void addReg(int64_t DwarfReg, const char *Comment=nullptr)
Emit a DW_OP_reg operation.
void setEntryValueFlags(const MachineLocation &Loc)
Lock this down to become an entry value location.
virtual void commitTemporaryBuffer()=0
Commit the data stored in the temporary buffer to the main output.
void addShr(unsigned ShiftBy)
Emit a shift-right dwarf operation.
void addWasmLocation(unsigned Index, uint64_t Offset)
Emit location information expressed via WebAssembly location + offset The Index is an identifier for ...
virtual void enableTemporaryBuffer()=0
Start emitting data to the temporary buffer.
void emitConstu(uint64_t Value)
Emit a normalized unsigned constant.
void beginEntryValueExpression(DIExpressionCursor &ExprCursor)
Begin emission of an entry value dwarf operation.
void addOpPiece(unsigned SizeInBits, unsigned OffsetInBits=0)
Emit a DW_OP_piece or DW_OP_bit_piece operation for a variable fragment.
void addBReg(int64_t DwarfReg, int64_t Offset)
Emit a DW_OP_breg operation.
Wrapper class representing virtual and physical registers.
Definition Register.h:20
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:83
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
SmallBitVector & set()
bool subsetOf(const SmallBitVector &RHS) const
Check if This is a subset of RHS.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM Value Representation.
Definition Value.h:75
An efficient, type-erasing, non-owning reference to a callable.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ DW_OP_LLVM_entry_value
Only used in LLVM metadata.
Definition Dwarf.h:147
@ DW_OP_LLVM_implicit_pointer
Only used in LLVM metadata.
Definition Dwarf.h:148
@ DW_OP_LLVM_extract_bits_zext
Only used in LLVM metadata.
Definition Dwarf.h:151
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition Dwarf.h:146
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Definition Dwarf.h:144
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
Definition Dwarf.h:149
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
Definition Dwarf.h:145
@ DW_OP_LLVM_extract_bits_sext
Only used in LLVM metadata.
Definition Dwarf.h:150
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:573
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
constexpr uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:144
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
DWARFExpression::Operation Op
#define N
Holds information about all subregisters comprising a register location.
static Register createRegister(int64_t RegNo, const char *Comment)
Create a full register, no extra DW_OP_piece operators necessary.
static Register createSubRegister(int64_t RegNo, unsigned SizeInBits, const char *Comment)
Create a subregister that needs a DW_OP_piece operator with SizeInBits.