Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  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"
  14. #include "llvm/CodeGen/MachineInstr.h"
  15. #include "llvm/IR/CallingConv.h"
  16. #include "llvm/Support/Debug.h"
  17. #include <algorithm>
  18. #include <cassert>
  19. #include <cstdint>
  20. #include <vector>
  21.  
  22. namespace llvm {
  23.  
  24. class AsmPrinter;
  25. class MCSymbol;
  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...
  35. class StackMapOpers {
  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.
  50.   uint32_t getNumPatchBytes() const {
  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.
  76. class PatchPointOpers {
  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.
  104.   uint32_t getNumPatchBytes() const {
  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
  114.   CallingConv::ID getCallingConv() const {
  115.     return getMetaOper(CCPos).getImm();
  116.   }
  117.  
  118.   unsigned getArgIdx() const { return getMetaIdx() + MetaEnd; }
  119.  
  120.   /// Return the number of call arguments
  121.   uint32_t getNumCallArgs() const {
  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. ///   <StackMaps::ConstantOp>, <num gc pointer args>, [gc pointer args...],
  152. ///   <StackMaps::ConstantOp>, <num gc allocas>, [gc allocas args...],
  153. ///   <StackMaps::ConstantOp>, <num  entries in gc map>, [base/derived pairs]
  154. ///   base/derived pairs in gc map are logical indices into <gc pointer args>
  155. ///   section.
  156. ///   All gc pointers assigned to VRegs produce new value (in form of MI Def
  157. ///   operand) and are tied to it.
  158. class StatepointOpers {
  159.   // TODO:: we should change the STATEPOINT representation so that CC and
  160.   // Flags should be part of meta operands, with args and deopt operands, and
  161.   // gc operands all prefixed by their length and a type code. This would be
  162.   // much more consistent.
  163.  
  164.   // These values are absolute offsets into the operands of the statepoint
  165.   // instruction.
  166.   enum { IDPos, NBytesPos, NCallArgsPos, CallTargetPos, MetaEnd };
  167.  
  168.   // These values are relative offsets from the start of the statepoint meta
  169.   // arguments (i.e. the end of the call arguments).
  170.   enum { CCOffset = 1, FlagsOffset = 3, NumDeoptOperandsOffset = 5 };
  171.  
  172. public:
  173.   explicit StatepointOpers(const MachineInstr *MI) : MI(MI) {
  174.     NumDefs = MI->getNumDefs();
  175.   }
  176.  
  177.   /// Get index of statepoint ID operand.
  178.   unsigned getIDPos() const { return NumDefs + IDPos; }
  179.  
  180.   /// Get index of Num Patch Bytes operand.
  181.   unsigned getNBytesPos() const { return NumDefs + NBytesPos; }
  182.  
  183.   /// Get index of Num Call Arguments operand.
  184.   unsigned getNCallArgsPos() const { return NumDefs + NCallArgsPos; }
  185.  
  186.   /// Get starting index of non call related arguments
  187.   /// (calling convention, statepoint flags, vm state and gc state).
  188.   unsigned getVarIdx() const {
  189.     return MI->getOperand(NumDefs + NCallArgsPos).getImm() + MetaEnd + NumDefs;
  190.   }
  191.  
  192.   /// Get index of Calling Convention operand.
  193.   unsigned getCCIdx() const { return getVarIdx() + CCOffset; }
  194.  
  195.   /// Get index of Flags operand.
  196.   unsigned getFlagsIdx() const { return getVarIdx() + FlagsOffset; }
  197.  
  198.   /// Get index of Number Deopt Arguments operand.
  199.   unsigned getNumDeoptArgsIdx() const {
  200.     return getVarIdx() + NumDeoptOperandsOffset;
  201.   }
  202.  
  203.   /// Return the ID for the given statepoint.
  204.   uint64_t getID() const { return MI->getOperand(NumDefs + IDPos).getImm(); }
  205.  
  206.   /// Return the number of patchable bytes the given statepoint should emit.
  207.   uint32_t getNumPatchBytes() const {
  208.     return MI->getOperand(NumDefs + NBytesPos).getImm();
  209.   }
  210.  
  211.   /// Return the target of the underlying call.
  212.   const MachineOperand &getCallTarget() const {
  213.     return MI->getOperand(NumDefs + CallTargetPos);
  214.   }
  215.  
  216.   /// Return the calling convention.
  217.   CallingConv::ID getCallingConv() const {
  218.     return MI->getOperand(getCCIdx()).getImm();
  219.   }
  220.  
  221.   /// Return the statepoint flags.
  222.   uint64_t getFlags() const { return MI->getOperand(getFlagsIdx()).getImm(); }
  223.  
  224.   uint64_t getNumDeoptArgs() const {
  225.     return MI->getOperand(getNumDeoptArgsIdx()).getImm();
  226.   }
  227.  
  228.   /// Get index of number of gc map entries.
  229.   unsigned getNumGcMapEntriesIdx();
  230.  
  231.   /// Get index of number of gc allocas.
  232.   unsigned getNumAllocaIdx();
  233.  
  234.   /// Get index of number of GC pointers.
  235.   unsigned getNumGCPtrIdx();
  236.  
  237.   /// Get index of first GC pointer operand of -1 if there are none.
  238.   int getFirstGCPtrIdx();
  239.  
  240.   /// Get vector of base/derived pairs from statepoint.
  241.   /// Elements are indices into GC Pointer operand list (logical).
  242.   /// Returns number of elements in GCMap.
  243.   unsigned
  244.   getGCPointerMap(SmallVectorImpl<std::pair<unsigned, unsigned>> &GCMap);
  245.  
  246.   /// Return true if Reg is used only in operands which can be folded to
  247.   /// stack usage.
  248.   bool isFoldableReg(Register Reg) const;
  249.  
  250.   /// Return true if Reg is used only in operands of MI which can be folded to
  251.   /// stack usage and MI is a statepoint instruction.
  252.   static bool isFoldableReg(const MachineInstr *MI, Register Reg);
  253.  
  254. private:
  255.   const MachineInstr *MI;
  256.   unsigned NumDefs;
  257. };
  258.  
  259. class StackMaps {
  260. public:
  261.   struct Location {
  262.     enum LocationType {
  263.       Unprocessed,
  264.       Register,
  265.       Direct,
  266.       Indirect,
  267.       Constant,
  268.       ConstantIndex
  269.     };
  270.     LocationType Type = Unprocessed;
  271.     unsigned Size = 0;
  272.     unsigned Reg = 0;
  273.     int64_t Offset = 0;
  274.  
  275.     Location() = default;
  276.     Location(LocationType Type, unsigned Size, unsigned Reg, int64_t Offset)
  277.         : Type(Type), Size(Size), Reg(Reg), Offset(Offset) {}
  278.   };
  279.  
  280.   struct LiveOutReg {
  281.     unsigned short Reg = 0;
  282.     unsigned short DwarfRegNum = 0;
  283.     unsigned short Size = 0;
  284.  
  285.     LiveOutReg() = default;
  286.     LiveOutReg(unsigned short Reg, unsigned short DwarfRegNum,
  287.                unsigned short Size)
  288.         : Reg(Reg), DwarfRegNum(DwarfRegNum), Size(Size) {}
  289.   };
  290.  
  291.   // OpTypes are used to encode information about the following logical
  292.   // operand (which may consist of several MachineOperands) for the
  293.   // OpParser.
  294.   using OpType = enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp };
  295.  
  296.   StackMaps(AsmPrinter &AP);
  297.  
  298.   /// Get index of next meta operand.
  299.   /// Similar to parseOperand, but does not actually parses operand meaning.
  300.   static unsigned getNextMetaArgIdx(const MachineInstr *MI, unsigned CurIdx);
  301.  
  302.   void reset() {
  303.     CSInfos.clear();
  304.     ConstPool.clear();
  305.     FnInfos.clear();
  306.   }
  307.  
  308.   using LocationVec = SmallVector<Location, 8>;
  309.   using LiveOutVec = SmallVector<LiveOutReg, 8>;
  310.   using ConstantPool = MapVector<uint64_t, uint64_t>;
  311.  
  312.   struct FunctionInfo {
  313.     uint64_t StackSize = 0;
  314.     uint64_t RecordCount = 1;
  315.  
  316.     FunctionInfo() = default;
  317.     explicit FunctionInfo(uint64_t StackSize) : StackSize(StackSize) {}
  318.   };
  319.  
  320.   struct CallsiteInfo {
  321.     const MCExpr *CSOffsetExpr = nullptr;
  322.     uint64_t ID = 0;
  323.     LocationVec Locations;
  324.     LiveOutVec LiveOuts;
  325.  
  326.     CallsiteInfo() = default;
  327.     CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID,
  328.                  LocationVec &&Locations, LiveOutVec &&LiveOuts)
  329.         : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(std::move(Locations)),
  330.           LiveOuts(std::move(LiveOuts)) {}
  331.   };
  332.  
  333.   using FnInfoMap = MapVector<const MCSymbol *, FunctionInfo>;
  334.   using CallsiteInfoList = std::vector<CallsiteInfo>;
  335.  
  336.   /// Generate a stackmap record for a stackmap instruction.
  337.   ///
  338.   /// MI must be a raw STACKMAP, not a PATCHPOINT.
  339.   void recordStackMap(const MCSymbol &L,
  340.                       const MachineInstr &MI);
  341.  
  342.   /// Generate a stackmap record for a patchpoint instruction.
  343.   void recordPatchPoint(const MCSymbol &L,
  344.                         const MachineInstr &MI);
  345.  
  346.   /// Generate a stackmap record for a statepoint instruction.
  347.   void recordStatepoint(const MCSymbol &L,
  348.                         const MachineInstr &MI);
  349.  
  350.   /// If there is any stack map data, create a stack map section and serialize
  351.   /// the map info into it. This clears the stack map data structures
  352.   /// afterwards.
  353.   void serializeToStackMapSection();
  354.  
  355.   /// Get call site info.
  356.   CallsiteInfoList &getCSInfos() { return CSInfos; }
  357.  
  358.   /// Get function info.
  359.   FnInfoMap &getFnInfos() { return FnInfos; }
  360.  
  361. private:
  362.   static const char *WSMP;
  363.  
  364.   AsmPrinter &AP;
  365.   CallsiteInfoList CSInfos;
  366.   ConstantPool ConstPool;
  367.   FnInfoMap FnInfos;
  368.  
  369.   MachineInstr::const_mop_iterator
  370.   parseOperand(MachineInstr::const_mop_iterator MOI,
  371.                MachineInstr::const_mop_iterator MOE, LocationVec &Locs,
  372.                LiveOutVec &LiveOuts) const;
  373.  
  374.   /// Specialized parser of statepoint operands.
  375.   /// They do not directly correspond to StackMap record entries.
  376.   void parseStatepointOpers(const MachineInstr &MI,
  377.                             MachineInstr::const_mop_iterator MOI,
  378.                             MachineInstr::const_mop_iterator MOE,
  379.                             LocationVec &Locations, LiveOutVec &LiveOuts);
  380.  
  381.   /// Create a live-out register record for the given register @p Reg.
  382.   LiveOutReg createLiveOutReg(unsigned Reg,
  383.                               const TargetRegisterInfo *TRI) const;
  384.  
  385.   /// Parse the register live-out mask and return a vector of live-out
  386.   /// registers that need to be recorded in the stackmap.
  387.   LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const;
  388.  
  389.   /// Record the locations of the operands of the provided instruction in a
  390.   /// record keyed by the provided label.  For instructions w/AnyReg calling
  391.   /// convention the return register is also recorded if requested.  For
  392.   /// STACKMAP, and PATCHPOINT the label is expected to immediately *preceed*
  393.   /// lowering of the MI to MCInsts.  For STATEPOINT, it expected to
  394.   /// immediately *follow*.  It's not clear this difference was intentional,
  395.   /// but it exists today.  
  396.   void recordStackMapOpers(const MCSymbol &L,
  397.                            const MachineInstr &MI, uint64_t ID,
  398.                            MachineInstr::const_mop_iterator MOI,
  399.                            MachineInstr::const_mop_iterator MOE,
  400.                            bool recordResult = false);
  401.  
  402.   /// Emit the stackmap header.
  403.   void emitStackmapHeader(MCStreamer &OS);
  404.  
  405.   /// Emit the function frame record for each function.
  406.   void emitFunctionFrameRecords(MCStreamer &OS);
  407.  
  408.   /// Emit the constant pool.
  409.   void emitConstantPoolEntries(MCStreamer &OS);
  410.  
  411.   /// Emit the callsite info for each stackmap/patchpoint intrinsic call.
  412.   void emitCallsiteEntries(MCStreamer &OS);
  413.  
  414.   void print(raw_ostream &OS);
  415.   void debug() { print(dbgs()); }
  416. };
  417.  
  418. } // end namespace llvm
  419.  
  420. #endif // LLVM_CODEGEN_STACKMAPS_H
  421.