LLVM  10.0.0svn
StackMaps.h
Go to the documentation of this file.
1 //===- StackMaps.h - StackMaps ----------------------------------*- C++ -*-===//
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 #ifndef LLVM_CODEGEN_STACKMAPS_H
10 #define LLVM_CODEGEN_STACKMAPS_H
11 
12 #include "llvm/ADT/MapVector.h"
13 #include "llvm/ADT/SmallVector.h"
15 #include "llvm/IR/CallingConv.h"
16 #include "llvm/MC/MCSymbol.h"
17 #include "llvm/Support/Debug.h"
18 #include <algorithm>
19 #include <cassert>
20 #include <cstdint>
21 #include <vector>
22 
23 namespace llvm {
24 
25 class AsmPrinter;
26 class MCExpr;
27 class MCStreamer;
28 class raw_ostream;
29 class TargetRegisterInfo;
30 
31 /// MI-level stackmap operands.
32 ///
33 /// MI stackmap operations take the form:
34 /// <id>, <numBytes>, live args...
36 public:
37  /// Enumerate the meta operands.
38  enum { IDPos, NBytesPos };
39 
40 private:
41  const MachineInstr* MI;
42 
43 public:
44  explicit StackMapOpers(const MachineInstr *MI);
45 
46  /// Return the ID for the given stackmap
47  uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
48 
49  /// Return the number of patchable bytes the given stackmap should emit.
51  return MI->getOperand(NBytesPos).getImm();
52  }
53 
54  /// Get the operand index of the variable list of non-argument operands.
55  /// These hold the "live state".
56  unsigned getVarIdx() const {
57  // Skip ID, nShadowBytes.
58  return 2;
59  }
60 };
61 
62 /// MI-level patchpoint operands.
63 ///
64 /// MI patchpoint operations take the form:
65 /// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
66 ///
67 /// IR patchpoint intrinsics do not have the <cc> operand because calling
68 /// convention is part of the subclass data.
69 ///
70 /// SD patchpoint nodes do not have a def operand because it is part of the
71 /// SDValue.
72 ///
73 /// Patchpoints following the anyregcc convention are handled specially. For
74 /// these, the stack map also records the location of the return value and
75 /// arguments.
77 public:
78  /// Enumerate the meta operands.
79  enum { IDPos, NBytesPos, TargetPos, NArgPos, CCPos, MetaEnd };
80 
81 private:
82  const MachineInstr *MI;
83  bool HasDef;
84 
85  unsigned getMetaIdx(unsigned Pos = 0) const {
86  assert(Pos < MetaEnd && "Meta operand index out of range.");
87  return (HasDef ? 1 : 0) + Pos;
88  }
89 
90  const MachineOperand &getMetaOper(unsigned Pos) const {
91  return MI->getOperand(getMetaIdx(Pos));
92  }
93 
94 public:
95  explicit PatchPointOpers(const MachineInstr *MI);
96 
97  bool isAnyReg() const { return (getCallingConv() == CallingConv::AnyReg); }
98  bool hasDef() const { return HasDef; }
99 
100  /// Return the ID for the given patchpoint.
101  uint64_t getID() const { return getMetaOper(IDPos).getImm(); }
102 
103  /// Return the number of patchable bytes the given patchpoint should emit.
105  return getMetaOper(NBytesPos).getImm();
106  }
107 
108  /// Returns the target of the underlying call.
109  const MachineOperand &getCallTarget() const {
110  return getMetaOper(TargetPos);
111  }
112 
113  /// Returns the calling convention
115  return getMetaOper(CCPos).getImm();
116  }
117 
118  unsigned getArgIdx() const { return getMetaIdx() + MetaEnd; }
119 
120  /// Return the number of call arguments
122  return MI->getOperand(getMetaIdx(NArgPos)).getImm();
123  }
124 
125  /// Get the operand index of the variable list of non-argument operands.
126  /// These hold the "live state".
127  unsigned getVarIdx() const {
128  return getMetaIdx() + MetaEnd + getNumCallArgs();
129  }
130 
131  /// Get the index at which stack map locations will be recorded.
132  /// Arguments are not recorded unless the anyregcc convention is used.
133  unsigned getStackMapStartIdx() const {
134  if (isAnyReg())
135  return getArgIdx();
136  return getVarIdx();
137  }
138 
139  /// Get the next scratch register operand index.
140  unsigned getNextScratchIdx(unsigned StartIdx = 0) const;
141 };
142 
143 /// MI-level Statepoint operands
144 ///
145 /// Statepoint operands take the form:
146 /// <id>, <num patch bytes >, <num call arguments>, <call target>,
147 /// [call arguments...],
148 /// <StackMaps::ConstantOp>, <calling convention>,
149 /// <StackMaps::ConstantOp>, <statepoint flags>,
150 /// <StackMaps::ConstantOp>, <num deopt args>, [deopt args...],
151 /// <gc base/derived pairs...> <gc allocas...>
152 /// Note that the last two sets of arguments are not currently length
153 /// prefixed.
155  // TODO:: we should change the STATEPOINT representation so that CC and
156  // Flags should be part of meta operands, with args and deopt operands, and
157  // gc operands all prefixed by their length and a type code. This would be
158  // much more consistent.
159 public:
160  // These values are aboolute offsets into the operands of the statepoint
161  // instruction.
162  enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd };
163 
164  // These values are relative offests from the start of the statepoint meta
165  // arguments (i.e. the end of the call arguments).
166  enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
167 
168  explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
169 
170  /// Get starting index of non call related arguments
171  /// (calling convention, statepoint flags, vm state and gc state).
172  unsigned getVarIdx() const {
173  return MI->getOperand(NCallArgsPos).getImm() + MetaEnd;
174  }
175 
176  /// Return the ID for the given statepoint.
177  uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
178 
179  /// Return the number of patchable bytes the given statepoint should emit.
181  return MI->getOperand(NBytesPos).getImm();
182  }
183 
184  /// Returns the target of the underlying call.
185  const MachineOperand &getCallTarget() const {
186  return MI->getOperand(CallTargetPos);
187  }
188 
189 private:
190  const MachineInstr *MI;
191 };
192 
193 class StackMaps {
194 public:
195  struct Location {
202  ConstantIndex
203  };
204  LocationType Type = Unprocessed;
205  unsigned Size = 0;
206  unsigned Reg = 0;
207  int64_t Offset = 0;
208 
209  Location() = default;
210  Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset)
211  : Type(Type), Size(Size), Reg(Reg), Offset(Offset) {}
212  };
213 
214  struct LiveOutReg {
215  unsigned short Reg = 0;
216  unsigned short DwarfRegNum = 0;
217  unsigned short Size = 0;
218 
219  LiveOutReg() = default;
220  LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum,
221  unsigned short Size)
222  : Reg(Reg), DwarfRegNum(DwarfRegNum), Size(Size) {}
223  };
224 
225  // OpTypes are used to encode information about the following logical
226  // operand (which may consist of several MachineOperands) for the
227  // OpParser.
228  using OpType = enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp };
229 
230  StackMaps(AsmPrinter &AP);
231 
232  void reset() {
233  CSInfos.clear();
234  ConstPool.clear();
235  FnInfos.clear();
236  }
237 
241 
242  struct FunctionInfo {
243  uint64_t StackSize = 0;
244  uint64_t RecordCount = 1;
245 
246  FunctionInfo() = default;
247  explicit FunctionInfo(uint64_t StackSize) : StackSize(StackSize) {}
248  };
249 
250  struct CallsiteInfo {
251  const MCExpr *CSOffsetExpr = nullptr;
252  uint64_t ID = 0;
255 
256  CallsiteInfo() = default;
257  CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
258  LocationVec &&Locations, LiveOutVec &&LiveOuts)
259  : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
260  LiveOuts(std::move(LiveOuts)) {}
261  };
262 
264  using CallsiteInfoList = std::vector<CallsiteInfo>;
265 
266  /// Generate a stackmap record for a stackmap instruction.
267  ///
268  /// MI must be a raw STACKMAP, not a PATCHPOINT.
269  void recordStackMap(const MachineInstr &MI);
270 
271  /// Generate a stackmap record for a patchpoint instruction.
272  void recordPatchPoint(const MachineInstr &MI);
273 
274  /// Generate a stackmap record for a statepoint instruction.
275  void recordStatepoint(const MachineInstr &MI);
276 
277  /// If there is any stack map data, create a stack map section and serialize
278  /// the map info into it. This clears the stack map data structures
279  /// afterwards.
280  void serializeToStackMapSection();
281 
282  /// Get call site info.
283  CallsiteInfoList &getCSInfos() { return CSInfos; }
284 
285  /// Get function info.
286  FnInfoMap &getFnInfos() { return FnInfos; }
287 
288 private:
289  static const char *WSMP;
290 
291  AsmPrinter &AP;
292  CallsiteInfoList CSInfos;
293  ConstantPool ConstPool;
294  FnInfoMap FnInfos;
295 
297  parseOperand(MachineInstr::const_mop_iterator MOI,
299  LiveOutVec &LiveOuts) const;
300 
301  /// Create a live-out register record for the given register @p Reg.
302  LiveOutReg createLiveOutReg(unsigned Reg,
303  const TargetRegisterInfo *TRI) const;
304 
305  /// Parse the register live-out mask and return a vector of live-out
306  /// registers that need to be recorded in the stackmap.
307  LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const;
308 
309  /// This should be called by the MC lowering code _immediately_ before
310  /// lowering the MI to an MCInst. It records where the operands for the
311  /// instruction are stored, and outputs a label to record the offset of
312  /// the call from the start of the text section. In special cases (e.g. AnyReg
313  /// calling convention) the return register is also recorded if requested.
314  void recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
317  bool recordResult = false);
318 
319  /// Emit the stackmap header.
320  void emitStackmapHeader(MCStreamer &OS);
321 
322  /// Emit the function frame record for each function.
323  void emitFunctionFrameRecords(MCStreamer &OS);
324 
325  /// Emit the constant pool.
326  void emitConstantPoolEntries(MCStreamer &OS);
327 
328  /// Emit the callsite info for each stackmap/patchpoint intrinsic call.
329  void emitCallsiteEntries(MCStreamer &OS);
330 
331  void print(raw_ostream &OS);
332  void debug() { print(dbgs()); }
333 };
334 
335 } // end namespace llvm
336 
337 #endif // LLVM_CODEGEN_STACKMAPS_H
This class represents lattice values for constants.
Definition: AllocatorList.h:23
bool hasDef() const
Definition: StackMaps.h:98
bool isAnyReg() const
Definition: StackMaps.h:97
unsigned Reg
StatepointOpers(const MachineInstr *MI)
Definition: StackMaps.h:168
unsigned const TargetRegisterInfo * TRI
Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset)
Definition: StackMaps.h:210
Definition: BitVector.h:937
unsigned getVarIdx() const
Get starting index of non call related arguments (calling convention, statepoint flags, vm state and gc state).
Definition: StackMaps.h:172
Base class for the full range of assembler expressions which are needed for parsing.
Definition: MCExpr.h:35
unsigned getStackMapStartIdx() const
Get the index at which stack map locations will be recorded.
Definition: StackMaps.h:133
CallsiteInfoList & getCSInfos()
Get call site info.
Definition: StackMaps.h:283
uint64_t getID() const
Return the ID for the given stackmap.
Definition: StackMaps.h:47
CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID, LocationVec &&Locations, LiveOutVec &&LiveOuts)
Definition: StackMaps.h:257
Streaming machine code generation interface.
Definition: MCStreamer.h:188
const MachineOperand & getCallTarget() const
Returns the target of the underlying call.
Definition: StackMaps.h:185
The instances of the Type class are immutable: once they are created, they are never changed...
Definition: Type.h:45
FnInfoMap & getFnInfos()
Get function info.
Definition: StackMaps.h:286
LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum, unsigned short Size)
Definition: StackMaps.h:220
This class is intended to be used as a driving class for all asm writers.
Definition: AsmPrinter.h:78
unsigned getVarIdx() const
Get the operand index of the variable list of non-argument operands.
Definition: StackMaps.h:127
static void print(raw_ostream &Out, object::Archive::Kind Kind, T Val)
MI-level patchpoint operands.
Definition: StackMaps.h:76
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given stackmap should emit.
Definition: StackMaps.h:50
StackMapOpers(const MachineInstr *MI)
Definition: StackMaps.cpp:48
MachineOperand class - Representation of each machine instruction operand.
unsigned getVarIdx() const
Get the operand index of the variable list of non-argument operands.
Definition: StackMaps.h:56
enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp } OpType
Definition: StackMaps.h:228
int64_t getImm() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:132
#define debug(s)
FunctionInfo(uint64_t StackSize)
Definition: StackMaps.h:247
Representation of each machine instruction.
Definition: MachineInstr.h:64
MI-level stackmap operands.
Definition: StackMaps.h:35
uint32_t getNumCallArgs() const
Return the number of call arguments.
Definition: StackMaps.h:121
MI-level Statepoint operands.
Definition: StackMaps.h:154
unsigned getArgIdx() const
Definition: StackMaps.h:118
uint32_t Size
Definition: Profile.cpp:46
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given patchpoint should emit.
Definition: StackMaps.h:104
uint64_t getID() const
Return the ID for the given patchpoint.
Definition: StackMaps.h:101
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
uint32_t getNumPatchBytes() const
Return the number of patchable bytes the given statepoint should emit.
Definition: StackMaps.h:180
uint64_t getID() const
Return the ID for the given statepoint.
Definition: StackMaps.h:177
std::underlying_type< E >::type Mask()
Get a bitmask with 1s in all places up to the high-order bit of E&#39;s largest value.
Definition: BitmaskEnum.h:80
This class implements an extremely fast bulk output stream that can only output to a stream...
Definition: raw_ostream.h:45
IRTranslator LLVM IR MI
const MachineOperand & getCallTarget() const
Returns the target of the underlying call.
Definition: StackMaps.h:109
CallingConv::ID getCallingConv() const
Returns the calling convention.
Definition: StackMaps.h:114
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:416
std::vector< CallsiteInfo > CallsiteInfoList
Definition: StackMaps.h:264