StackMaps.h 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256
  1. //===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #ifndef LLVM_CODEGEN_STACKMAPS_H
  10. #define LLVM_CODEGEN_STACKMAPS_H
  11. #include "llvm/ADT/MapVector.h"
  12. #include "llvm/ADT/SmallVector.h"
  13. #include "llvm/CodeGen/MachineInstr.h"
  14. #include "llvm/Support/Debug.h"
  15. #include <map>
  16. #include <vector>
  17. namespace llvm {
  18. class AsmPrinter;
  19. class MCExpr;
  20. class MCStreamer;
  21. /// \brief MI-level patchpoint operands.
  22. ///
  23. /// MI patchpoint operations take the form:
  24. /// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
  25. ///
  26. /// IR patchpoint intrinsics do not have the <cc> operand because calling
  27. /// convention is part of the subclass data.
  28. ///
  29. /// SD patchpoint nodes do not have a def operand because it is part of the
  30. /// SDValue.
  31. ///
  32. /// Patchpoints following the anyregcc convention are handled specially. For
  33. /// these, the stack map also records the location of the return value and
  34. /// arguments.
  35. class PatchPointOpers {
  36. public:
  37. /// Enumerate the meta operands.
  38. enum { IDPos, NBytesPos, TargetPos, NArgPos, CCPos, MetaEnd };
  39. private:
  40. const MachineInstr *MI;
  41. bool HasDef;
  42. bool IsAnyReg;
  43. public:
  44. explicit PatchPointOpers(const MachineInstr *MI);
  45. bool isAnyReg() const { return IsAnyReg; }
  46. bool hasDef() const { return HasDef; }
  47. unsigned getMetaIdx(unsigned Pos = 0) const {
  48. assert(Pos < MetaEnd && "Meta operand index out of range.");
  49. return (HasDef ? 1 : 0) + Pos;
  50. }
  51. const MachineOperand &getMetaOper(unsigned Pos) {
  52. return MI->getOperand(getMetaIdx(Pos));
  53. }
  54. unsigned getArgIdx() const { return getMetaIdx() + MetaEnd; }
  55. /// Get the operand index of the variable list of non-argument operands.
  56. /// These hold the "live state".
  57. unsigned getVarIdx() const {
  58. return getMetaIdx() + MetaEnd +
  59. MI->getOperand(getMetaIdx(NArgPos)).getImm();
  60. }
  61. /// Get the index at which stack map locations will be recorded.
  62. /// Arguments are not recorded unless the anyregcc convention is used.
  63. unsigned getStackMapStartIdx() const {
  64. if (IsAnyReg)
  65. return getArgIdx();
  66. return getVarIdx();
  67. }
  68. /// \brief Get the next scratch register operand index.
  69. unsigned getNextScratchIdx(unsigned StartIdx = 0) const;
  70. };
  71. /// MI-level Statepoint operands
  72. ///
  73. /// Statepoint operands take the form:
  74. /// <id>, <num patch bytes >, <num call arguments>, <call target>,
  75. /// [call arguments], <StackMaps::ConstantOp>, <calling convention>,
  76. /// <StackMaps::ConstantOp>, <statepoint flags>,
  77. /// <StackMaps::ConstantOp>, <num other args>, [other args],
  78. /// [gc values]
  79. class StatepointOpers {
  80. private:
  81. // These values are aboolute offsets into the operands of the statepoint
  82. // instruction.
  83. enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd };
  84. // These values are relative offests from the start of the statepoint meta
  85. // arguments (i.e. the end of the call arguments).
  86. enum { CCOffset = 1, FlagsOffset = 3, NumVMSArgsOffset = 5 };
  87. public:
  88. explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {}
  89. /// Get starting index of non call related arguments
  90. /// (calling convention, statepoint flags, vm state and gc state).
  91. unsigned getVarIdx() const {
  92. return MI->getOperand(NCallArgsPos).getImm() + MetaEnd;
  93. }
  94. /// Return the ID for the given statepoint.
  95. uint64_t getID() const { return MI->getOperand(IDPos).getImm(); }
  96. /// Return the number of patchable bytes the given statepoint should emit.
  97. uint32_t getNumPatchBytes() const {
  98. return MI->getOperand(NBytesPos).getImm();
  99. }
  100. /// Returns the target of the underlying call.
  101. const MachineOperand &getCallTarget() const {
  102. return MI->getOperand(CallTargetPos);
  103. }
  104. private:
  105. const MachineInstr *MI;
  106. };
  107. class StackMaps {
  108. public:
  109. struct Location {
  110. enum LocationType {
  111. Unprocessed,
  112. Register,
  113. Direct,
  114. Indirect,
  115. Constant,
  116. ConstantIndex
  117. };
  118. LocationType Type;
  119. unsigned Size;
  120. unsigned Reg;
  121. int64_t Offset;
  122. Location() : Type(Unprocessed), Size(0), Reg(0), Offset(0) {}
  123. Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset)
  124. : Type(Type), Size(Size), Reg(Reg), Offset(Offset) {}
  125. };
  126. struct LiveOutReg {
  127. unsigned short Reg;
  128. unsigned short DwarfRegNum;
  129. unsigned short Size;
  130. LiveOutReg() : Reg(0), DwarfRegNum(0), Size(0) {}
  131. LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum,
  132. unsigned short Size)
  133. : Reg(Reg), DwarfRegNum(DwarfRegNum), Size(Size) {}
  134. };
  135. // OpTypes are used to encode information about the following logical
  136. // operand (which may consist of several MachineOperands) for the
  137. // OpParser.
  138. typedef enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp } OpType;
  139. StackMaps(AsmPrinter &AP);
  140. void reset() {
  141. CSInfos.clear();
  142. ConstPool.clear();
  143. FnStackSize.clear();
  144. }
  145. /// \brief Generate a stackmap record for a stackmap instruction.
  146. ///
  147. /// MI must be a raw STACKMAP, not a PATCHPOINT.
  148. void recordStackMap(const MachineInstr &MI);
  149. /// \brief Generate a stackmap record for a patchpoint instruction.
  150. void recordPatchPoint(const MachineInstr &MI);
  151. /// \brief Generate a stackmap record for a statepoint instruction.
  152. void recordStatepoint(const MachineInstr &MI);
  153. /// If there is any stack map data, create a stack map section and serialize
  154. /// the map info into it. This clears the stack map data structures
  155. /// afterwards.
  156. void serializeToStackMapSection();
  157. private:
  158. static const char *WSMP;
  159. typedef SmallVector<Location, 8> LocationVec;
  160. typedef SmallVector<LiveOutReg, 8> LiveOutVec;
  161. typedef MapVector<uint64_t, uint64_t> ConstantPool;
  162. typedef MapVector<const MCSymbol *, uint64_t> FnStackSizeMap;
  163. struct CallsiteInfo {
  164. const MCExpr *CSOffsetExpr;
  165. uint64_t ID;
  166. LocationVec Locations;
  167. LiveOutVec LiveOuts;
  168. CallsiteInfo() : CSOffsetExpr(nullptr), ID(0) {}
  169. CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
  170. LocationVec &&Locations, LiveOutVec &&LiveOuts)
  171. : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
  172. LiveOuts(std::move(LiveOuts)) {}
  173. };
  174. typedef std::vector<CallsiteInfo> CallsiteInfoList;
  175. AsmPrinter &AP;
  176. CallsiteInfoList CSInfos;
  177. ConstantPool ConstPool;
  178. FnStackSizeMap FnStackSize;
  179. MachineInstr::const_mop_iterator
  180. parseOperand(MachineInstr::const_mop_iterator MOI,
  181. MachineInstr::const_mop_iterator MOE, LocationVec &Locs,
  182. LiveOutVec &LiveOuts) const;
  183. /// \brief Create a live-out register record for the given register @p Reg.
  184. LiveOutReg createLiveOutReg(unsigned Reg,
  185. const TargetRegisterInfo *TRI) const;
  186. /// \brief Parse the register live-out mask and return a vector of live-out
  187. /// registers that need to be recorded in the stackmap.
  188. LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const;
  189. /// This should be called by the MC lowering code _immediately_ before
  190. /// lowering the MI to an MCInst. It records where the operands for the
  191. /// instruction are stored, and outputs a label to record the offset of
  192. /// the call from the start of the text section. In special cases (e.g. AnyReg
  193. /// calling convention) the return register is also recorded if requested.
  194. void recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
  195. MachineInstr::const_mop_iterator MOI,
  196. MachineInstr::const_mop_iterator MOE,
  197. bool recordResult = false);
  198. /// \brief Emit the stackmap header.
  199. void emitStackmapHeader(MCStreamer &OS);
  200. /// \brief Emit the function frame record for each function.
  201. void emitFunctionFrameRecords(MCStreamer &OS);
  202. /// \brief Emit the constant pool.
  203. void emitConstantPoolEntries(MCStreamer &OS);
  204. /// \brief Emit the callsite info for each stackmap/patchpoint intrinsic call.
  205. void emitCallsiteEntries(MCStreamer &OS);
  206. void print(raw_ostream &OS);
  207. void debug() { print(dbgs()); }
  208. };
  209. }
  210. #endif