LLVM  17.0.0git
StackMaps.cpp
Go to the documentation of this file.
1 //===- StackMaps.cpp ------------------------------------------------------===//
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 
10 #include "llvm/ADT/DenseMapInfo.h"
11 #include "llvm/ADT/STLExtras.h"
12 #include "llvm/ADT/Twine.h"
21 #include "llvm/IR/DataLayout.h"
22 #include "llvm/MC/MCContext.h"
23 #include "llvm/MC/MCExpr.h"
25 #include "llvm/MC/MCRegisterInfo.h"
26 #include "llvm/MC/MCStreamer.h"
28 #include "llvm/Support/Debug.h"
32 #include <algorithm>
33 #include <cassert>
34 #include <cstdint>
35 #include <iterator>
36 #include <utility>
37 
38 using namespace llvm;
39 
40 #define DEBUG_TYPE "stackmaps"
41 
43  "stackmap-version", cl::init(3), cl::Hidden,
44  cl::desc("Specify the stackmap encoding version (default = 3)"));
45 
46 const char *StackMaps::WSMP = "Stack Maps: ";
47 
48 static uint64_t getConstMetaVal(const MachineInstr &MI, unsigned Idx) {
49  assert(MI.getOperand(Idx).isImm() &&
50  MI.getOperand(Idx).getImm() == StackMaps::ConstantOp);
51  const auto &MO = MI.getOperand(Idx + 1);
52  assert(MO.isImm());
53  return MO.getImm();
54 }
55 
57  : MI(MI) {
58  assert(getVarIdx() <= MI->getNumOperands() &&
59  "invalid stackmap definition");
60 }
61 
63  : MI(MI), HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
64  !MI->getOperand(0).isImplicit()) {
65 #ifndef NDEBUG
66  unsigned CheckStartIdx = 0, e = MI->getNumOperands();
67  while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() &&
68  MI->getOperand(CheckStartIdx).isDef() &&
69  !MI->getOperand(CheckStartIdx).isImplicit())
70  ++CheckStartIdx;
71 
72  assert(getMetaIdx() == CheckStartIdx &&
73  "Unexpected additional definition in Patchpoint intrinsic.");
74 #endif
75 }
76 
77 unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const {
78  if (!StartIdx)
79  StartIdx = getVarIdx();
80 
81  // Find the next scratch register (implicit def and early clobber)
82  unsigned ScratchIdx = StartIdx, e = MI->getNumOperands();
83  while (ScratchIdx < e &&
84  !(MI->getOperand(ScratchIdx).isReg() &&
85  MI->getOperand(ScratchIdx).isDef() &&
86  MI->getOperand(ScratchIdx).isImplicit() &&
87  MI->getOperand(ScratchIdx).isEarlyClobber()))
88  ++ScratchIdx;
89 
90  assert(ScratchIdx != e && "No scratch register available");
91  return ScratchIdx;
92 }
93 
95  // Take index of num of allocas and skip all allocas records.
96  unsigned CurIdx = getNumAllocaIdx();
97  unsigned NumAllocas = getConstMetaVal(*MI, CurIdx - 1);
98  CurIdx++;
99  while (NumAllocas--)
100  CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
101  return CurIdx + 1; // skip <StackMaps::ConstantOp>
102 }
103 
105  // Take index of num of gc ptrs and skip all gc ptr records.
106  unsigned CurIdx = getNumGCPtrIdx();
107  unsigned NumGCPtrs = getConstMetaVal(*MI, CurIdx - 1);
108  CurIdx++;
109  while (NumGCPtrs--)
110  CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
111  return CurIdx + 1; // skip <StackMaps::ConstantOp>
112 }
113 
115  // Take index of num of deopt args and skip all deopt records.
116  unsigned CurIdx = getNumDeoptArgsIdx();
117  unsigned NumDeoptArgs = getConstMetaVal(*MI, CurIdx - 1);
118  CurIdx++;
119  while (NumDeoptArgs--) {
120  CurIdx = StackMaps::getNextMetaArgIdx(MI, CurIdx);
121  }
122  return CurIdx + 1; // skip <StackMaps::ConstantOp>
123 }
124 
126  unsigned NumGCPtrsIdx = getNumGCPtrIdx();
127  unsigned NumGCPtrs = getConstMetaVal(*MI, NumGCPtrsIdx - 1);
128  if (NumGCPtrs == 0)
129  return -1;
130  ++NumGCPtrsIdx; // skip <num gc ptrs>
131  assert(NumGCPtrsIdx < MI->getNumOperands());
132  return (int)NumGCPtrsIdx;
133 }
134 
136  SmallVectorImpl<std::pair<unsigned, unsigned>> &GCMap) {
137  unsigned CurIdx = getNumGcMapEntriesIdx();
138  unsigned GCMapSize = getConstMetaVal(*MI, CurIdx - 1);
139  CurIdx++;
140  for (unsigned N = 0; N < GCMapSize; ++N) {
141  unsigned B = MI->getOperand(CurIdx++).getImm();
142  unsigned D = MI->getOperand(CurIdx++).getImm();
143  GCMap.push_back(std::make_pair(B, D));
144  }
145 
146  return GCMapSize;
147 }
148 
150  unsigned FoldableAreaStart = getVarIdx();
151  for (const MachineOperand &MO : MI->uses()) {
152  if (MI->getOperandNo(&MO) >= FoldableAreaStart)
153  break;
154  if (MO.isReg() && MO.getReg() == Reg)
155  return false;
156  }
157  return true;
158 }
159 
161  if (MI->getOpcode() != TargetOpcode::STATEPOINT)
162  return false;
163  return StatepointOpers(MI).isFoldableReg(Reg);
164 }
165 
167  if (StackMapVersion != 3)
168  llvm_unreachable("Unsupported stackmap version!");
169 }
170 
171 unsigned StackMaps::getNextMetaArgIdx(const MachineInstr *MI, unsigned CurIdx) {
172  assert(CurIdx < MI->getNumOperands() && "Bad meta arg index");
173  const auto &MO = MI->getOperand(CurIdx);
174  if (MO.isImm()) {
175  switch (MO.getImm()) {
176  default:
177  llvm_unreachable("Unrecognized operand type.");
178  case StackMaps::DirectMemRefOp:
179  CurIdx += 2;
180  break;
181  case StackMaps::IndirectMemRefOp:
182  CurIdx += 3;
183  break;
184  case StackMaps::ConstantOp:
185  ++CurIdx;
186  break;
187  }
188  }
189  ++CurIdx;
190  assert(CurIdx < MI->getNumOperands() && "points past operand list");
191  return CurIdx;
192 }
193 
194 /// Go up the super-register chain until we hit a valid dwarf register number.
195 static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) {
196  int RegNum = TRI->getDwarfRegNum(Reg, false);
197  for (MCSuperRegIterator SR(Reg, TRI); SR.isValid() && RegNum < 0; ++SR)
198  RegNum = TRI->getDwarfRegNum(*SR, false);
199 
200  assert(RegNum >= 0 && "Invalid Dwarf register number.");
201  return (unsigned)RegNum;
202 }
203 
205 StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
206  MachineInstr::const_mop_iterator MOE, LocationVec &Locs,
207  LiveOutVec &LiveOuts) const {
209  if (MOI->isImm()) {
210  switch (MOI->getImm()) {
211  default:
212  llvm_unreachable("Unrecognized operand type.");
213  case StackMaps::DirectMemRefOp: {
214  auto &DL = AP.MF->getDataLayout();
215 
216  unsigned Size = DL.getPointerSizeInBits();
217  assert((Size % 8) == 0 && "Need pointer size in bytes.");
218  Size /= 8;
219  Register Reg = (++MOI)->getReg();
220  int64_t Imm = (++MOI)->getImm();
221  Locs.emplace_back(StackMaps::Location::Direct, Size,
223  break;
224  }
225  case StackMaps::IndirectMemRefOp: {
226  int64_t Size = (++MOI)->getImm();
227  assert(Size > 0 && "Need a valid size for indirect memory locations.");
228  Register Reg = (++MOI)->getReg();
229  int64_t Imm = (++MOI)->getImm();
230  Locs.emplace_back(StackMaps::Location::Indirect, Size,
232  break;
233  }
234  case StackMaps::ConstantOp: {
235  ++MOI;
236  assert(MOI->isImm() && "Expected constant operand.");
237  int64_t Imm = MOI->getImm();
238  Locs.emplace_back(Location::Constant, sizeof(int64_t), 0, Imm);
239  break;
240  }
241  }
242  return ++MOI;
243  }
244 
245  // The physical register number will ultimately be encoded as a DWARF regno.
246  // The stack map also records the size of a spill slot that can hold the
247  // register content. (The runtime can track the actual size of the data type
248  // if it needs to.)
249  if (MOI->isReg()) {
250  // Skip implicit registers (this includes our scratch registers)
251  if (MOI->isImplicit())
252  return ++MOI;
253 
254  if (MOI->isUndef()) {
255  // Record `undef` register as constant. Use same value as ISel uses.
256  Locs.emplace_back(Location::Constant, sizeof(int64_t), 0, 0xFEFEFEFE);
257  return ++MOI;
258  }
259 
260  assert(MOI->getReg().isPhysical() &&
261  "Virtreg operands should have been rewritten before now.");
263  assert(!MOI->getSubReg() && "Physical subreg still around.");
264 
265  unsigned Offset = 0;
266  unsigned DwarfRegNum = getDwarfRegNum(MOI->getReg(), TRI);
267  unsigned LLVMRegNum = *TRI->getLLVMRegNum(DwarfRegNum, false);
268  unsigned SubRegIdx = TRI->getSubRegIndex(LLVMRegNum, MOI->getReg());
269  if (SubRegIdx)
270  Offset = TRI->getSubRegIdxOffset(SubRegIdx);
271 
272  Locs.emplace_back(Location::Register, TRI->getSpillSize(*RC),
273  DwarfRegNum, Offset);
274  return ++MOI;
275  }
276 
277  if (MOI->isRegLiveOut())
278  LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
279 
280  return ++MOI;
281 }
282 
283 void StackMaps::print(raw_ostream &OS) {
284  const TargetRegisterInfo *TRI =
285  AP.MF ? AP.MF->getSubtarget().getRegisterInfo() : nullptr;
286  OS << WSMP << "callsites:\n";
287  for (const auto &CSI : CSInfos) {
288  const LocationVec &CSLocs = CSI.Locations;
289  const LiveOutVec &LiveOuts = CSI.LiveOuts;
290 
291  OS << WSMP << "callsite " << CSI.ID << "\n";
292  OS << WSMP << " has " << CSLocs.size() << " locations\n";
293 
294  unsigned Idx = 0;
295  for (const auto &Loc : CSLocs) {
296  OS << WSMP << "\t\tLoc " << Idx << ": ";
297  switch (Loc.Type) {
299  OS << "<Unprocessed operand>";
300  break;
301  case Location::Register:
302  OS << "Register ";
303  if (TRI)
304  OS << printReg(Loc.Reg, TRI);
305  else
306  OS << Loc.Reg;
307  break;
308  case Location::Direct:
309  OS << "Direct ";
310  if (TRI)
311  OS << printReg(Loc.Reg, TRI);
312  else
313  OS << Loc.Reg;
314  if (Loc.Offset)
315  OS << " + " << Loc.Offset;
316  break;
317  case Location::Indirect:
318  OS << "Indirect ";
319  if (TRI)
320  OS << printReg(Loc.Reg, TRI);
321  else
322  OS << Loc.Reg;
323  OS << "+" << Loc.Offset;
324  break;
325  case Location::Constant:
326  OS << "Constant " << Loc.Offset;
327  break;
329  OS << "Constant Index " << Loc.Offset;
330  break;
331  }
332  OS << "\t[encoding: .byte " << Loc.Type << ", .byte 0"
333  << ", .short " << Loc.Size << ", .short " << Loc.Reg << ", .short 0"
334  << ", .int " << Loc.Offset << "]\n";
335  Idx++;
336  }
337 
338  OS << WSMP << "\thas " << LiveOuts.size() << " live-out registers\n";
339 
340  Idx = 0;
341  for (const auto &LO : LiveOuts) {
342  OS << WSMP << "\t\tLO " << Idx << ": ";
343  if (TRI)
344  OS << printReg(LO.Reg, TRI);
345  else
346  OS << LO.Reg;
347  OS << "\t[encoding: .short " << LO.DwarfRegNum << ", .byte 0, .byte "
348  << LO.Size << "]\n";
349  Idx++;
350  }
351  }
352 }
353 
354 /// Create a live-out register record for the given register Reg.
356 StackMaps::createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const {
357  unsigned DwarfRegNum = getDwarfRegNum(Reg, TRI);
359  return LiveOutReg(Reg, DwarfRegNum, Size);
360 }
361 
362 /// Parse the register live-out mask and return a vector of live-out registers
363 /// that need to be recorded in the stackmap.
365 StackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const {
366  assert(Mask && "No register mask specified");
368  LiveOutVec LiveOuts;
369 
370  // Create a LiveOutReg for each bit that is set in the register mask.
371  for (unsigned Reg = 0, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg)
372  if ((Mask[Reg / 32] >> (Reg % 32)) & 1)
373  LiveOuts.push_back(createLiveOutReg(Reg, TRI));
374 
375  // We don't need to keep track of a register if its super-register is already
376  // in the list. Merge entries that refer to the same dwarf register and use
377  // the maximum size that needs to be spilled.
378 
379  llvm::sort(LiveOuts, [](const LiveOutReg &LHS, const LiveOutReg &RHS) {
380  // Only sort by the dwarf register number.
381  return LHS.DwarfRegNum < RHS.DwarfRegNum;
382  });
383 
384  for (auto I = LiveOuts.begin(), E = LiveOuts.end(); I != E; ++I) {
385  for (auto *II = std::next(I); II != E; ++II) {
386  if (I->DwarfRegNum != II->DwarfRegNum) {
387  // Skip all the now invalid entries.
388  I = --II;
389  break;
390  }
391  I->Size = std::max(I->Size, II->Size);
392  if (TRI->isSuperRegister(I->Reg, II->Reg))
393  I->Reg = II->Reg;
394  II->Reg = 0; // mark for deletion.
395  }
396  }
397 
398  llvm::erase_if(LiveOuts, [](const LiveOutReg &LO) { return LO.Reg == 0; });
399 
400  return LiveOuts;
401 }
402 
403 // See statepoint MI format description in StatepointOpers' class comment
404 // in include/llvm/CodeGen/StackMaps.h
405 void StackMaps::parseStatepointOpers(const MachineInstr &MI,
408  LocationVec &Locations,
409  LiveOutVec &LiveOuts) {
410  LLVM_DEBUG(dbgs() << "record statepoint : " << MI << "\n");
411  StatepointOpers SO(&MI);
412  MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // CC
413  MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // Flags
414  MOI = parseOperand(MOI, MOE, Locations, LiveOuts); // Num Deopts
415 
416  // Record Deopt Args.
417  unsigned NumDeoptArgs = Locations.back().Offset;
418  assert(Locations.back().Type == Location::Constant);
419  assert(NumDeoptArgs == SO.getNumDeoptArgs());
420 
421  while (NumDeoptArgs--)
422  MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
423 
424  // Record gc base/derived pairs
425  assert(MOI->isImm() && MOI->getImm() == StackMaps::ConstantOp);
426  ++MOI;
427  assert(MOI->isImm());
428  unsigned NumGCPointers = MOI->getImm();
429  ++MOI;
430  if (NumGCPointers) {
431  // Map logical index of GC ptr to MI operand index.
432  SmallVector<unsigned, 8> GCPtrIndices;
433  unsigned GCPtrIdx = (unsigned)SO.getFirstGCPtrIdx();
434  assert((int)GCPtrIdx != -1);
435  assert(MOI - MI.operands_begin() == GCPtrIdx + 0LL);
436  while (NumGCPointers--) {
437  GCPtrIndices.push_back(GCPtrIdx);
438  GCPtrIdx = StackMaps::getNextMetaArgIdx(&MI, GCPtrIdx);
439  }
440 
442  unsigned NumGCPairs = SO.getGCPointerMap(GCPairs);
443  (void)NumGCPairs;
444  LLVM_DEBUG(dbgs() << "NumGCPairs = " << NumGCPairs << "\n");
445 
446  auto MOB = MI.operands_begin();
447  for (auto &P : GCPairs) {
448  assert(P.first < GCPtrIndices.size() && "base pointer index not found");
449  assert(P.second < GCPtrIndices.size() &&
450  "derived pointer index not found");
451  unsigned BaseIdx = GCPtrIndices[P.first];
452  unsigned DerivedIdx = GCPtrIndices[P.second];
453  LLVM_DEBUG(dbgs() << "Base : " << BaseIdx << " Derived : " << DerivedIdx
454  << "\n");
455  (void)parseOperand(MOB + BaseIdx, MOE, Locations, LiveOuts);
456  (void)parseOperand(MOB + DerivedIdx, MOE, Locations, LiveOuts);
457  }
458 
459  MOI = MOB + GCPtrIdx;
460  }
461 
462  // Record gc allocas
463  assert(MOI < MOE);
464  assert(MOI->isImm() && MOI->getImm() == StackMaps::ConstantOp);
465  ++MOI;
466  unsigned NumAllocas = MOI->getImm();
467  ++MOI;
468  while (NumAllocas--) {
469  MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
470  assert(MOI < MOE);
471  }
472 }
473 
474 void StackMaps::recordStackMapOpers(const MCSymbol &MILabel,
475  const MachineInstr &MI, uint64_t ID,
478  bool recordResult) {
479  MCContext &OutContext = AP.OutStreamer->getContext();
480 
482  LiveOutVec LiveOuts;
483 
484  if (recordResult) {
485  assert(PatchPointOpers(&MI).hasDef() && "Stackmap has no return value.");
486  parseOperand(MI.operands_begin(), std::next(MI.operands_begin()), Locations,
487  LiveOuts);
488  }
489 
490  // Parse operands.
491  if (MI.getOpcode() == TargetOpcode::STATEPOINT)
492  parseStatepointOpers(MI, MOI, MOE, Locations, LiveOuts);
493  else
494  while (MOI != MOE)
495  MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
496 
497  // Move large constants into the constant pool.
498  for (auto &Loc : Locations) {
499  // Constants are encoded as sign-extended integers.
500  // -1 is directly encoded as .long 0xFFFFFFFF with no constant pool.
501  if (Loc.Type == Location::Constant && !isInt<32>(Loc.Offset)) {
502  Loc.Type = Location::ConstantIndex;
503  // ConstPool is intentionally a MapVector of 'uint64_t's (as
504  // opposed to 'int64_t's). We should never be in a situation
505  // where we have to insert either the tombstone or the empty
506  // keys into a map, and for a DenseMap<uint64_t, T> these are
507  // (uint64_t)0 and (uint64_t)-1. They can be and are
508  // represented using 32 bit integers.
510  (uint64_t)Loc.Offset !=
512  "empty and tombstone keys should fit in 32 bits!");
513  auto Result = ConstPool.insert(std::make_pair(Loc.Offset, Loc.Offset));
514  Loc.Offset = Result.first - ConstPool.begin();
515  }
516  }
517 
518  // Create an expression to calculate the offset of the callsite from function
519  // entry.
520  const MCExpr *CSOffsetExpr = MCBinaryExpr::createSub(
521  MCSymbolRefExpr::create(&MILabel, OutContext),
522  MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext);
523 
524  CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations),
525  std::move(LiveOuts));
526 
527  // Record the stack size of the current function and update callsite count.
528  const MachineFrameInfo &MFI = AP.MF->getFrameInfo();
529  const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo();
530  bool HasDynamicFrameSize =
531  MFI.hasVarSizedObjects() || RegInfo->hasStackRealignment(*(AP.MF));
532  uint64_t FrameSize = HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize();
533 
534  auto CurrentIt = FnInfos.find(AP.CurrentFnSym);
535  if (CurrentIt != FnInfos.end())
536  CurrentIt->second.RecordCount++;
537  else
538  FnInfos.insert(std::make_pair(AP.CurrentFnSym, FunctionInfo(FrameSize)));
539 }
540 
542  assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
543 
544  StackMapOpers opers(&MI);
545  const int64_t ID = MI.getOperand(PatchPointOpers::IDPos).getImm();
546  recordStackMapOpers(L, MI, ID, std::next(MI.operands_begin(),
547  opers.getVarIdx()),
548  MI.operands_end());
549 }
550 
552  assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint");
553 
554  PatchPointOpers opers(&MI);
555  const int64_t ID = opers.getID();
556  auto MOI = std::next(MI.operands_begin(), opers.getStackMapStartIdx());
557  recordStackMapOpers(L, MI, ID, MOI, MI.operands_end(),
558  opers.isAnyReg() && opers.hasDef());
559 
560 #ifndef NDEBUG
561  // verify anyregcc
562  auto &Locations = CSInfos.back().Locations;
563  if (opers.isAnyReg()) {
564  unsigned NArgs = opers.getNumCallArgs();
565  for (unsigned i = 0, e = (opers.hasDef() ? NArgs + 1 : NArgs); i != e; ++i)
566  assert(Locations[i].Type == Location::Register &&
567  "anyreg arg must be in reg.");
568  }
569 #endif
570 }
571 
573  assert(MI.getOpcode() == TargetOpcode::STATEPOINT && "expected statepoint");
574 
575  StatepointOpers opers(&MI);
576  const unsigned StartIdx = opers.getVarIdx();
577  recordStackMapOpers(L, MI, opers.getID(), MI.operands_begin() + StartIdx,
578  MI.operands_end(), false);
579 }
580 
581 /// Emit the stackmap header.
582 ///
583 /// Header {
584 /// uint8 : Stack Map Version (currently 3)
585 /// uint8 : Reserved (expected to be 0)
586 /// uint16 : Reserved (expected to be 0)
587 /// }
588 /// uint32 : NumFunctions
589 /// uint32 : NumConstants
590 /// uint32 : NumRecords
591 void StackMaps::emitStackmapHeader(MCStreamer &OS) {
592  // Header.
593  OS.emitIntValue(StackMapVersion, 1); // Version.
594  OS.emitIntValue(0, 1); // Reserved.
595  OS.emitInt16(0); // Reserved.
596 
597  // Num functions.
598  LLVM_DEBUG(dbgs() << WSMP << "#functions = " << FnInfos.size() << '\n');
599  OS.emitInt32(FnInfos.size());
600  // Num constants.
601  LLVM_DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n');
602  OS.emitInt32(ConstPool.size());
603  // Num callsites.
604  LLVM_DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n');
605  OS.emitInt32(CSInfos.size());
606 }
607 
608 /// Emit the function frame record for each function.
609 ///
610 /// StkSizeRecord[NumFunctions] {
611 /// uint64 : Function Address
612 /// uint64 : Stack Size
613 /// uint64 : Record Count
614 /// }
615 void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) {
616  // Function Frame records.
617  LLVM_DEBUG(dbgs() << WSMP << "functions:\n");
618  for (auto const &FR : FnInfos) {
619  LLVM_DEBUG(dbgs() << WSMP << "function addr: " << FR.first
620  << " frame size: " << FR.second.StackSize
621  << " callsite count: " << FR.second.RecordCount << '\n');
622  OS.emitSymbolValue(FR.first, 8);
623  OS.emitIntValue(FR.second.StackSize, 8);
624  OS.emitIntValue(FR.second.RecordCount, 8);
625  }
626 }
627 
628 /// Emit the constant pool.
629 ///
630 /// int64 : Constants[NumConstants]
631 void StackMaps::emitConstantPoolEntries(MCStreamer &OS) {
632  // Constant pool entries.
633  LLVM_DEBUG(dbgs() << WSMP << "constants:\n");
634  for (const auto &ConstEntry : ConstPool) {
635  LLVM_DEBUG(dbgs() << WSMP << ConstEntry.second << '\n');
636  OS.emitIntValue(ConstEntry.second, 8);
637  }
638 }
639 
640 /// Emit the callsite info for each callsite.
641 ///
642 /// StkMapRecord[NumRecords] {
643 /// uint64 : PatchPoint ID
644 /// uint32 : Instruction Offset
645 /// uint16 : Reserved (record flags)
646 /// uint16 : NumLocations
647 /// Location[NumLocations] {
648 /// uint8 : Register | Direct | Indirect | Constant | ConstantIndex
649 /// uint8 : Size in Bytes
650 /// uint16 : Dwarf RegNum
651 /// int32 : Offset
652 /// }
653 /// uint16 : Padding
654 /// uint16 : NumLiveOuts
655 /// LiveOuts[NumLiveOuts] {
656 /// uint16 : Dwarf RegNum
657 /// uint8 : Reserved
658 /// uint8 : Size in Bytes
659 /// }
660 /// uint32 : Padding (only if required to align to 8 byte)
661 /// }
662 ///
663 /// Location Encoding, Type, Value:
664 /// 0x1, Register, Reg (value in register)
665 /// 0x2, Direct, Reg + Offset (frame index)
666 /// 0x3, Indirect, [Reg + Offset] (spilled value)
667 /// 0x4, Constant, Offset (small constant)
668 /// 0x5, ConstIndex, Constants[Offset] (large constant)
669 void StackMaps::emitCallsiteEntries(MCStreamer &OS) {
670  LLVM_DEBUG(print(dbgs()));
671  // Callsite entries.
672  for (const auto &CSI : CSInfos) {
673  const LocationVec &CSLocs = CSI.Locations;
674  const LiveOutVec &LiveOuts = CSI.LiveOuts;
675 
676  // Verify stack map entry. It's better to communicate a problem to the
677  // runtime than crash in case of in-process compilation. Currently, we do
678  // simple overflow checks, but we may eventually communicate other
679  // compilation errors this way.
680  if (CSLocs.size() > UINT16_MAX || LiveOuts.size() > UINT16_MAX) {
681  OS.emitIntValue(UINT64_MAX, 8); // Invalid ID.
682  OS.emitValue(CSI.CSOffsetExpr, 4);
683  OS.emitInt16(0); // Reserved.
684  OS.emitInt16(0); // 0 locations.
685  OS.emitInt16(0); // padding.
686  OS.emitInt16(0); // 0 live-out registers.
687  OS.emitInt32(0); // padding.
688  continue;
689  }
690 
691  OS.emitIntValue(CSI.ID, 8);
692  OS.emitValue(CSI.CSOffsetExpr, 4);
693 
694  // Reserved for flags.
695  OS.emitInt16(0);
696  OS.emitInt16(CSLocs.size());
697 
698  for (const auto &Loc : CSLocs) {
699  OS.emitIntValue(Loc.Type, 1);
700  OS.emitIntValue(0, 1); // Reserved
701  OS.emitInt16(Loc.Size);
702  OS.emitInt16(Loc.Reg);
703  OS.emitInt16(0); // Reserved
704  OS.emitInt32(Loc.Offset);
705  }
706 
707  // Emit alignment to 8 byte.
709 
710  // Num live-out registers and padding to align to 4 byte.
711  OS.emitInt16(0);
712  OS.emitInt16(LiveOuts.size());
713 
714  for (const auto &LO : LiveOuts) {
715  OS.emitInt16(LO.DwarfRegNum);
716  OS.emitIntValue(0, 1);
717  OS.emitIntValue(LO.Size, 1);
718  }
719  // Emit alignment to 8 byte.
721  }
722 }
723 
724 /// Serialize the stackmap data.
726  (void)WSMP;
727  // Bail out if there's no stack map data.
728  assert((!CSInfos.empty() || ConstPool.empty()) &&
729  "Expected empty constant pool too!");
730  assert((!CSInfos.empty() || FnInfos.empty()) &&
731  "Expected empty function record too!");
732  if (CSInfos.empty())
733  return;
734 
735  MCContext &OutContext = AP.OutStreamer->getContext();
736  MCStreamer &OS = *AP.OutStreamer;
737 
738  // Create the section.
739  MCSection *StackMapSection =
740  OutContext.getObjectFileInfo()->getStackMapSection();
741  OS.switchSection(StackMapSection);
742 
743  // Emit a dummy symbol to force section inclusion.
744  OS.emitLabel(OutContext.getOrCreateSymbol(Twine("__LLVM_StackMaps")));
745 
746  // Serialize data.
747  LLVM_DEBUG(dbgs() << "********** Stack Map Output **********\n");
748  emitStackmapHeader(OS);
749  emitFunctionFrameRecords(OS);
750  emitConstantPoolEntries(OS);
751  emitCallsiteEntries(OS);
752  OS.addBlankLine();
753 
754  // Clean up.
755  CSInfos.clear();
756  ConstPool.clear();
757 }
llvm::Check::Size
@ Size
Definition: FileCheck.h:77
llvm::StackMaps::Location::Indirect
@ Indirect
Definition: StackMaps.h:266
i
i
Definition: README.txt:29
AsmPrinter.h
llvm::MachineFrameInfo::hasVarSizedObjects
bool hasVarSizedObjects() const
This method may be called any time after instruction selection is complete to determine if the stack ...
Definition: MachineFrameInfo.h:355
llvm::MCContext::getObjectFileInfo
const MCObjectFileInfo * getObjectFileInfo() const
Definition: MCContext.h:450
llvm::PatchPointOpers::getNumCallArgs
uint32_t getNumCallArgs() const
Return the number of call arguments.
Definition: StackMaps.h:121
llvm::AArch64CC::LO
@ LO
Definition: AArch64BaseInfo.h:258
llvm::MachineInstr::uses
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
Definition: MachineInstr.h:689
llvm::PatchPointOpers::hasDef
bool hasDef() const
Definition: StackMaps.h:98
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:109
llvm::MachineInstr::getOperandNo
unsigned getOperandNo(const_mop_iterator I) const
Returns the number of the operand iterator I points to.
Definition: MachineInstr.h:706
MachineInstr.h
MathExtras.h
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
llvm::StackMapOpers
MI-level stackmap operands.
Definition: StackMaps.h:35
llvm::StackMaps::Location::Register
@ Register
Definition: StackMaps.h:264
StackMapVersion
static cl::opt< int > StackMapVersion("stackmap-version", cl::init(3), cl::Hidden, cl::desc("Specify the stackmap encoding version (default = 3)"))
llvm::MCSymbol
MCSymbol - Instances of this class represent a symbol name in the MC file, and MCSymbols are created ...
Definition: MCSymbol.h:41
llvm::ISD::PATCHPOINT
@ PATCHPOINT
Definition: ISDOpcodes.h:1303
llvm::StackMaps::recordStatepoint
void recordStatepoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a statepoint instruction.
Definition: StackMaps.cpp:572
llvm::PatchPointOpers::IDPos
@ IDPos
Definition: StackMaps.h:79
llvm::AsmPrinter::CurrentFnSymForSize
MCSymbol * CurrentFnSymForSize
The symbol used to represent the start of the current function for the purpose of calculating its siz...
Definition: AsmPrinter.h:130
llvm::MCContext
Context object for machine code objects.
Definition: MCContext.h:76
P
This currently compiles esp xmm0 movsd esp eax eax esp ret We should use not the dag combiner This is because dagcombine2 needs to be able to see through the X86ISD::Wrapper which DAGCombine can t really do The code for turning x load into a single vector load is target independent and should be moved to the dag combiner The code for turning x load into a vector load can only handle a direct load from a global or a direct load from the stack It should be generalized to handle any load from P
Definition: README-SSE.txt:411
llvm::SmallVector
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1199
ErrorHandling.h
llvm::MCRegisterInfo::getDwarfRegNum
int getDwarfRegNum(MCRegister RegNum, bool isEH) const
Map a target register to an equivalent dwarf register number.
Definition: MCRegisterInfo.cpp:68
llvm::MCRegisterInfo::getNumRegs
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
Definition: MCRegisterInfo.h:491
llvm::X86Disassembler::Reg
Reg
All possible values of the reg field in the ModR/M byte.
Definition: X86DisassemblerDecoder.h:462
llvm::erase_if
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition: STLExtras.h:1998
llvm::TargetSubtargetInfo::getRegisterInfo
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
Definition: TargetSubtargetInfo.h:127
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:138
llvm::MCStreamer::emitValue
void emitValue(const MCExpr *Value, unsigned Size, SMLoc Loc=SMLoc())
Definition: MCStreamer.cpp:180
llvm::StatepointOpers::StatepointOpers
StatepointOpers(const MachineInstr *MI)
Definition: StackMaps.h:173
getDwarfRegNum
static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI)
Go up the super-register chain until we hit a valid dwarf register number.
Definition: StackMaps.cpp:195
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:236
MCObjectFileInfo.h
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition: Type.h:45
llvm::StatepointOpers::getNumGcMapEntriesIdx
unsigned getNumGcMapEntriesIdx()
Get index of number of gc map entries.
Definition: StackMaps.cpp:94
llvm::MCStreamer::emitInt32
void emitInt32(uint64_t Value)
Definition: MCStreamer.h:744
llvm::logicalview::LVWarningKind::Locations
@ Locations
llvm::max
Expected< ExpressionValue > max(const ExpressionValue &Lhs, const ExpressionValue &Rhs)
Definition: FileCheck.cpp:337
STLExtras.h
RHS
Value * RHS
Definition: X86PartialReduction.cpp:76
llvm::PatchPointOpers
MI-level patchpoint operands.
Definition: StackMaps.h:76
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1628
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::PatchPointOpers::getID
uint64_t getID() const
Return the ID for the given patchpoint.
Definition: StackMaps.h:101
llvm::StackMaps::recordStackMap
void recordStackMap(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a stackmap instruction.
Definition: StackMaps.cpp:541
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::BitmaskEnumDetail::Mask
constexpr std::underlying_type_t< E > Mask()
Get a bitmask with 1s in all places up to the high-order bit of E's largest value.
Definition: BitmaskEnum.h:80
CommandLine.h
llvm::Register::isPhysical
bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:97
llvm::MCStreamer
Streaming machine code generation interface.
Definition: MCStreamer.h:212
LHS
Value * LHS
Definition: X86PartialReduction.cpp:75
llvm::StatepointOpers::getNumDeoptArgsIdx
unsigned getNumDeoptArgsIdx() const
Get index of Number Deopt Arguments operand.
Definition: StackMaps.h:199
llvm::DenseMapInfo
An information struct used to provide DenseMap with the various necessary components for a given valu...
Definition: APInt.h:34
llvm::MapVector::begin
iterator begin()
Definition: MapVector.h:70
llvm::MCContext::getOrCreateSymbol
MCSymbol * getOrCreateSymbol(const Twine &Name)
Lookup the symbol inside with the specified Name.
Definition: MCContext.cpp:201
llvm::MachineOperand::isImplicit
bool isImplicit() const
Definition: MachineOperand.h:386
getReg
static unsigned getReg(const MCDisassembler *D, unsigned RC, unsigned RegNo)
Definition: MipsDisassembler.cpp:521
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:553
llvm::AsmPrinter::OutStreamer
std::unique_ptr< MCStreamer > OutStreamer
This is the MCStreamer object for the file we are generating.
Definition: AsmPrinter.h:99
llvm::MachineInstr::getOperand
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:526
Twine.h
MCContext.h
llvm::StatepointOpers::getGCPointerMap
unsigned getGCPointerMap(SmallVectorImpl< std::pair< unsigned, unsigned >> &GCMap)
Get vector of base/derived pairs from statepoint.
Definition: StackMaps.cpp:135
llvm::MCStreamer::emitLabel
virtual void emitLabel(MCSymbol *Symbol, SMLoc Loc=SMLoc())
Emit a label for Symbol into the current section.
Definition: MCStreamer.cpp:423
llvm::MCStreamer::switchSection
virtual void switchSection(MCSection *Section, const MCExpr *Subsection=nullptr)
Set the current section where code is being emitted to Section.
Definition: MCStreamer.cpp:1234
llvm::TargetRegisterClass
Definition: TargetRegisterInfo.h:45
llvm::MCStreamer::emitSymbolValue
void emitSymbolValue(const MCSymbol *Sym, unsigned Size, bool IsSectionRelative=false)
Special case of EmitValue that avoids the client having to pass in a MCExpr for MCSymbols.
Definition: MCStreamer.cpp:184
llvm::ms_demangle::QualifierMangleMode::Result
@ Result
llvm::MCObjectFileInfo::getStackMapSection
MCSection * getStackMapSection() const
Definition: MCObjectFileInfo.h:350
UINT64_MAX
#define UINT64_MAX
Definition: DataTypes.h:77
TargetOpcodes.h
llvm::MCRegisterInfo::getSubRegIndex
unsigned getSubRegIndex(MCRegister RegNo, MCRegister SubRegNo) const
For a given register pair, return the sub-register index if the second register is a sub-register of ...
Definition: MCRegisterInfo.cpp:44
B
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:48
llvm::StatepointOpers::getVarIdx
unsigned getVarIdx() const
Get starting index of non call related arguments (calling convention, statepoint flags,...
Definition: StackMaps.h:188
llvm::AsmPrinter::CurrentFnSym
MCSymbol * CurrentFnSym
The symbol for the current function.
Definition: AsmPrinter.h:121
llvm::StackMaps::StackMaps
StackMaps(AsmPrinter &AP)
Definition: StackMaps.cpp:166
llvm::PatchPointOpers::PatchPointOpers
PatchPointOpers(const MachineInstr *MI)
Definition: StackMaps.cpp:62
llvm::raw_ostream
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
llvm::MachineFrameInfo::getStackSize
uint64_t getStackSize() const
Return the number of bytes that must be allocated to hold all of the fixed size frame objects.
Definition: MachineFrameInfo.h:585
Align
uint64_t Align
Definition: ELFObjHandler.cpp:82
llvm::MCStreamer::addBlankLine
virtual void addBlankLine()
Emit a blank line to a .s file to pretty it up.
Definition: MCStreamer.h:376
llvm::MachineOperand::isRegLiveOut
bool isRegLiveOut() const
isRegLiveOut - Tests if this is a MO_RegisterLiveOut operand.
Definition: MachineOperand.h:352
llvm::CallingConv::ID
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
llvm::PatchPointOpers::isAnyReg
bool isAnyReg() const
Definition: StackMaps.h:97
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1683
llvm::PatchPointOpers::getNextScratchIdx
unsigned getNextScratchIdx(unsigned StartIdx=0) const
Get the next scratch register operand index.
Definition: StackMaps.cpp:77
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:672
llvm::MCStreamer::emitInt16
void emitInt16(uint64_t Value)
Definition: MCStreamer.h:743
llvm::cl::opt
Definition: CommandLine.h:1410
llvm::TargetRegisterInfo::getSpillSize
unsigned getSpillSize(const TargetRegisterClass &RC) const
Return the size in bytes of the stack slot allocated to hold a spilled copy of a register from class ...
Definition: TargetRegisterInfo.h:285
llvm::MachineOperand::isUndef
bool isUndef() const
Definition: MachineOperand.h:401
llvm::StatepointOpers::getNumAllocaIdx
unsigned getNumAllocaIdx()
Get index of number of gc allocas.
Definition: StackMaps.cpp:104
llvm::StackMapOpers::getVarIdx
unsigned getVarIdx() const
Get the operand index of the variable list of non-argument operands.
Definition: StackMaps.h:56
llvm::PatchPointOpers::getVarIdx
unsigned getVarIdx() const
Get the operand index of the variable list of non-argument operands.
Definition: StackMaps.h:127
llvm::MapVector::find
iterator find(const KeyT &Key)
Definition: MapVector.h:148
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:326
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:66
uint64_t
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::StackMaps::Location::Constant
@ Constant
Definition: StackMaps.h:267
llvm::StackMaps::serializeToStackMapSection
void serializeToStackMapSection()
If there is any stack map data, create a stack map section and serialize the map info into it.
Definition: StackMaps.cpp:725
move
compiles ldr LCPI1_0 ldr ldr mov lsr tst moveq r1 ldr LCPI1_1 and r0 bx lr It would be better to do something like to fold the shift into the conditional move
Definition: README.txt:546
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:31
I
#define I(x, y, z)
Definition: MD5.cpp:58
llvm::cl::init
initializer< Ty > init(const Ty &Val)
Definition: CommandLine.h:445
MCRegisterInfo.h
llvm::StackMaps::LiveOutVec
SmallVector< LiveOutReg, 8 > LiveOutVec
Definition: StackMaps.h:309
llvm::MCRegisterInfo::getLLVMRegNum
std::optional< unsigned > getLLVMRegNum(unsigned RegNum, bool isEH) const
Map a dwarf register back to a target register.
Definition: MCRegisterInfo.cpp:81
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MCStreamer::emitIntValue
virtual void emitIntValue(uint64_t Value, unsigned Size)
Special case of EmitValue that avoids the client having to pass in a MCExpr for constant integers.
Definition: MCStreamer.cpp:134
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:688
llvm::MachineOperand::isEarlyClobber
bool isEarlyClobber() const
Definition: MachineOperand.h:442
llvm::ISD::STACKMAP
@ STACKMAP
Definition: ISDOpcodes.h:1297
llvm::MCBinaryExpr::createSub
static const MCBinaryExpr * createSub(const MCExpr *LHS, const MCExpr *RHS, MCContext &Ctx)
Definition: MCExpr.h:610
llvm::AsmPrinter::MF
MachineFunction * MF
The current machine function.
Definition: AsmPrinter.h:102
llvm::MCSuperRegIterator
MCSuperRegIterator enumerates all super-registers of Reg.
Definition: MCRegisterInfo.h:644
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:366
llvm::StackMaps::getNextMetaArgIdx
static unsigned getNextMetaArgIdx(const MachineInstr *MI, unsigned CurIdx)
Get index of next meta operand.
Definition: StackMaps.cpp:171
llvm::PatchPointOpers::getStackMapStartIdx
unsigned getStackMapStartIdx() const
Get the index at which stack map locations will be recorded.
Definition: StackMaps.h:133
isReg
static bool isReg(const MCInst &MI, unsigned OpNo)
Definition: MipsInstPrinter.cpp:31
llvm::MapVector::insert
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition: MapVector.h:118
DataLayout.h
llvm::Offset
@ Offset
Definition: DWP.cpp:406
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:143
uint32_t
TargetSubtargetInfo.h
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
llvm::MCSection
Instances of this class represent a uniqued identifier for a section in the current translation unit.
Definition: MCSection.h:39
llvm::MachineOperand::isDef
bool isDef() const
Definition: MachineOperand.h:381
llvm::MCStreamer::emitValueToAlignment
virtual void emitValueToAlignment(Align Alignment, int64_t Value=0, unsigned ValueSize=1, unsigned MaxBytesToEmit=0)
Emit some number of copies of Value until the byte alignment ByteAlignment is reached.
Definition: MCStreamer.cpp:1222
llvm::StackMapOpers::StackMapOpers
StackMapOpers(const MachineInstr *MI)
Definition: StackMaps.cpp:56
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineOperand::getSubReg
unsigned getSubReg() const
Definition: MachineOperand.h:371
llvm::MapVector::end
iterator end()
Definition: MapVector.h:72
llvm::StatepointOpers::getFirstGCPtrIdx
int getFirstGCPtrIdx()
Get index of first GC pointer operand of -1 if there are none.
Definition: StackMaps.cpp:125
llvm::StackMaps::Location::Direct
@ Direct
Definition: StackMaps.h:265
llvm::Twine
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
llvm::StatepointOpers
MI-level Statepoint operands.
Definition: StackMaps.h:158
llvm::StackMaps::Location::ConstantIndex
@ ConstantIndex
Definition: StackMaps.h:268
MachineFrameInfo.h
llvm::StatepointOpers::isFoldableReg
bool isFoldableReg(Register Reg) const
Return true if Reg is used only in operands which can be folded to stack usage.
Definition: StackMaps.cpp:149
llvm::StackMaps::recordPatchPoint
void recordPatchPoint(const MCSymbol &L, const MachineInstr &MI)
Generate a stackmap record for a patchpoint instruction.
Definition: StackMaps.cpp:551
llvm::MapVector::size
size_type size() const
Definition: MapVector.h:61
StackMaps.h
llvm::AsmPrinter
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:84
llvm::MCSymbolRefExpr::create
static const MCSymbolRefExpr * create(const MCSymbol *Symbol, MCContext &Ctx)
Definition: MCExpr.h:386
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:328
llvm::RISCVMatInt::Imm
@ Imm
Definition: RISCVMatInt.h:23
llvm::TargetRegisterInfo::hasStackRealignment
bool hasStackRealignment(const MachineFunction &MF) const
True if stack realignment is required and still possible.
Definition: TargetRegisterInfo.h:975
llvm::MCRegisterInfo::isSuperRegister
bool isSuperRegister(MCRegister RegA, MCRegister RegB) const
Returns true if RegB is a super-register of RegA.
Definition: MCRegisterInfo.h:659
getConstMetaVal
static uint64_t getConstMetaVal(const MachineInstr &MI, unsigned Idx)
Definition: StackMaps.cpp:48
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:106
N
#define N
llvm::MCRegisterInfo::DiffListIterator::isValid
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
Definition: MCRegisterInfo.h:224
MCStreamer.h
llvm::MachineInstr::getNumOperands
unsigned getNumOperands() const
Retuns the total number of operands.
Definition: MachineInstr.h:519
llvm::StackMaps::Location::Unprocessed
@ Unprocessed
Definition: StackMaps.h:263
llvm::MachineFunction::getDataLayout
const DataLayout & getDataLayout() const
Return the DataLayout attached to the Module associated to this MF.
Definition: MachineFunction.cpp:292
llvm::MachineOperand::getRegLiveOut
const uint32_t * getRegLiveOut() const
getRegLiveOut - Returns a bit mask of live-out registers.
Definition: MachineOperand.h:667
llvm::MCRegisterInfo::getSubRegIdxOffset
unsigned getSubRegIdxOffset(unsigned Idx) const
Get the offset of the bit range covered by a sub-register index.
Definition: MCRegisterInfo.cpp:62
llvm::SmallVectorImpl
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
Definition: APFloat.h:42
MachineOperand.h
DenseMapInfo.h
llvm::StatepointOpers::getID
uint64_t getID() const
Return the ID for the given statepoint.
Definition: StackMaps.h:204
llvm::StackMaps::LocationVec
SmallVector< Location, 8 > LocationVec
Definition: StackMaps.h:308
llvm::cl::desc
Definition: CommandLine.h:411
llvm::TargetRegisterInfo::getMinimalPhysRegClass
const TargetRegisterClass * getMinimalPhysRegClass(MCRegister Reg, MVT VT=MVT::Other) const
Returns the Register Class of a physical register of the given type, picking the most sub register cl...
Definition: TargetRegisterInfo.cpp:212
raw_ostream.h
MachineFunction.h
llvm::printReg
Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
Definition: TargetRegisterInfo.cpp:111
MCExpr.h
TargetRegisterInfo.h
llvm::MCExpr
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
Debug.h
llvm::StatepointOpers::getNumGCPtrIdx
unsigned getNumGCPtrIdx()
Get index of number of GC pointers.
Definition: StackMaps.cpp:114
llvm::StackMaps::LiveOutReg
Definition: StackMaps.h:280