Revert r354244 "[DAGCombiner] Eliminate dead stores to stack."
[llvm-complete.git] / lib / CodeGen / AsmPrinter / DwarfExpression.cpp
blob558d33ac0e6bdf4d3d11a802784daf06023767a7
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.
11 //===----------------------------------------------------------------------===//
13 #include "DwarfExpression.h"
14 #include "llvm/ADT/APInt.h"
15 #include "llvm/ADT/SmallBitVector.h"
16 #include "llvm/BinaryFormat/Dwarf.h"
17 #include "llvm/CodeGen/TargetRegisterInfo.h"
18 #include "llvm/IR/DebugInfoMetadata.h"
19 #include "llvm/Support/ErrorHandling.h"
20 #include <algorithm>
21 #include <cassert>
22 #include <cstdint>
24 using namespace llvm;
26 void DwarfExpression::emitConstu(uint64_t Value) {
27 if (Value < 32)
28 emitOp(dwarf::DW_OP_lit0 + Value);
29 else if (Value == std::numeric_limits<uint64_t>::max()) {
30 // Only do this for 64-bit values as the DWARF expression stack uses
31 // target-address-size values.
32 emitOp(dwarf::DW_OP_lit0);
33 emitOp(dwarf::DW_OP_not);
34 } else {
35 emitOp(dwarf::DW_OP_constu);
36 emitUnsigned(Value);
40 void DwarfExpression::addReg(int DwarfReg, const char *Comment) {
41 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
42 assert((LocationKind == Unknown || LocationKind == Register) &&
43 "location description already locked down");
44 LocationKind = Register;
45 if (DwarfReg < 32) {
46 emitOp(dwarf::DW_OP_reg0 + DwarfReg, Comment);
47 } else {
48 emitOp(dwarf::DW_OP_regx, Comment);
49 emitUnsigned(DwarfReg);
53 void DwarfExpression::addBReg(int DwarfReg, int Offset) {
54 assert(DwarfReg >= 0 && "invalid negative dwarf register number");
55 assert(LocationKind != Register && "location description already locked down");
56 if (DwarfReg < 32) {
57 emitOp(dwarf::DW_OP_breg0 + DwarfReg);
58 } else {
59 emitOp(dwarf::DW_OP_bregx);
60 emitUnsigned(DwarfReg);
62 emitSigned(Offset);
65 void DwarfExpression::addFBReg(int Offset) {
66 emitOp(dwarf::DW_OP_fbreg);
67 emitSigned(Offset);
70 void DwarfExpression::addOpPiece(unsigned SizeInBits, unsigned OffsetInBits) {
71 if (!SizeInBits)
72 return;
74 const unsigned SizeOfByte = 8;
75 if (OffsetInBits > 0 || SizeInBits % SizeOfByte) {
76 emitOp(dwarf::DW_OP_bit_piece);
77 emitUnsigned(SizeInBits);
78 emitUnsigned(OffsetInBits);
79 } else {
80 emitOp(dwarf::DW_OP_piece);
81 unsigned ByteSize = SizeInBits / SizeOfByte;
82 emitUnsigned(ByteSize);
84 this->OffsetInBits += SizeInBits;
87 void DwarfExpression::addShr(unsigned ShiftBy) {
88 emitConstu(ShiftBy);
89 emitOp(dwarf::DW_OP_shr);
92 void DwarfExpression::addAnd(unsigned Mask) {
93 emitConstu(Mask);
94 emitOp(dwarf::DW_OP_and);
97 bool DwarfExpression::addMachineReg(const TargetRegisterInfo &TRI,
98 unsigned MachineReg, unsigned MaxSize) {
99 if (!TRI.isPhysicalRegister(MachineReg)) {
100 if (isFrameRegister(TRI, MachineReg)) {
101 DwarfRegs.push_back({-1, 0, nullptr});
102 return true;
104 return false;
107 int Reg = TRI.getDwarfRegNum(MachineReg, false);
109 // If this is a valid register number, emit it.
110 if (Reg >= 0) {
111 DwarfRegs.push_back({Reg, 0, nullptr});
112 return true;
115 // Walk up the super-register chain until we find a valid number.
116 // For example, EAX on x86_64 is a 32-bit fragment of RAX with offset 0.
117 for (MCSuperRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
118 Reg = TRI.getDwarfRegNum(*SR, false);
119 if (Reg >= 0) {
120 unsigned Idx = TRI.getSubRegIndex(*SR, MachineReg);
121 unsigned Size = TRI.getSubRegIdxSize(Idx);
122 unsigned RegOffset = TRI.getSubRegIdxOffset(Idx);
123 DwarfRegs.push_back({Reg, 0, "super-register"});
124 // Use a DW_OP_bit_piece to describe the sub-register.
125 setSubRegisterPiece(Size, RegOffset);
126 return true;
130 // Otherwise, attempt to find a covering set of sub-register numbers.
131 // For example, Q0 on ARM is a composition of D0+D1.
132 unsigned CurPos = 0;
133 // The size of the register in bits.
134 const TargetRegisterClass *RC = TRI.getMinimalPhysRegClass(MachineReg);
135 unsigned RegSize = TRI.getRegSizeInBits(*RC);
136 // Keep track of the bits in the register we already emitted, so we
137 // can avoid emitting redundant aliasing subregs. Because this is
138 // just doing a greedy scan of all subregisters, it is possible that
139 // this doesn't find a combination of subregisters that fully cover
140 // the register (even though one may exist).
141 SmallBitVector Coverage(RegSize, false);
142 for (MCSubRegIterator SR(MachineReg, &TRI); SR.isValid(); ++SR) {
143 unsigned Idx = TRI.getSubRegIndex(MachineReg, *SR);
144 unsigned Size = TRI.getSubRegIdxSize(Idx);
145 unsigned Offset = TRI.getSubRegIdxOffset(Idx);
146 Reg = TRI.getDwarfRegNum(*SR, false);
147 if (Reg < 0)
148 continue;
150 // Intersection between the bits we already emitted and the bits
151 // covered by this subregister.
152 SmallBitVector CurSubReg(RegSize, false);
153 CurSubReg.set(Offset, Offset + Size);
155 // If this sub-register has a DWARF number and we haven't covered
156 // its range, emit a DWARF piece for it.
157 if (CurSubReg.test(Coverage)) {
158 // Emit a piece for any gap in the coverage.
159 if (Offset > CurPos)
160 DwarfRegs.push_back({-1, Offset - CurPos, "no DWARF register encoding"});
161 DwarfRegs.push_back(
162 {Reg, std::min<unsigned>(Size, MaxSize - Offset), "sub-register"});
163 if (Offset >= MaxSize)
164 break;
166 // Mark it as emitted.
167 Coverage.set(Offset, Offset + Size);
168 CurPos = Offset + Size;
171 // Failed to find any DWARF encoding.
172 if (CurPos == 0)
173 return false;
174 // Found a partial or complete DWARF encoding.
175 if (CurPos < RegSize)
176 DwarfRegs.push_back({-1, RegSize - CurPos, "no DWARF register encoding"});
177 return true;
180 void DwarfExpression::addStackValue() {
181 if (DwarfVersion >= 4)
182 emitOp(dwarf::DW_OP_stack_value);
185 void DwarfExpression::addSignedConstant(int64_t Value) {
186 assert(LocationKind == Implicit || LocationKind == Unknown);
187 LocationKind = Implicit;
188 emitOp(dwarf::DW_OP_consts);
189 emitSigned(Value);
192 void DwarfExpression::addUnsignedConstant(uint64_t Value) {
193 assert(LocationKind == Implicit || LocationKind == Unknown);
194 LocationKind = Implicit;
195 emitConstu(Value);
198 void DwarfExpression::addUnsignedConstant(const APInt &Value) {
199 assert(LocationKind == Implicit || LocationKind == Unknown);
200 LocationKind = Implicit;
202 unsigned Size = Value.getBitWidth();
203 const uint64_t *Data = Value.getRawData();
205 // Chop it up into 64-bit pieces, because that's the maximum that
206 // addUnsignedConstant takes.
207 unsigned Offset = 0;
208 while (Offset < Size) {
209 addUnsignedConstant(*Data++);
210 if (Offset == 0 && Size <= 64)
211 break;
212 addStackValue();
213 addOpPiece(std::min(Size - Offset, 64u), Offset);
214 Offset += 64;
218 bool DwarfExpression::addMachineRegExpression(const TargetRegisterInfo &TRI,
219 DIExpressionCursor &ExprCursor,
220 unsigned MachineReg,
221 unsigned FragmentOffsetInBits) {
222 auto Fragment = ExprCursor.getFragmentInfo();
223 if (!addMachineReg(TRI, MachineReg, Fragment ? Fragment->SizeInBits : ~1U)) {
224 LocationKind = Unknown;
225 return false;
228 bool HasComplexExpression = false;
229 auto Op = ExprCursor.peek();
230 if (Op && Op->getOp() != dwarf::DW_OP_LLVM_fragment)
231 HasComplexExpression = true;
233 // If the register can only be described by a complex expression (i.e.,
234 // multiple subregisters) it doesn't safely compose with another complex
235 // expression. For example, it is not possible to apply a DW_OP_deref
236 // operation to multiple DW_OP_pieces.
237 if (HasComplexExpression && DwarfRegs.size() > 1) {
238 DwarfRegs.clear();
239 LocationKind = Unknown;
240 return false;
243 // Handle simple register locations.
244 if (LocationKind != Memory && !HasComplexExpression) {
245 for (auto &Reg : DwarfRegs) {
246 if (Reg.DwarfRegNo >= 0)
247 addReg(Reg.DwarfRegNo, Reg.Comment);
248 addOpPiece(Reg.Size);
250 DwarfRegs.clear();
251 return true;
254 // Don't emit locations that cannot be expressed without DW_OP_stack_value.
255 if (DwarfVersion < 4)
256 if (any_of(ExprCursor, [](DIExpression::ExprOperand Op) -> bool {
257 return Op.getOp() == dwarf::DW_OP_stack_value;
258 })) {
259 DwarfRegs.clear();
260 LocationKind = Unknown;
261 return false;
264 assert(DwarfRegs.size() == 1);
265 auto Reg = DwarfRegs[0];
266 bool FBReg = isFrameRegister(TRI, MachineReg);
267 int SignedOffset = 0;
268 assert(Reg.Size == 0 && "subregister has same size as superregister");
270 // Pattern-match combinations for which more efficient representations exist.
271 // [Reg, DW_OP_plus_uconst, Offset] --> [DW_OP_breg, Offset].
272 if (Op && (Op->getOp() == dwarf::DW_OP_plus_uconst)) {
273 SignedOffset = Op->getArg(0);
274 ExprCursor.take();
277 // [Reg, DW_OP_constu, Offset, DW_OP_plus] --> [DW_OP_breg, Offset]
278 // [Reg, DW_OP_constu, Offset, DW_OP_minus] --> [DW_OP_breg,-Offset]
279 // If Reg is a subregister we need to mask it out before subtracting.
280 if (Op && Op->getOp() == dwarf::DW_OP_constu) {
281 auto N = ExprCursor.peekNext();
282 if (N && (N->getOp() == dwarf::DW_OP_plus ||
283 (N->getOp() == dwarf::DW_OP_minus && !SubRegisterSizeInBits))) {
284 int Offset = Op->getArg(0);
285 SignedOffset = (N->getOp() == dwarf::DW_OP_minus) ? -Offset : Offset;
286 ExprCursor.consume(2);
290 if (FBReg)
291 addFBReg(SignedOffset);
292 else
293 addBReg(Reg.DwarfRegNo, SignedOffset);
294 DwarfRegs.clear();
295 return true;
298 /// Assuming a well-formed expression, match "DW_OP_deref* DW_OP_LLVM_fragment?".
299 static bool isMemoryLocation(DIExpressionCursor ExprCursor) {
300 while (ExprCursor) {
301 auto Op = ExprCursor.take();
302 switch (Op->getOp()) {
303 case dwarf::DW_OP_deref:
304 case dwarf::DW_OP_LLVM_fragment:
305 break;
306 default:
307 return false;
310 return true;
313 void DwarfExpression::addExpression(DIExpressionCursor &&ExprCursor,
314 unsigned FragmentOffsetInBits) {
315 // If we need to mask out a subregister, do it now, unless the next
316 // operation would emit an OpPiece anyway.
317 auto N = ExprCursor.peek();
318 if (SubRegisterSizeInBits && N && (N->getOp() != dwarf::DW_OP_LLVM_fragment))
319 maskSubRegister();
321 while (ExprCursor) {
322 auto Op = ExprCursor.take();
323 switch (Op->getOp()) {
324 case dwarf::DW_OP_LLVM_fragment: {
325 unsigned SizeInBits = Op->getArg(1);
326 unsigned FragmentOffset = Op->getArg(0);
327 // The fragment offset must have already been adjusted by emitting an
328 // empty DW_OP_piece / DW_OP_bit_piece before we emitted the base
329 // location.
330 assert(OffsetInBits >= FragmentOffset && "fragment offset not added?");
332 // If addMachineReg already emitted DW_OP_piece operations to represent
333 // a super-register by splicing together sub-registers, subtract the size
334 // of the pieces that was already emitted.
335 SizeInBits -= OffsetInBits - FragmentOffset;
337 // If addMachineReg requested a DW_OP_bit_piece to stencil out a
338 // sub-register that is smaller than the current fragment's size, use it.
339 if (SubRegisterSizeInBits)
340 SizeInBits = std::min<unsigned>(SizeInBits, SubRegisterSizeInBits);
342 // Emit a DW_OP_stack_value for implicit location descriptions.
343 if (LocationKind == Implicit)
344 addStackValue();
346 // Emit the DW_OP_piece.
347 addOpPiece(SizeInBits, SubRegisterOffsetInBits);
348 setSubRegisterPiece(0, 0);
349 // Reset the location description kind.
350 LocationKind = Unknown;
351 return;
353 case dwarf::DW_OP_plus_uconst:
354 assert(LocationKind != Register);
355 emitOp(dwarf::DW_OP_plus_uconst);
356 emitUnsigned(Op->getArg(0));
357 break;
358 case dwarf::DW_OP_plus:
359 case dwarf::DW_OP_minus:
360 case dwarf::DW_OP_mul:
361 case dwarf::DW_OP_div:
362 case dwarf::DW_OP_mod:
363 case dwarf::DW_OP_or:
364 case dwarf::DW_OP_and:
365 case dwarf::DW_OP_xor:
366 case dwarf::DW_OP_shl:
367 case dwarf::DW_OP_shr:
368 case dwarf::DW_OP_shra:
369 case dwarf::DW_OP_lit0:
370 case dwarf::DW_OP_not:
371 case dwarf::DW_OP_dup:
372 emitOp(Op->getOp());
373 break;
374 case dwarf::DW_OP_deref:
375 assert(LocationKind != Register);
376 if (LocationKind != Memory && ::isMemoryLocation(ExprCursor))
377 // Turning this into a memory location description makes the deref
378 // implicit.
379 LocationKind = Memory;
380 else
381 emitOp(dwarf::DW_OP_deref);
382 break;
383 case dwarf::DW_OP_constu:
384 assert(LocationKind != Register);
385 emitConstu(Op->getArg(0));
386 break;
387 case dwarf::DW_OP_stack_value:
388 LocationKind = Implicit;
389 break;
390 case dwarf::DW_OP_swap:
391 assert(LocationKind != Register);
392 emitOp(dwarf::DW_OP_swap);
393 break;
394 case dwarf::DW_OP_xderef:
395 assert(LocationKind != Register);
396 emitOp(dwarf::DW_OP_xderef);
397 break;
398 default:
399 llvm_unreachable("unhandled opcode found in expression");
403 if (LocationKind == Implicit)
404 // Turn this into an implicit location description.
405 addStackValue();
408 /// add masking operations to stencil out a subregister.
409 void DwarfExpression::maskSubRegister() {
410 assert(SubRegisterSizeInBits && "no subregister was registered");
411 if (SubRegisterOffsetInBits > 0)
412 addShr(SubRegisterOffsetInBits);
413 uint64_t Mask = (1ULL << (uint64_t)SubRegisterSizeInBits) - 1ULL;
414 addAnd(Mask);
417 void DwarfExpression::finalize() {
418 assert(DwarfRegs.size() == 0 && "dwarf registers not emitted");
419 // Emit any outstanding DW_OP_piece operations to mask out subregisters.
420 if (SubRegisterSizeInBits == 0)
421 return;
422 // Don't emit a DW_OP_piece for a subregister at offset 0.
423 if (SubRegisterOffsetInBits == 0)
424 return;
425 addOpPiece(SubRegisterSizeInBits, SubRegisterOffsetInBits);
428 void DwarfExpression::addFragmentOffset(const DIExpression *Expr) {
429 if (!Expr || !Expr->isFragment())
430 return;
432 uint64_t FragmentOffset = Expr->getFragmentInfo()->OffsetInBits;
433 assert(FragmentOffset >= OffsetInBits &&
434 "overlapping or duplicate fragments");
435 if (FragmentOffset > OffsetInBits)
436 addOpPiece(FragmentOffset - OffsetInBits);
437 OffsetInBits = FragmentOffset;