13d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick//===------------------- StackMaps.h - StackMaps ----------------*- C++ -*-===// 236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 33d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// 43d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// The LLVM Compiler Infrastructure 53d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// 63d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// This file is distributed under the University of Illinois Open Source 73d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// License. See LICENSE.TXT for details. 83d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// 93d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick//===----------------------------------------------------------------------===// 103d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 113d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#ifndef LLVM_STACKMAPS 123d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#define LLVM_STACKMAPS 133d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/ADT/MapVector.h" 153d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/ADT/SmallVector.h" 163d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/CodeGen/MachineInstr.h" 173d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include <map> 183d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include <vector> 193d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 203d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Tricknamespace llvm { 213d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 223d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trickclass AsmPrinter; 233d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trickclass MCExpr; 24dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesclass MCStreamer; 253d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 2672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// \brief MI-level patchpoint operands. 2772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// 2872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// MI patchpoint operations take the form: 2972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ... 3072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// 31c00090b16b2b35f2d042d965945c4246d13321b5Bill Wendling/// IR patchpoint intrinsics do not have the <cc> operand because calling 32c00090b16b2b35f2d042d965945c4246d13321b5Bill Wendling/// convention is part of the subclass data. 33c00090b16b2b35f2d042d965945c4246d13321b5Bill Wendling/// 34c00090b16b2b35f2d042d965945c4246d13321b5Bill Wendling/// SD patchpoint nodes do not have a def operand because it is part of the 35c00090b16b2b35f2d042d965945c4246d13321b5Bill Wendling/// SDValue. 3672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// 3772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// Patchpoints following the anyregcc convention are handled specially. For 3872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// these, the stack map also records the location of the return value and 3972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling/// arguments. 4072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendlingclass PatchPointOpers { 4172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendlingpublic: 4272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// Enumerate the meta operands. 4372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling enum { IDPos, NBytesPos, TargetPos, NArgPos, CCPos, MetaEnd }; 4472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendlingprivate: 4572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling const MachineInstr *MI; 4672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling bool HasDef; 4772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling bool IsAnyReg; 4872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendlingpublic: 4972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling explicit PatchPointOpers(const MachineInstr *MI); 5072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 5172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling bool isAnyReg() const { return IsAnyReg; } 5272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling bool hasDef() const { return HasDef; } 5372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 5472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned getMetaIdx(unsigned Pos = 0) const { 5572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling assert(Pos < MetaEnd && "Meta operand index out of range."); 5672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling return (HasDef ? 1 : 0) + Pos; 5772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling } 5872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 5972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling const MachineOperand &getMetaOper(unsigned Pos) { 6072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling return MI->getOperand(getMetaIdx(Pos)); 6172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling } 6272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 6372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned getArgIdx() const { return getMetaIdx() + MetaEnd; } 6472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 6572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// Get the operand index of the variable list of non-argument operands. 6672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// These hold the "live state". 6772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned getVarIdx() const { 6872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling return getMetaIdx() + MetaEnd 6972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling + MI->getOperand(getMetaIdx(NArgPos)).getImm(); 7072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling } 7172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 7272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// Get the index at which stack map locations will be recorded. 7372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// Arguments are not recorded unless the anyregcc convention is used. 7472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned getStackMapStartIdx() const { 7572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling if (IsAnyReg) 7672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling return getArgIdx(); 7772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling return getVarIdx(); 7872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling } 7972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 8072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// \brief Get the next scratch register operand index. 8172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned getNextScratchIdx(unsigned StartIdx = 0) const; 8272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling}; 8372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 843d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trickclass StackMaps { 853d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trickpublic: 863d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick struct Location { 873d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick enum LocationType { Unprocessed, Register, Direct, Indirect, Constant, 883d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick ConstantIndex }; 893d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick LocationType LocType; 90bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick unsigned Size; 913d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick unsigned Reg; 923d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick int64_t Offset; 93bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick Location() : LocType(Unprocessed), Size(0), Reg(0), Offset(0) {} 94bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick Location(LocationType LocType, unsigned Size, unsigned Reg, int64_t Offset) 95bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick : LocType(LocType), Size(Size), Reg(Reg), Offset(Offset) {} 963d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick }; 973d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 9836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines struct LiveOutReg { 9936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned short Reg; 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned short RegNo; 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned short Size; 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOutReg() : Reg(0), RegNo(0), Size(0) {} 10436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOutReg(unsigned short Reg, unsigned short RegNo, unsigned short Size) 10536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : Reg(Reg), RegNo(RegNo), Size(Size) {} 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void MarkInvalid() { Reg = 0; } 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Only sort by the dwarf register number. 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines bool operator< (const LiveOutReg &LO) const { return RegNo < LO.RegNo; } 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines static bool IsInvalid(const LiveOutReg &LO) { return LO.Reg == 0; } 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines }; 1133d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1143d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // OpTypes are used to encode information about the following logical 1153d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // operand (which may consist of several MachineOperands) for the 1163d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // OpParser. 1173d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick typedef enum { DirectMemRefOp, IndirectMemRefOp, ConstantOp } OpType; 1183d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 119dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines StackMaps(AsmPrinter &AP); 1203d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 12172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// \brief Generate a stackmap record for a stackmap instruction. 12272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// 12372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// MI must be a raw STACKMAP, not a PATCHPOINT. 12472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling void recordStackMap(const MachineInstr &MI); 12572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 12672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// \brief Generate a stackmap record for a patchpoint instruction. 12772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling void recordPatchPoint(const MachineInstr &MI); 1283d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1293d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick /// If there is any stack map data, create a stack map section and serialize 1303d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick /// the map info into it. This clears the stack map data structures 1313d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick /// afterwards. 1323d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick void serializeToStackMapSection(); 1333d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1343d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trickprivate: 135dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines static const char *WSMP; 136dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 1373d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick typedef SmallVector<Location, 8> LocationVec; 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef SmallVector<LiveOutReg, 8> LiveOutVec; 139dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines typedef MapVector<int64_t, int64_t> ConstantPool; 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines typedef MapVector<const MCSymbol *, uint64_t> FnStackSizeMap; 1413d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1423d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick struct CallsiteInfo { 1433d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick const MCExpr *CSOffsetExpr; 14436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines uint64_t ID; 1453d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick LocationVec Locations; 14636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOutVec LiveOuts; 147dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines CallsiteInfo() : CSOffsetExpr(nullptr), ID(0) {} 14836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines CallsiteInfo(const MCExpr *CSOffsetExpr, uint64_t ID, 14936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LocationVec &Locations, LiveOutVec &LiveOuts) 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines : CSOffsetExpr(CSOffsetExpr), ID(ID), Locations(Locations), 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOuts(LiveOuts) {} 1523d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick }; 1533d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1543d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick typedef std::vector<CallsiteInfo> CallsiteInfoList; 1553d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1563d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick AsmPrinter &AP; 1573d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick CallsiteInfoList CSInfos; 1583d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick ConstantPool ConstPool; 15936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FnStackSizeMap FnStackSize; 16036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 16136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineInstr::const_mop_iterator 16236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines parseOperand(MachineInstr::const_mop_iterator MOI, 16336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MachineInstr::const_mop_iterator MOE, 16436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LocationVec &Locs, LiveOutVec &LiveOuts) const; 16536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Create a live-out register record for the given register @p Reg. 16736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOutReg createLiveOutReg(unsigned Reg, 16836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const TargetRegisterInfo *TRI) const; 16936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 17036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// \brief Parse the register live-out mask and return a vector of live-out 17136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines /// registers that need to be recorded in the stackmap. 17236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOutVec parseRegisterLiveOutMask(const uint32_t *Mask) const; 17372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 17472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// This should be called by the MC lowering code _immediately_ before 17572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// lowering the MI to an MCInst. It records where the operands for the 17672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// instruction are stored, and outputs a label to record the offset of 17772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// the call from the start of the text section. In special cases (e.g. AnyReg 17872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling /// calling convention) the return register is also recorded if requested. 17936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines void recordStackMapOpers(const MachineInstr &MI, uint64_t ID, 18072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MachineInstr::const_mop_iterator MOI, 18172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MachineInstr::const_mop_iterator MOE, 18272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling bool recordResult = false); 183dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 184dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// \brief Emit the stackmap header. 185dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitStackmapHeader(MCStreamer &OS); 186dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 187dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// \brief Emit the function frame record for each function. 188dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitFunctionFrameRecords(MCStreamer &OS); 189dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 190dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// \brief Emit the constant pool. 191dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitConstantPoolEntries(MCStreamer &OS); 192dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 193dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines /// \brief Emit the callsite info for each stackmap/patchpoint intrinsic call. 194dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines void emitCallsiteEntries(MCStreamer &OS, const TargetRegisterInfo *TRI); 1953d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick}; 1963d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1973d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick} 1983d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 1993d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#endif // LLVM_STACKMAPS 200