LLVM 19.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"
22#include <algorithm>
23
24using namespace llvm;
25
26#define DEBUG_TYPE "dwarfdebug"
27
29 if (Value < 32)
30 emitOp(dwarf::DW_OP_lit0 + Value);
31 else if (Value == std::numeric_limits<uint64_t>::max()) {
32 // Only do this for 64-bit values as the DWARF expression stack uses
33 // target-address-size values.
34 emitOp(dwarf::DW_OP_lit0);
35 emitOp(dwarf::DW_OP_not);
36 } else {
37 emitOp(dwarf::DW_OP_constu);
39 }
40}
41
42void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
43 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
45 "location description already locked down");
47 if (DwarfReg < 32) {
48 emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
49 } else {
50 emitOp(dwarf::DW_OP_regx, Comment);
51 emitUnsigned(DwarfReg);
52 }
53}
54
55void DwarfExpression::addBReg(int DwarfReg, int Offset) {
56 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
57 assert(!isRegisterLocation() && "location description already locked down");
58 if (DwarfReg < 32) {
59 emitOp(dwarf::DW_OP_breg0 + DwarfReg);
60 } else {
61 emitOp(dwarf::DW_OP_bregx);
62 emitUnsigned(DwarfReg);
63 }
65}
66
68 emitOp(dwarf::DW_OP_fbreg);
70}
71
72void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
73 if (!SizeInBits)
74 return;
75
76 const unsigned SizeOfByte = 8;
77 if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
78 emitOp(dwarf::DW_OP_bit_piece);
79 emitUnsigned(SizeInBits);
81 } else {
82 emitOp(dwarf::DW_OP_piece);
83 unsigned ByteSize = SizeInBits / SizeOfByte;
84 emitUnsigned(ByteSize);
85 }
86 this->OffsetInBits += SizeInBits;
87}
88
89void DwarfExpression::addShr(unsigned ShiftBy) {
90 emitConstu(ShiftBy);
91 emitOp(dwarf::DW_OP_shr);
92}
93
94void DwarfExpression::addAnd(unsigned Mask) {
95 emitConstu(Mask);
96 emitOp(dwarf::DW_OP_and);
97}
98
100 llvm::Register MachineReg,
101 unsigned MaxSize) {
102 if (!MachineReg.isPhysical()) {
103 if (isFrameRegister(TRI, MachineReg)) {
104 DwarfRegs.push_back(Register::createRegister(-1, nullptr));
105 return true;
106 }
107 return false;
108 }
109
110 int Reg = TRI.getDwarfRegNum(MachineReg, false);
111
112 // If this is a valid register number, emit it.
113 if (Reg >= 0) {
114 DwarfRegs.push_back(Register::createRegister(Reg, nullptr));
115 return true;
116 }
117
118 // Walk up the super-register chain until we find a valid number.
119 // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
120 for (MCPhysReg SR : TRI.superregs(MachineReg)) {
121 Reg = TRI.getDwarfRegNum(SR, false);
122 if (Reg >= 0) {
123 unsigned Idx = TRI.getSubRegIndex(SR, MachineReg);
124 unsigned Size = TRI.getSubRegIdxSize(Idx);
125 unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
126 DwarfRegs.push_back(Register::createRegister(Reg, "super-register"));
127 // Use a DW_OP_bit_piece to describe the sub-register.
128 setSubRegisterPiece(Size, RegOffset);
129 return true;
130 }
131 }
132
133 // Otherwise, attempt to find a covering set of sub-register numbers.
134 // For example, Q0 on ARM is a composition of D0+D1.
135 unsigned CurPos = 0;
136 // The size of the register in bits.
137 const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
138 unsigned RegSize = TRI.getRegSizeInBits(*RC);
139 // Keep track of the bits in the register we already emitted, so we
140 // can avoid emitting redundant aliasing subregs. Because this is
141 // just doing a greedy scan of all subregisters, it is possible that
142 // this doesn't find a combination of subregisters that fully cover
143 // the register (even though one may exist).
144 SmallBitVector Coverage(RegSize, false);
145 for (MCPhysReg SR : TRI.subregs(MachineReg)) {
146 unsigned Idx = TRI.getSubRegIndex(MachineReg, SR);
147 unsigned Size = TRI.getSubRegIdxSize(Idx);
148 unsigned Offset = TRI.getSubRegIdxOffset(Idx);
149 Reg = TRI.getDwarfRegNum(SR, false);
150 if (Reg < 0)
151 continue;
152
153 // Used to build the intersection between the bits we already
154 // emitted and the bits covered by this subregister.
155 SmallBitVector CurSubReg(RegSize, false);
156 CurSubReg.set(Offset, Offset + Size);
157
158 // If this sub-register has a DWARF number and we haven't covered
159 // its range, and its range covers the value, emit a DWARF piece for it.
160 if (Offset < MaxSize && CurSubReg.test(Coverage)) {
161 // Emit a piece for any gap in the coverage.
162 if (Offset > CurPos)
164 -1, Offset - CurPos, "no DWARF register encoding"));
165 if (Offset == 0 && Size >= MaxSize)
166 DwarfRegs.push_back(Register::createRegister(Reg, "sub-register"));
167 else
169 Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"));
170 }
171 // Mark it as emitted.
172 Coverage.set(Offset, Offset + Size);
173 CurPos = Offset + Size;
174 }
175 // Failed to find any DWARF encoding.
176 if (CurPos == 0)
177 return false;
178 // Found a partial or complete DWARF encoding.
179 if (CurPos < RegSize)
181 -1, RegSize - CurPos, "no DWARF register encoding"));
182 return true;
183}
184
186 if (DwarfVersion >= 4)
187 emitOp(dwarf::DW_OP_stack_value);
188}
189
193 emitOp(dwarf::DW_OP_consts);
195}
196
201}
202
206
207 unsigned Size = Value.getBitWidth();
208 const uint64_t *Data = Value.getRawData();
209
210 // Chop it up into 64-bit pieces, because that's the maximum that
211 // addUnsignedConstant takes.
212 unsigned Offset = 0;
213 while (Offset < Size) {
215 if (Offset == 0 && Size <= 64)
216 break;
218 addOpPiece(std::min(Size - Offset, 64u), Offset);
219 Offset += 64;
220 }
221}
222
225 APInt API = APF.bitcastToAPInt();
226 int NumBytes = API.getBitWidth() / 8;
227 if (NumBytes == 4 /*float*/ || NumBytes == 8 /*double*/) {
228 // FIXME: Add support for `long double`.
229 emitOp(dwarf::DW_OP_implicit_value);
230 emitUnsigned(NumBytes /*Size of the block in bytes*/);
231
232 // The loop below is emitting the value starting at least significant byte,
233 // so we need to perform a byte-swap to get the byte order correct in case
234 // of a big-endian target.
235 if (AP.getDataLayout().isBigEndian())
236 API = API.byteSwap();
237
238 for (int i = 0; i < NumBytes; ++i) {
239 emitData1(API.getZExtValue() & 0xFF);
240 API = API.lshr(8);
241 }
242
243 return;
244 }
246 dbgs() << "Skipped DW_OP_implicit_value creation for ConstantFP of size: "
247 << API.getBitWidth() << " bits\n");
248}
249
251 DIExpressionCursor &ExprCursor,
252 llvm::Register MachineReg,
253 unsigned FragmentOffsetInBits) {
254 auto Fragment = ExprCursor.getFragmentInfo();
255 if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
257 return false;
258 }
259
260 bool HasComplexExpression = false;
261 auto Op = ExprCursor.peek();
262 if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
263 HasComplexExpression = true;
264
265 // If the register can only be described by a complex expression (i.e.,
266 // multiple subregisters) it doesn't safely compose with another complex
267 // expression. For example, it is not possible to apply a DW_OP_deref
268 // operation to multiple DW_OP_pieces, since composite location descriptions
269 // do not push anything on the DWARF stack.
270 //
271 // DW_OP_entry_value operations can only hold a DWARF expression or a
272 // register location description, so we can't emit a single entry value
273 // covering a composite location description. In the future we may want to
274 // emit entry value operations for each register location in the composite
275 // location, but until that is supported do not emit anything.
276 if ((HasComplexExpression || IsEmittingEntryValue) && DwarfRegs.size() > 1) {
279 DwarfRegs.clear();
281 return false;
282 }
283
284 // Handle simple register locations. If we are supposed to emit
285 // a call site parameter expression and if that expression is just a register
286 // location, emit it with addBReg and offset 0, because we should emit a DWARF
287 // expression representing a value, rather than a location.
288 if ((!isParameterValue() && !isMemoryLocation() && !HasComplexExpression) ||
289 isEntryValue()) {
290 auto FragmentInfo = ExprCursor.getFragmentInfo();
291 unsigned RegSize = 0;
292 for (auto &Reg : DwarfRegs) {
293 RegSize += Reg.SubRegSize;
294 if (Reg.DwarfRegNo >= 0)
295 addReg(Reg.DwarfRegNo, Reg.Comment);
296 if (FragmentInfo)
297 if (RegSize > FragmentInfo->SizeInBits)
298 // If the register is larger than the current fragment stop
299 // once the fragment is covered.
300 break;
301 addOpPiece(Reg.SubRegSize);
302 }
303
304 if (isEntryValue()) {
306
307 if (!isIndirect() && !isParameterValue() && !HasComplexExpression &&
308 DwarfVersion >= 4)
309 emitOp(dwarf::DW_OP_stack_value);
310 }
311
312 DwarfRegs.clear();
313 // If we need to mask out a subregister, do it now, unless the next
314 // operation would emit an OpPiece anyway.
315 auto NextOp = ExprCursor.peek();
316 if (SubRegisterSizeInBits && NextOp &&
317 (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
319 return true;
320 }
321
322 // Don't emit locations that cannot be expressed without DW_OP_stack_value.
323 if (DwarfVersion < 4)
324 if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
325 return Op.getOp() == dwarf::DW_OP_stack_value;
326 })) {
327 DwarfRegs.clear();
329 return false;
330 }
331
332 // TODO: We should not give up here but the following code needs to be changed
333 // to deal with multiple (sub)registers first.
334 if (DwarfRegs.size() > 1) {
335 LLVM_DEBUG(dbgs() << "TODO: giving up on debug information due to "
336 "multi-register usage.\n");
337 DwarfRegs.clear();
339 return false;
340 }
341
342 auto Reg = DwarfRegs[0];
343 bool FBReg = isFrameRegister(TRI, MachineReg);
344 int SignedOffset = 0;
345 assert(!Reg.isSubRegister() && "full register expected");
346
347 // Pattern-match combinations for which more efficient representations exist.
348 // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
349 if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
350 uint64_t Offset = Op->getArg(0);
351 uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
352 if (Offset <= IntMax) {
353 SignedOffset = Offset;
354 ExprCursor.take();
355 }
356 }
357
358 // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
359 // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
360 // If Reg is a subregister we need to mask it out before subtracting.
361 if (Op && Op->getOp() == dwarf::DW_OP_constu) {
362 uint64_t Offset = Op->getArg(0);
363 uint64_t IntMax = static_cast<uint64_t>(std::numeric_limits<int>::max());
364 auto N = ExprCursor.peekNext();
365 if (N && N->getOp() == dwarf::DW_OP_plus && Offset <= IntMax) {
366 SignedOffset = Offset;
367 ExprCursor.consume(2);
368 } else if (N && N->getOp() == dwarf::DW_OP_minus &&
369 !SubRegisterSizeInBits && Offset <= IntMax + 1) {
370 SignedOffset = -static_cast<int64_t>(Offset);
371 ExprCursor.consume(2);
372 }
373 }
374
375 if (FBReg)
376 addFBReg(SignedOffset);
377 else
378 addBReg(Reg.DwarfRegNo, SignedOffset);
379 DwarfRegs.clear();
380
381 // If we need to mask out a subregister, do it now, unless the next
382 // operation would emit an OpPiece anyway.
383 auto NextOp = ExprCursor.peek();
384 if (SubRegisterSizeInBits && NextOp &&
385 (NextOp->getOp() != dwarf::DW_OP_LLVM_fragment))
387
388 return true;
389}
390
393 if (Loc.isIndirect())
395}
396
398 const DIExpression *DIExpr) {
399 if (Loc.isIndirect())
401
402 if (DIExpr->isEntryValue())
404}
405
407 DIExpressionCursor &ExprCursor) {
408 auto Op = ExprCursor.take();
409 (void)Op;
411 assert(!IsEmittingEntryValue && "Already emitting entry value?");
412 assert(Op->getArg(0) == 1 &&
413 "Can currently only emit entry values covering a single operation");
414
420}
421
423 assert(IsEmittingEntryValue && "Entry value not open?");
425
426 emitOp(CU.getDwarf5OrGNULocationAtom(dwarf::DW_OP_entry_value));
427
428 // Emit the entry value's size operand.
429 unsigned Size = getTemporaryBufferSize();
431
432 // Emit the entry value's DWARF block operand.
434
435 LocationFlags &= ~EntryValue;
437 IsEmittingEntryValue = false;
438}
439
441 assert(IsEmittingEntryValue && "Entry value not open?");
443
444 // The temporary buffer can't be emptied, so for now just assert that nothing
445 // has been emitted to it.
447 "Began emitting entry value block before cancelling entry value");
448
450 IsEmittingEntryValue = false;
451}
452
453unsigned DwarfExpression::getOrCreateBaseType(unsigned BitSize,
454 dwarf::TypeKind Encoding) {
455 // Reuse the base_type if we already have one in this CU otherwise we
456 // create a new one.
457 unsigned I = 0, E = CU.ExprRefedBaseTypes.size();
458 for (; I != E; ++I)
459 if (CU.ExprRefedBaseTypes[I].BitSize == BitSize &&
460 CU.ExprRefedBaseTypes[I].Encoding == Encoding)
461 break;
462
463 if (I == E)
464 CU.ExprRefedBaseTypes.emplace_back(BitSize, Encoding);
465 return I;
466}
467
468/// Assuming a well-formed expression, match "DW_OP_deref*
469/// DW_OP_LLVM_fragment?".
470static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
471 while (ExprCursor) {
472 auto Op = ExprCursor.take();
473 switch (Op->getOp()) {
474 case dwarf::DW_OP_deref:
476 break;
477 default:
478 return false;
479 }
480 }
481 return true;
482}
483
485 addExpression(std::move(ExprCursor),
486 [](unsigned Idx, DIExpressionCursor &Cursor) -> bool {
487 llvm_unreachable("unhandled opcode found in expression");
488 });
489}
490
492 DIExpressionCursor &&ExprCursor,
493 llvm::function_ref<bool(unsigned, DIExpressionCursor &)> InsertArg) {
494 // Entry values can currently only cover the initial register location,
495 // and not any other parts of the following DWARF expression.
496 assert(!IsEmittingEntryValue && "Can't emit entry value around expression");
497
498 std::optional<DIExpression::ExprOperand> PrevConvertOp;
499
500 while (ExprCursor) {
501 auto Op = ExprCursor.take();
502 uint64_t OpNum = Op->getOp();
503
504 if (OpNum >= dwarf::DW_OP_reg0 && OpNum <= dwarf::DW_OP_reg31) {
505 emitOp(OpNum);
506 continue;
507 } else if (OpNum >= dwarf::DW_OP_breg0 && OpNum <= dwarf::DW_OP_breg31) {
508 addBReg(OpNum - dwarf::DW_OP_breg0, Op->getArg(0));
509 continue;
510 }
511
512 switch (OpNum) {
514 if (!InsertArg(Op->getArg(0), ExprCursor)) {
516 return false;
517 }
518 break;
520 unsigned SizeInBits = Op->getArg(1);
521 unsigned FragmentOffset = Op->getArg(0);
522 // The fragment offset must have already been adjusted by emitting an
523 // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
524 // location.
525 assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
526 assert(SizeInBits >= OffsetInBits - FragmentOffset && "size underflow");
527
528 // If addMachineReg already emitted DW_OP_piece operations to represent
529 // a super-register by splicing together sub-registers, subtract the size
530 // of the pieces that was already emitted.
531 SizeInBits -= OffsetInBits - FragmentOffset;
532
533 // If addMachineReg requested a DW_OP_bit_piece to stencil out a
534 // sub-register that is smaller than the current fragment's size, use it.
536 SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
537
538 // Emit a DW_OP_stack_value for implicit location descriptions.
539 if (isImplicitLocation())
541
542 // Emit the DW_OP_piece.
545 // Reset the location description kind.
547 return true;
548 }
549 case dwarf::DW_OP_plus_uconst:
551 emitOp(dwarf::DW_OP_plus_uconst);
552 emitUnsigned(Op->getArg(0));
553 break;
554 case dwarf::DW_OP_plus:
555 case dwarf::DW_OP_minus:
556 case dwarf::DW_OP_mul:
557 case dwarf::DW_OP_div:
558 case dwarf::DW_OP_mod:
559 case dwarf::DW_OP_or:
560 case dwarf::DW_OP_and:
561 case dwarf::DW_OP_xor:
562 case dwarf::DW_OP_shl:
563 case dwarf::DW_OP_shr:
564 case dwarf::DW_OP_shra:
565 case dwarf::DW_OP_lit0:
566 case dwarf::DW_OP_not:
567 case dwarf::DW_OP_dup:
568 case dwarf::DW_OP_push_object_address:
569 case dwarf::DW_OP_over:
570 case dwarf::DW_OP_eq:
571 case dwarf::DW_OP_ne:
572 case dwarf::DW_OP_gt:
573 case dwarf::DW_OP_ge:
574 case dwarf::DW_OP_lt:
575 case dwarf::DW_OP_le:
576 emitOp(OpNum);
577 break;
578 case dwarf::DW_OP_deref:
580 if (!isMemoryLocation() && ::isMemoryLocation(ExprCursor))
581 // Turning this into a memory location description makes the deref
582 // implicit.
584 else
585 emitOp(dwarf::DW_OP_deref);
586 break;
587 case dwarf::DW_OP_constu:
589 emitConstu(Op->getArg(0));
590 break;
591 case dwarf::DW_OP_consts:
593 emitOp(dwarf::DW_OP_consts);
594 emitSigned(Op->getArg(0));
595 break;
597 unsigned BitSize = Op->getArg(0);
598 dwarf::TypeKind Encoding = static_cast<dwarf::TypeKind>(Op->getArg(1));
599 if (DwarfVersion >= 5 && CU.getDwarfDebug().useOpConvert()) {
600 emitOp(dwarf::DW_OP_convert);
601 // If targeting a location-list; simply emit the index into the raw
602 // byte stream as ULEB128, DwarfDebug::emitDebugLocEntry has been
603 // fitted with means to extract it later.
604 // If targeting a inlined DW_AT_location; insert a DIEBaseTypeRef
605 // (containing the index and a resolve mechanism during emit) into the
606 // DIE value list.
607 emitBaseTypeRef(getOrCreateBaseType(BitSize, Encoding));
608 } else {
609 if (PrevConvertOp && PrevConvertOp->getArg(0) < BitSize) {
610 if (Encoding == dwarf::DW_ATE_signed)
611 emitLegacySExt(PrevConvertOp->getArg(0));
612 else if (Encoding == dwarf::DW_ATE_unsigned)
613 emitLegacyZExt(PrevConvertOp->getArg(0));
614 PrevConvertOp = std::nullopt;
615 } else {
616 PrevConvertOp = Op;
617 }
618 }
619 break;
620 }
621 case dwarf::DW_OP_stack_value:
623 break;
624 case dwarf::DW_OP_swap:
626 emitOp(dwarf::DW_OP_swap);
627 break;
628 case dwarf::DW_OP_xderef:
630 emitOp(dwarf::DW_OP_xderef);
631 break;
632 case dwarf::DW_OP_deref_size:
633 emitOp(dwarf::DW_OP_deref_size);
634 emitData1(Op->getArg(0));
635 break;
637 TagOffset = Op->getArg(0);
638 break;
639 case dwarf::DW_OP_regx:
640 emitOp(dwarf::DW_OP_regx);
641 emitUnsigned(Op->getArg(0));
642 break;
643 case dwarf::DW_OP_bregx:
644 emitOp(dwarf::DW_OP_bregx);
645 emitUnsigned(Op->getArg(0));
646 emitSigned(Op->getArg(1));
647 break;
648 default:
649 llvm_unreachable("unhandled opcode found in expression");
650 }
651 }
652
654 // Turn this into an implicit location description.
656
657 return true;
658}
659
660/// add masking operations to stencil out a subregister.
662 assert(SubRegisterSizeInBits && "no subregister was registered");
665 uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
666 addAnd(Mask);
667}
668
670 assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
671 // Emit any outstanding DW_OP_piece operations to mask out subregisters.
672 if (SubRegisterSizeInBits == 0)
673 return;
674 // Don't emit a DW_OP_piece for a subregister at offset 0.
676 return;
678}
679
681 if (!Expr || !Expr->isFragment())
682 return;
683
684 uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
685 assert(FragmentOffset >= OffsetInBits &&
686 "overlapping or duplicate fragments");
687 if (FragmentOffset > OffsetInBits)
688 addOpPiece(FragmentOffset - OffsetInBits);
689 OffsetInBits = FragmentOffset;
690}
691
692void DwarfExpression::emitLegacySExt(unsigned FromBits) {
693 // (((X >> (FromBits - 1)) * (~0)) << FromBits) | X
694 emitOp(dwarf::DW_OP_dup);
695 emitOp(dwarf::DW_OP_constu);
696 emitUnsigned(FromBits - 1);
697 emitOp(dwarf::DW_OP_shr);
698 emitOp(dwarf::DW_OP_lit0);
699 emitOp(dwarf::DW_OP_not);
700 emitOp(dwarf::DW_OP_mul);
701 emitOp(dwarf::DW_OP_constu);
702 emitUnsigned(FromBits);
703 emitOp(dwarf::DW_OP_shl);
704 emitOp(dwarf::DW_OP_or);
705}
706
707void DwarfExpression::emitLegacyZExt(unsigned FromBits) {
708 // Heuristic to decide the most efficient encoding.
709 // A ULEB can encode 7 1-bits per byte.
710 if (FromBits / 7 < 1+1+1+1+1) {
711 // (X & (1 << FromBits - 1))
712 emitOp(dwarf::DW_OP_constu);
713 emitUnsigned((1ULL << FromBits) - 1);
714 } else {
715 // Note that the DWARF 4 stack consists of pointer-sized elements,
716 // so technically it doesn't make sense to shift left more than 64
717 // bits. We leave that for the consumer to decide though. LLDB for
718 // example uses APInt for the stack elements and can still deal
719 // with this.
720 emitOp(dwarf::DW_OP_lit1);
721 emitOp(dwarf::DW_OP_constu);
722 emitUnsigned(FromBits);
723 emitOp(dwarf::DW_OP_shl);
724 emitOp(dwarf::DW_OP_lit1);
725 emitOp(dwarf::DW_OP_minus);
726 }
727 emitOp(dwarf::DW_OP_and);
728}
729
731 emitOp(dwarf::DW_OP_WASM_location);
732 emitUnsigned(Index == 4/*TI_LOCAL_INDIRECT*/ ? 0/*TI_LOCAL*/ : Index);
734 if (Index == 4 /*TI_LOCAL_INDIRECT*/) {
737 } else {
740 }
741}
unsigned RegSize
This file implements a class to represent arbitrary precision integral constant values and operations...
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
#define LLVM_DEBUG(X)
Definition: Debug.h:101
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.
uint64_t Size
#define I(x, y, z)
Definition: MD5.cpp:58
unsigned const TargetRegisterInfo * TRI
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the SmallBitVector class.
APInt bitcastToAPInt() const
Definition: APFloat.h:1210
Class for arbitrary precision integers.
Definition: APInt.h:76
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1491
unsigned getBitWidth() const
Return the number of bits in the APInt.
Definition: APInt.h:1439
APInt byteSwap() const
Definition: APInt.cpp:715
APInt lshr(unsigned shiftAmt) const
Logical right-shift function.
Definition: APInt.h:829
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:84
const DataLayout & getDataLayout() const
Return information about data layout.
Definition: AsmPrinter.cpp:402
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.
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 std::optional< FragmentInfo > getFragmentInfo(expr_op_iterator Start, expr_op_iterator End)
Retrieve the details of this fragment expression.
This class represents an Operation in the Expression.
bool isBigEndian() const
Definition: DataLayout.h:239
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.
void addReg(int DwarfReg, const char *Comment=nullptr)
Emit a DW_OP_reg operation.
std::optional< uint8_t > TagOffset
bool isImplicitLocation() const
virtual void emitUnsigned(uint64_t Value)=0
Emit a raw unsigned value.
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...
void addBReg(int DwarfReg, int Offset)
Emit a DW_OP_breg operation.
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(int 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 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.
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:95
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:74
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:144
@ DW_OP_LLVM_tag_offset
Only used in LLVM metadata.
Definition: Dwarf.h:143
@ DW_OP_LLVM_fragment
Only used in LLVM metadata.
Definition: Dwarf.h:141
@ DW_OP_LLVM_arg
Only used in LLVM metadata.
Definition: Dwarf.h:146
@ DW_OP_LLVM_convert
Only used in LLVM metadata.
Definition: Dwarf.h:142
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
@ Offset
Definition: DWP.cpp:456
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:1738
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
DWARFExpression::Operation Op
#define N
Holds information about all subregisters comprising a register location.
static Register createRegister(int RegNo, const char *Comment)
Create a full register, no extra DW_OP_piece operators necessary.
static Register createSubRegister(int RegNo, unsigned SizeInBits, const char *Comment)
Create a subregister that needs a DW_OP_piece operator with SizeInBits.