LLVM 22.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 virtual register anyway, eg. for NVPTX.
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);
157 if (Reg < 0)
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.test(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
241 APInt API = APF.bitcastToAPInt();
242 int NumBytes = API.getBitWidth() / 8;
243 if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
244 // FIXME: Add support for `long double`.
245 emitOp(dwarf::DW_OP_implicit_value);
246 emitUnsigned(NumBytes /*Size of the block in bytes*/);
247
248 // The loop below is emitting the value starting at least significant byte,
249 // so we need to perform a byte-swap to get the byte order correct in case
250 // of a big-endian target.
251 if (AP.getDataLayout().isBigEndian())
252 API = API.byteSwap();
253
254 for (int i = 0; i < NumBytes; ++i) {
255 emitData1(API.getZExtValue() & 0xFF);
256 API = API.lshr(8);
257 }
258
259 return;
260 }
262 dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
263 << API.getBitWidth() << " bits\n");
264}
265
267 DIExpressionCursor &ExprCursor,
268 llvm::Register MachineReg,
269 unsigned FragmentOffsetInBits) {
270 auto Fragment = ExprCursor.getFragmentInfo();
271 if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
273 return false;
274 }
275
276 bool HasComplexExpression = false;
277 auto Op = ExprCursor.peek();
278 if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
279 HasComplexExpression = true;
280
281 // If the register can only be described by a complex expression (i.e.,
282 // multiple subregisters) it doesn't safely compose with another complex
283 // expression. For example, it is not possible to apply a DW_OP_deref
284 // operation to multiple DW_OP_pieces, since composite location descriptions
285 // do not push anything on the DWARF stack.
286 //
287 // DW_OP_entry_value operations can only hold a DWARF expression or a
288 // register location description, so we can't emit a single entry value
289 // covering a composite location description. In the future we may want to
290 // emit entry value operations for each register location in the composite
291 // location, but until that is supported do not emit anything.
292 if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {
295 DwarfRegs.clear();
297 return false;
298 }
299
300 // Handle simple register locations. If we are supposed to emit
301 // a call site parameter expression and if that expression is just a register
302 // location, emit it with addBReg and offset 0, because we should emit a DWARF
303 // expression representing a value, rather than a location.
304 if ((!isParameterValue() && !isMemoryLocation() && !HasComplexExpression) ||
305 isEntryValue()) {
306 auto FragmentInfo = ExprCursor.getFragmentInfo();
307 unsigned RegSize = 0;
308 for (auto &Reg : DwarfRegs) {
309 RegSize += Reg.SubRegSize;
310 if (Reg.DwarfRegNo >= 0)
311 addReg(Reg.DwarfRegNo, Reg.Comment);
312 if (FragmentInfo)
313 if (RegSize > FragmentInfo->SizeInBits)
314 // If the register is larger than the current fragment stop
315 // once the fragment is covered.
316 break;
317 addOpPiece(Reg.SubRegSize);
318 }
319
320 if (isEntryValue()) {
322
323 if (!isIndirect() && !isParameterValue() && !HasComplexExpression &&
324 DwarfVersion >= 4)
325 emitOp(dwarf::DW_OP_stack_value);
326 }
327
328 DwarfRegs.clear();
329 // If we need to mask out a subregister, do it now, unless the next
330 // operation would emit an OpPiece anyway.
331 auto NextOp = ExprCursor.peek();
332 if (SubRegisterSizeInBits && NextOp &&
333 (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
335 return true;
336 }
337
338 // Don't emit locations that cannot be expressed without DW_OP_stack_value.
339 if (DwarfVersion < 4)
340 if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
341 return Op.getOp() == dwarf::DW_OP_stack_value;
342 })) {
343 DwarfRegs.clear();
345 return false;
346 }
347
348 // TODO: We should not give up here but the following code needs to be changed
349 // to deal with multiple (sub)registers first.
350 if (DwarfRegs.size() > 1) {
351 LLVM_DEBUG(dbgs() << "TODO: giving up on debug information due to "
352 "multi-register usage.\n");
353 DwarfRegs.clear();
355 return false;
356 }
357
358 auto Reg = DwarfRegs[0];
359 bool FBReg = isFrameRegister(TRI, MachineReg);
360 int SignedOffset = 0;
361 assert(!Reg.isSubRegister() && "full register expected");
362
363 // Pattern-match combinations for which more efficient representations exist.
364 // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
365 if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
366 uint64_t Offset = Op->getArg(0);
367 uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
368 if (Offset <= IntMax) {
369 SignedOffset = Offset;
370 ExprCursor.take();
371 }
372 }
373
374 // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
375 // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
376 // If Reg is a subregister we need to mask it out before subtracting.
377 if (Op && Op->getOp() == dwarf::DW_OP_constu) {
378 uint64_t Offset = Op->getArg(0);
379 uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
380 auto N = ExprCursor.peekNext();
381 if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {
382 SignedOffset = Offset;
383 ExprCursor.consume(2);
384 } else if (N && N->getOp() == dwarf::DW_OP_minus &&
385 !SubRegisterSizeInBits && Offset <= IntMax + 1) {
386 SignedOffset = -static_cast<int64_t>(Offset);
387 ExprCursor.consume(2);
388 }
389 }
390
391 if (FBReg)
392 addFBReg(SignedOffset);
393 else
394 addBReg(Reg.DwarfRegNo, SignedOffset);
395 DwarfRegs.clear();
396
397 // If we need to mask out a subregister, do it now, unless the next
398 // operation would emit an OpPiece anyway.
399 auto NextOp = ExprCursor.peek();
400 if (SubRegisterSizeInBits && NextOp &&
401 (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
403
404 return true;
405}
406
412
414 const DIExpression *DIExpr) {
415 if (Loc.isIndirect())
417
418 if (DIExpr->isEntryValue())
420}
421
423 DIExpressionCursor &ExprCursor) {
424 auto Op = ExprCursor.take();
425 (void)Op;
427 assert(!IsEmittingEntryValue && "Already emitting entry value?");
428 assert(Op->getArg(0) == 1 &&
429 "Can currently only emit entry values covering a single operation");
430
436}
437
439 assert(IsEmittingEntryValue && "Entry value not open?");
441
442 emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
443
444 // Emit the entry value's size operand.
445 unsigned Size = getTemporaryBufferSize();
447
448 // Emit the entry value's DWARF block operand.
450
453 IsEmittingEntryValue = false;
454}
455
457 assert(IsEmittingEntryValue && "Entry value not open?");
459
460 // The temporary buffer can't be emptied, so for now just assert that nothing
461 // has been emitted to it.
463 "Began emitting entry value block before cancelling entry value");
464
466 IsEmittingEntryValue = false;
467}
468
469unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,
470 dwarf::TypeKind Encoding) {
471 // Reuse the base_type if we already have one in this CU otherwise we
472 // create a new one.
473 unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
474 for (; I != E; ++I)
475 if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
476 CU.ExprRefedBaseTypes[I].Encoding == Encoding)
477 break;
478
479 if (I == E)
480 CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
481 return I;
482}
483
484/// Assuming a well-formed expression, match "DW_OP_deref*
485/// DW_OP_LLVM_fragment?".
486static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
487 while (ExprCursor) {
488 auto Op = ExprCursor.take();
489 switch (Op->getOp()) {
490 case dwarf::DW_OP_deref:
492 break;
493 default:
494 return false;
495 }
496 }
497 return true;
498}
499
501 addExpression(std::move(ExprCursor),
502 [](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
503 llvm_unreachable("unhandled opcode found in expression");
504 });
505}
506
508 DIExpressionCursor &&ExprCursor,
509 llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
510 // Entry values can currently only cover the initial register location,
511 // and not any other parts of the following DWARF expression.
512 assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
513
514 std::optional<DIExpression::ExprOperand> PrevConvertOp;
515
516 while (ExprCursor) {
517 auto Op = ExprCursor.take();
518 uint64_t OpNum = Op->getOp();
519
520 if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
521 emitOp(OpNum);
522 continue;
523 } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
524 addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
525 continue;
526 }
527
528 switch (OpNum) {
530 if (!InsertArg(Op->getArg(0), ExprCursor)) {
532 return false;
533 }
534 break;
536 unsigned SizeInBits = Op->getArg(1);
537 unsigned FragmentOffset = Op->getArg(0);
538 // The fragment offset must have already been adjusted by emitting an
539 // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
540 // location.
541 assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
542 assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");
543
544 // If addMachineReg already emitted DW_OP_piece operations to represent
545 // a super-register by splicing together sub-registers, subtract the size
546 // of the pieces that was already emitted.
547 SizeInBits -= OffsetInBits - FragmentOffset;
548
549 // If addMachineReg requested a DW_OP_bit_piece to stencil out a
550 // sub-register that is smaller than the current fragment's size, use it.
552 SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
553
554 // Emit a DW_OP_stack_value for implicit location descriptions.
555 if (isImplicitLocation())
557
558 // Emit the DW_OP_piece.
561 // Reset the location description kind.
563 return true;
564 }
567 unsigned SizeInBits = Op->getArg(1);
568 unsigned BitOffset = Op->getArg(0);
569
570 // If we have a memory location then dereference to get the value, though
571 // we have to make sure we don't dereference any bytes past the end of the
572 // object.
573 if (isMemoryLocation()) {
574 emitOp(dwarf::DW_OP_deref_size);
575 emitUnsigned(alignTo(BitOffset + SizeInBits, 8) / 8);
576 }
577
578 // Extract the bits by a shift left (to shift out the bits after what we
579 // want to extract) followed by shift right (to shift the bits to position
580 // 0 and also sign/zero extend). These operations are done in the DWARF
581 // "generic type" whose size is the size of a pointer.
582 unsigned PtrSizeInBytes = CU.getAsmPrinter()->MAI->getCodePointerSize();
583 unsigned LeftShift = PtrSizeInBytes * 8 - (SizeInBits + BitOffset);
584 unsigned RightShift = LeftShift + BitOffset;
585 if (LeftShift) {
586 emitOp(dwarf::DW_OP_constu);
587 emitUnsigned(LeftShift);
588 emitOp(dwarf::DW_OP_shl);
589 }
590 emitOp(dwarf::DW_OP_constu);
591 emitUnsigned(RightShift);
592 emitOp(OpNum == dwarf::DW_OP_LLVM_extract_bits_sext ? dwarf::DW_OP_shra
593 : dwarf::DW_OP_shr);
594
595 // The value is now at the top of the stack, so set the location to
596 // implicit so that we get a stack_value at the end.
598 break;
599 }
600 case dwarf::DW_OP_plus_uconst:
602 emitOp(dwarf::DW_OP_plus_uconst);
603 emitUnsigned(Op->getArg(0));
604 break;
605 case dwarf::DW_OP_plus:
606 case dwarf::DW_OP_minus:
607 case dwarf::DW_OP_mul:
608 case dwarf::DW_OP_div:
609 case dwarf::DW_OP_mod:
610 case dwarf::DW_OP_or:
611 case dwarf::DW_OP_and:
612 case dwarf::DW_OP_xor:
613 case dwarf::DW_OP_shl:
614 case dwarf::DW_OP_shr:
615 case dwarf::DW_OP_shra:
616 case dwarf::DW_OP_lit0:
617 case dwarf::DW_OP_not:
618 case dwarf::DW_OP_dup:
619 case dwarf::DW_OP_push_object_address:
620 case dwarf::DW_OP_over:
621 case dwarf::DW_OP_eq:
622 case dwarf::DW_OP_ne:
623 case dwarf::DW_OP_gt:
624 case dwarf::DW_OP_ge:
625 case dwarf::DW_OP_lt:
626 case dwarf::DW_OP_le:
627 emitOp(OpNum);
628 break;
629 case dwarf::DW_OP_deref:
631 if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))
632 // Turning this into a memory location description makes the deref
633 // implicit.
635 else
636 emitOp(dwarf::DW_OP_deref);
637 break;
638 case dwarf::DW_OP_constu:
640 emitConstu(Op->getArg(0));
641 break;
642 case dwarf::DW_OP_consts:
644 emitOp(dwarf::DW_OP_consts);
645 emitSigned(Op->getArg(0));
646 break;
648 unsigned BitSize = Op->getArg(0);
649 dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
650 if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
651 emitOp(dwarf::DW_OP_convert);
652 // If targeting a location-list; simply emit the index into the raw
653 // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
654 // fitted with means to extract it later.
655 // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
656 // (containing the index and a resolve mechanism during emit) into the
657 // DIE value list.
658 emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));
659 } else {
660 if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
661 if (Encoding == dwarf::DW_ATE_signed)
662 emitLegacySExt(PrevConvertOp->getArg(0));
663 else if (Encoding == dwarf::DW_ATE_unsigned)
664 emitLegacyZExt(PrevConvertOp->getArg(0));
665 PrevConvertOp = std::nullopt;
666 } else {
667 PrevConvertOp = Op;
668 }
669 }
670 break;
671 }
672 case dwarf::DW_OP_stack_value:
674 break;
675 case dwarf::DW_OP_swap:
677 emitOp(dwarf::DW_OP_swap);
678 break;
679 case dwarf::DW_OP_xderef:
681 emitOp(dwarf::DW_OP_xderef);
682 break;
683 case dwarf::DW_OP_deref_size:
684 emitOp(dwarf::DW_OP_deref_size);
685 emitData1(Op->getArg(0));
686 break;
688 TagOffset = Op->getArg(0);
689 break;
690 case dwarf::DW_OP_regx:
691 emitOp(dwarf::DW_OP_regx);
692 emitUnsigned(Op->getArg(0));
693 break;
694 case dwarf::DW_OP_bregx:
695 emitOp(dwarf::DW_OP_bregx);
696 emitUnsigned(Op->getArg(0));
697 emitSigned(Op->getArg(1));
698 break;
699 default:
700 llvm_unreachable("unhandled opcode found in expression");
701 }
702 }
703
705 // Turn this into an implicit location description.
707
708 return true;
709}
710
711/// add masking operations to stencil out a subregister.
713 assert(SubRegisterSizeInBits && "no subregister was registered");
716 uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
717 addAnd(Mask);
718}
719
721 assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
722 // Emit any outstanding DW_OP_piece operations to mask out subregisters.
723 if (SubRegisterSizeInBits == 0)
724 return;
725 // Don't emit a DW_OP_piece for a subregister at offset 0.
727 return;
729}
730
732 if (!Expr || !Expr->isFragment())
733 return;
734
735 uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
736 assert(FragmentOffset >= OffsetInBits &&
737 "overlapping or duplicate fragments");
738 if (FragmentOffset > OffsetInBits)
739 addOpPiece(FragmentOffset - OffsetInBits);
740 OffsetInBits = FragmentOffset;
741}
742
743void DwarfExpression::emitLegacySExt(unsigned FromBits) {
744 // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X
745 emitOp(dwarf::DW_OP_dup);
746 emitOp(dwarf::DW_OP_constu);
747 emitUnsigned(FromBits - 1);
748 emitOp(dwarf::DW_OP_shr);
749 emitOp(dwarf::DW_OP_lit0);
750 emitOp(dwarf::DW_OP_not);
751 emitOp(dwarf::DW_OP_mul);
752 emitOp(dwarf::DW_OP_constu);
753 emitUnsigned(FromBits);
754 emitOp(dwarf::DW_OP_shl);
755 emitOp(dwarf::DW_OP_or);
756}
757
758void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
759 // Heuristic to decide the most efficient encoding.
760 // A ULEB can encode 7 1-bits per byte.
761 if (FromBits / 7 < 1+1+1+1+1) {
762 // (X & (1 << FromBits - 1))
763 emitOp(dwarf::DW_OP_constu);
764 emitUnsigned((1ULL << FromBits) - 1);
765 } else {
766 // Note that the DWARF 4 stack consists of pointer-sized elements,
767 // so technically it doesn't make sense to shift left more than 64
768 // bits. We leave that for the consumer to decide though. LLDB for
769 // example uses APInt for the stack elements and can still deal
770 // with this.
771 emitOp(dwarf::DW_OP_lit1);
772 emitOp(dwarf::DW_OP_constu);
773 emitUnsigned(FromBits);
774 emitOp(dwarf::DW_OP_shl);
775 emitOp(dwarf::DW_OP_lit1);
776 emitOp(dwarf::DW_OP_minus);
777 }
778 emitOp(dwarf::DW_OP_and);
779}
780
782 emitOp(dwarf::DW_OP_WASM_location);
783 emitUnsigned(Index == 4/*TI_LOCAL_INDIRECT*/ ? 0/*TI_LOCAL*/ : Index);
785 if (Index == 4 /*TI_LOCAL_INDIRECT*/) {
788 } else {
791 }
792}
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:58
Register const TargetRegisterInfo * TRI
This file implements the SmallBitVector class.
#define LLVM_DEBUG(...)
Definition Debug.h:114
APInt bitcastToAPInt() const
Definition APFloat.h:1353
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1540
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition APInt.h:1488
LLVM_ABI APInt byteSwap() const
Definition APInt.cpp:746
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition APInt.h:851
This class is intended to be used as a driving class for all asm writers.
Definition AsmPrinter.h:90
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:199
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 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:19
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition Register.h:78
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
SmallBitVector & set()
bool test(unsigned Idx) const
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:146
@ DW_OP_LLVM_extract_bits_zext
Only used in LLVM metadata.
Definition Dwarf.h:150
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition Dwarf.h:145
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Definition Dwarf.h:143
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
Definition Dwarf.h:148
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
Definition Dwarf.h:144
@ DW_OP_LLVM_extract_bits_sext
Only used in LLVM metadata.
Definition Dwarf.h:149
This is an optimization pass for GlobalISel generic memory operations.
@ Offset
Definition DWP.cpp:477
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:1714
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:207
FunctionAddr VTableAddr uintptr_t uintptr_t Data
Definition InstrProf.h:189
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
Definition MCRegister.h:21
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition Alignment.h:155
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.