13d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick//===---------------------------- StackMaps.cpp ---------------------------===// 23d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// 33d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// The LLVM Compiler Infrastructure 43d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// 53d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// This file is distributed under the University of Illinois Open Source 63d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// License. See LICENSE.TXT for details. 73d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick// 83d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick//===----------------------------------------------------------------------===// 93d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 103d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/CodeGen/StackMaps.h" 113d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/CodeGen/AsmPrinter.h" 1236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFrameInfo.h" 1336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/CodeGen/MachineFunction.h" 143d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/CodeGen/MachineInstr.h" 1536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/IR/DataLayout.h" 163d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/MC/MCContext.h" 173d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/MC/MCExpr.h" 18de753f48535fb19cdd967af3bc3a743fa2a675ffLang Hames#include "llvm/MC/MCObjectFileInfo.h" 193d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/MC/MCSectionMachO.h" 203d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/MC/MCStreamer.h" 21dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#include "llvm/Support/CommandLine.h" 223d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/Target/TargetMachine.h" 2336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines#include "llvm/Target/TargetOpcodes.h" 243d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include "llvm/Target/TargetRegisterInfo.h" 2537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines#include "llvm/Target/TargetSubtargetInfo.h" 263d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick#include <iterator> 273d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 283d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trickusing namespace llvm; 293d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 30dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines#define DEBUG_TYPE "stackmaps" 31dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 32f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainarstatic cl::opt<int> StackMapVersion( 33f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar "stackmap-version", cl::init(1), 34f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar cl::desc("Specify the stackmap encoding version (default = 1)")); 35dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 36dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesconst char *StackMaps::WSMP = "Stack Maps: "; 37dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 3836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesPatchPointOpers::PatchPointOpers(const MachineInstr *MI) 39f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar : MI(MI), HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() && 40f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar !MI->getOperand(0).isImplicit()), 41f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() == 42f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar CallingConv::AnyReg) { 4372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling#ifndef NDEBUG 4472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned CheckStartIdx = 0, e = MI->getNumOperands(); 4572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() && 4672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MI->getOperand(CheckStartIdx).isDef() && 4772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling !MI->getOperand(CheckStartIdx).isImplicit()) 4872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling ++CheckStartIdx; 4972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 5072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling assert(getMetaIdx() == CheckStartIdx && 5136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Unexpected additional definition in Patchpoint intrinsic."); 5272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling#endif 5372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling} 5472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 5572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendlingunsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const { 5672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling if (!StartIdx) 5772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling StartIdx = getVarIdx(); 5872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 5972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling // Find the next scratch register (implicit def and early clobber) 6072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned ScratchIdx = StartIdx, e = MI->getNumOperands(); 6172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling while (ScratchIdx < e && 6272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling !(MI->getOperand(ScratchIdx).isReg() && 6372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MI->getOperand(ScratchIdx).isDef() && 6472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MI->getOperand(ScratchIdx).isImplicit() && 6572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MI->getOperand(ScratchIdx).isEarlyClobber())) 6672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling ++ScratchIdx; 6772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 6872ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling assert(ScratchIdx != e && "No scratch register available"); 6972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling return ScratchIdx; 7072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling} 7172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 72dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen HinesStackMaps::StackMaps(AsmPrinter &AP) : AP(AP) { 73dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (StackMapVersion != 1) 74dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines llvm_unreachable("Unsupported stackmap version!"); 75dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 76dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar/// Go up the super-register chain until we hit a valid dwarf register number. 784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarstatic unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) { 79f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar int RegNum = TRI->getDwarfRegNum(Reg, false); 80f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (MCSuperRegIterator SR(Reg, TRI); SR.isValid() && RegNum < 0; ++SR) 81f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar RegNum = TRI->getDwarfRegNum(*SR, false); 824c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 83f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(RegNum >= 0 && "Invalid Dwarf register number."); 84f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return (unsigned)RegNum; 854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar} 864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 8736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesMachineInstr::const_mop_iterator 8836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesStackMaps::parseOperand(MachineInstr::const_mop_iterator MOI, 89f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MachineInstr::const_mop_iterator MOE, LocationVec &Locs, 90f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LiveOutVec &LiveOuts) const { 914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const TargetRegisterInfo *TRI = AP.MF->getSubtarget().getRegisterInfo(); 9236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MOI->isImm()) { 9336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines switch (MOI->getImm()) { 94f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar default: 95f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar llvm_unreachable("Unrecognized operand type."); 9636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackMaps::DirectMemRefOp: { 97f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &DL = AP.MF->getDataLayout(); 98f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 99f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Size = DL.getPointerSizeInBits(); 10036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert((Size % 8) == 0 && "Need pointer size in bytes."); 10136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines Size /= 8; 10236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Reg = (++MOI)->getReg(); 10336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t Imm = (++MOI)->getImm(); 104f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Locs.emplace_back(StackMaps::Location::Direct, Size, 105f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar getDwarfRegNum(Reg, TRI), Imm); 10636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 10736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 10836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackMaps::IndirectMemRefOp: { 10936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t Size = (++MOI)->getImm(); 11036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Size > 0 && "Need a valid size for indirect memory locations."); 11136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Reg = (++MOI)->getReg(); 11236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t Imm = (++MOI)->getImm(); 113f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Locs.emplace_back(StackMaps::Location::Indirect, Size, 114f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar getDwarfRegNum(Reg, TRI), Imm); 11536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 11636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 11736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines case StackMaps::ConstantOp: { 11836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines ++MOI; 11936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(MOI->isImm() && "Expected constant operand."); 12036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines int64_t Imm = MOI->getImm(); 121f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Locs.emplace_back(Location::Constant, sizeof(int64_t), 0, Imm); 12236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 12336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ++MOI; 12636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 12736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 12836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The physical register number will ultimately be encoded as a DWARF regno. 12936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // The stack map also records the size of a spill slot that can hold the 13036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // register content. (The runtime can track the actual size of the data type 13136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // if it needs to.) 13236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MOI->isReg()) { 13336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip implicit registers (this includes our scratch registers) 13436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MOI->isImplicit()) 13536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ++MOI; 13636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 13736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(TargetRegisterInfo::isPhysicalRegister(MOI->getReg()) && 13836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines "Virtreg operands should have been rewritten before now."); 1394c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const TargetRegisterClass *RC = TRI->getMinimalPhysRegClass(MOI->getReg()); 14036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(!MOI->getSubReg() && "Physical subreg still around."); 1414c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 1424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar unsigned Offset = 0; 143f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DwarfRegNum = getDwarfRegNum(MOI->getReg(), TRI); 144f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned LLVMRegNum = TRI->getLLVMRegNum(DwarfRegNum, false); 145f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned SubRegIdx = TRI->getSubRegIndex(LLVMRegNum, MOI->getReg()); 1464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (SubRegIdx) 1474c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar Offset = TRI->getSubRegIdxOffset(SubRegIdx); 1484c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 149f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Locs.emplace_back(Location::Register, RC->getSize(), DwarfRegNum, Offset); 15036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ++MOI; 15136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 15236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (MOI->isRegLiveOut()) 15436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut()); 15536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 15636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return ++MOI; 15736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 15836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1594c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid StackMaps::print(raw_ostream &OS) { 1604c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const TargetRegisterInfo *TRI = 1614c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar AP.MF ? AP.MF->getSubtarget().getRegisterInfo() : nullptr; 1624c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << WSMP << "callsites:\n"; 1634c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &CSI : CSInfos) { 1644c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const LocationVec &CSLocs = CSI.Locations; 1654c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const LiveOutVec &LiveOuts = CSI.LiveOuts; 16636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 1674c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << WSMP << "callsite " << CSI.ID << "\n"; 1684c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << WSMP << " has " << CSLocs.size() << " locations\n"; 1694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 170f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned Idx = 0; 1714c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &Loc : CSLocs) { 172f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << WSMP << "\t\tLoc " << Idx << ": "; 173f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar switch (Loc.Type) { 1744c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case Location::Unprocessed: 1754c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << "<Unprocessed operand>"; 1764c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 1774c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case Location::Register: 1784c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << "Register "; 179f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (TRI) 180f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << TRI->getName(Loc.Reg); 181f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar else 182f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << Loc.Reg; 1834c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 1844c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case Location::Direct: 1854c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << "Direct "; 1864c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (TRI) 1874c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << TRI->getName(Loc.Reg); 1884c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 1894c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << Loc.Reg; 1904c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (Loc.Offset) 1914c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << " + " << Loc.Offset; 1924c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 1934c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case Location::Indirect: 1944c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << "Indirect "; 1954c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (TRI) 1964c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << TRI->getName(Loc.Reg); 1974c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 1984c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << Loc.Reg; 1994c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << "+" << Loc.Offset; 2004c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 2014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case Location::Constant: 2024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << "Constant " << Loc.Offset; 2034c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 2044c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar case Location::ConstantIndex: 2054c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << "Constant Index " << Loc.Offset; 2064c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar break; 2074c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 208f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << "\t[encoding: .byte " << Loc.Type << ", .byte " << Loc.Size 2094c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar << ", .short " << Loc.Reg << ", .int " << Loc.Offset << "]\n"; 210f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Idx++; 2114c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 2124c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 213f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << WSMP << "\thas " << LiveOuts.size() << " live-out registers\n"; 2144c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar 215f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Idx = 0; 2164c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar for (const auto &LO : LiveOuts) { 217f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << WSMP << "\t\tLO " << Idx << ": "; 2184c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar if (TRI) 2194c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << TRI->getName(LO.Reg); 2204c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar else 2214c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS << LO.Reg; 222f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS << "\t[encoding: .short " << LO.DwarfRegNum << ", .byte 0, .byte " 2234c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar << LO.Size << "]\n"; 224f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Idx++; 2254c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 2264c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar } 22736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 22836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 22936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Create a live-out register record for the given register Reg. 23036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesStackMaps::LiveOutReg 23136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesStackMaps::createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const { 232f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar unsigned DwarfRegNum = getDwarfRegNum(Reg, TRI); 23336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize(); 234f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return LiveOutReg(Reg, DwarfRegNum, Size); 23536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 23636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 23736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Parse the register live-out mask and return a vector of live-out registers 23836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// that need to be recorded in the stackmap. 23936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesStackMaps::LiveOutVec 24036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen HinesStackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const { 24136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(Mask && "No register mask specified"); 2424c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar const TargetRegisterInfo *TRI = AP.MF->getSubtarget().getRegisterInfo(); 24336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOutVec LiveOuts; 24436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 24536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Create a LiveOutReg for each bit that is set in the register mask. 24636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines for (unsigned Reg = 0, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg) 24736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if ((Mask[Reg / 32] >> Reg % 32) & 1) 24836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOuts.push_back(createLiveOutReg(Reg, TRI)); 24936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 25036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // We don't need to keep track of a register if its super-register is already 25136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // in the list. Merge entries that refer to the same dwarf register and use 25236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // the maximum size that needs to be spilled. 253f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 254f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::sort(LiveOuts.begin(), LiveOuts.end(), 255f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar [](const LiveOutReg &LHS, const LiveOutReg &RHS) { 256f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar // Only sort by the dwarf register number. 257f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar return LHS.DwarfRegNum < RHS.DwarfRegNum; 258f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar }); 259f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 260f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto I = LiveOuts.begin(), E = LiveOuts.end(); I != E; ++I) { 261f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto II = std::next(I); II != E; ++II) { 262f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (I->DwarfRegNum != II->DwarfRegNum) { 26336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Skip all the now invalid entries. 26436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I = --II; 26536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines break; 26636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 26736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I->Size = std::max(I->Size, II->Size); 26836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (TRI->isSuperRegister(I->Reg, II->Reg)) 26936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines I->Reg = II->Reg; 270f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar II->Reg = 0; // mark for deletion. 27136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 27236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 273f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 274f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LiveOuts.erase( 275f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar std::remove_if(LiveOuts.begin(), LiveOuts.end(), 276f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar [](const LiveOutReg &LO) { return LO.Reg == 0; }), 277f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LiveOuts.end()); 278f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar 27936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines return LiveOuts; 28036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines} 28136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 28236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hinesvoid StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID, 28372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MachineInstr::const_mop_iterator MOI, 28472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling MachineInstr::const_mop_iterator MOE, 28572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling bool recordResult) { 2863d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 2876948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCContext &OutContext = AP.OutStreamer->getContext(); 2886948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSymbol *MILabel = OutContext.createTempSymbol(); 2896948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar AP.OutStreamer->EmitLabel(MILabel); 2903d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 29136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LocationVec Locations; 29236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines LiveOutVec LiveOuts; 2933d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 294623d2e618f4e672c47edff9ec63ed6d733ac81d3Juergen Ributzka if (recordResult) { 29536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(PatchPointOpers(&MI).hasDef() && "Stackmap has no return value."); 296f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar parseOperand(MI.operands_begin(), std::next(MI.operands_begin()), Locations, 297f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar LiveOuts); 298623d2e618f4e672c47edff9ec63ed6d733ac81d3Juergen Ributzka } 299623d2e618f4e672c47edff9ec63ed6d733ac81d3Juergen Ributzka 30036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Parse operands. 3013d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick while (MOI != MOE) { 30236b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MOI = parseOperand(MOI, MOE, Locations, LiveOuts); 30336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 3043d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 30536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Move large constants into the constant pool. 306f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (auto &Loc : Locations) { 30736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Constants are encoded as sign-extended integers. 30836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // -1 is directly encoded as .long 0xFFFFFFFF with no constant pool. 309f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar if (Loc.Type == Location::Constant && !isInt<32>(Loc.Offset)) { 310f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Loc.Type = Location::ConstantIndex; 31137ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // ConstPool is intentionally a MapVector of 'uint64_t's (as 31237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // opposed to 'int64_t's). We should never be in a situation 31337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // where we have to insert either the tombstone or the empty 31437ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // keys into a map, and for a DenseMap<uint64_t, T> these are 31537ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // (uint64_t)0 and (uint64_t)-1. They can be and are 31637ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines // represented using 32 bit integers. 317f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert((uint64_t)Loc.Offset != DenseMapInfo<uint64_t>::getEmptyKey() && 318f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar (uint64_t)Loc.Offset != 319f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar DenseMapInfo<uint64_t>::getTombstoneKey() && 32037ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines "empty and tombstone keys should fit in 32 bits!"); 321f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto Result = ConstPool.insert(std::make_pair(Loc.Offset, Loc.Offset)); 322f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar Loc.Offset = Result.first - ConstPool.begin(); 3233d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick } 3243d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick } 3253d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 32636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Create an expression to calculate the offset of the callsite from function 32736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // entry. 3286948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar const MCExpr *CSOffsetExpr = MCBinaryExpr::createSub( 329f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSymbolRefExpr::create(MILabel, OutContext), 330f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext); 3313d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 33237ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations), 33337ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines std::move(LiveOuts)); 33472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 33536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Record the stack size of the current function. 33636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines const MachineFrameInfo *MFI = AP.MF->getFrameInfo(); 33737ed9c199ca639565f6ce88105f9e39e898d82d0Stephen Hines const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo(); 338f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar bool HasDynamicFrameSize = 339f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(*(AP.MF)); 34036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines FnStackSize[AP.CurrentFnSym] = 341f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar HasDynamicFrameSize ? UINT64_MAX : MFI->getStackSize(); 34272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling} 34372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 34472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendlingvoid StackMaps::recordStackMap(const MachineInstr &MI) { 34536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap"); 34672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 34772ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling int64_t ID = MI.getOperand(0).getImm(); 34836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines recordStackMapOpers(MI, ID, std::next(MI.operands_begin(), 2), 34936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines MI.operands_end()); 35072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling} 35172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 35272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendlingvoid StackMaps::recordPatchPoint(const MachineInstr &MI) { 35336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint"); 35472ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 35572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling PatchPointOpers opers(&MI); 35672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm(); 35736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 358f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto MOI = std::next(MI.operands_begin(), opers.getStackMapStartIdx()); 35936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines recordStackMapOpers(MI, ID, MOI, MI.operands_end(), 36072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling opers.isAnyReg() && opers.hasDef()); 36172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 36272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling#ifndef NDEBUG 36372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling // verify anyregcc 364f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar auto &Locations = CSInfos.back().Locations; 36572ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling if (opers.isAnyReg()) { 36672ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling unsigned NArgs = opers.getMetaOper(PatchPointOpers::NArgPos).getImm(); 367f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (unsigned i = 0, e = (opers.hasDef() ? NArgs + 1 : NArgs); i != e; ++i) 368f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(Locations[i].Type == Location::Register && 36972ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling "anyreg arg must be in reg."); 37072ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling } 37172ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling#endif 37272ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling} 373ebe69fe11e48d322045d5949c83283927a0d790bStephen Hinesvoid StackMaps::recordStatepoint(const MachineInstr &MI) { 374f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar assert(MI.getOpcode() == TargetOpcode::STATEPOINT && "expected statepoint"); 375ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines 376ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines StatepointOpers opers(&MI); 377ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // Record all the deopt and gc operands (they're contiguous and run from the 378ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines // initial index to the end of the operand list) 379ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines const unsigned StartIdx = opers.getVarIdx(); 3806948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar recordStackMapOpers(MI, opers.getID(), MI.operands_begin() + StartIdx, 3816948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MI.operands_end(), false); 382ebe69fe11e48d322045d5949c83283927a0d790bStephen Hines} 38372ef53ad21cf2df7cdf6f2a0470b4eaa98d9e7edBill Wendling 384dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Emit the stackmap header. 3853d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// 38636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// Header { 38736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint8 : Stack Map Version (currently 1) 38836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint8 : Reserved (expected to be 0) 38936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint16 : Reserved (expected to be 0) 39036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// } 39136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint32 : NumFunctions 3923d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// uint32 : NumConstants 3933d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// uint32 : NumRecords 394dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid StackMaps::emitStackmapHeader(MCStreamer &OS) { 395dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Header. 396dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(StackMapVersion, 1); // Version. 397f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS.EmitIntValue(0, 1); // Reserved. 398f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS.EmitIntValue(0, 2); // Reserved. 399dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 400dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Num functions. 401dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << WSMP << "#functions = " << FnStackSize.size() << '\n'); 402dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(FnStackSize.size(), 4); 403dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Num constants. 404dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n'); 405dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(ConstPool.size(), 4); 406dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Num callsites. 407dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n'); 408dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(CSInfos.size(), 4); 409dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 410dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 411dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Emit the function frame record for each function. 412dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// 41336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// StkSizeRecord[NumFunctions] { 41436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint64 : Function Address 41536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint64 : Stack Size 41636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// } 417dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid StackMaps::emitFunctionFrameRecords(MCStreamer &OS) { 418dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Function Frame records. 419dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << WSMP << "functions:\n"); 420dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (auto const &FR : FnStackSize) { 421dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << WSMP << "function addr: " << FR.first 422f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar << " frame size: " << FR.second); 423dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitSymbolValue(FR.first, 8); 424dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(FR.second, 8); 425dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 426dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 427dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 428dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Emit the constant pool. 429dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// 43036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// int64 : Constants[NumConstants] 431dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid StackMaps::emitConstantPoolEntries(MCStreamer &OS) { 432dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Constant pool entries. 433dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << WSMP << "constants:\n"); 434f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar for (const auto &ConstEntry : ConstPool) { 435dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << WSMP << ConstEntry.second << '\n'); 436dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(ConstEntry.second, 8); 437dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines } 438dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 439dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 440dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Emit the callsite info for each callsite. 441dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// 4423d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// StkMapRecord[NumRecords] { 44336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint64 : PatchPoint ID 4443d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// uint32 : Instruction Offset 4453d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// uint16 : Reserved (record flags) 4463d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// uint16 : NumLocations 4473d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// Location[NumLocations] { 4483d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// uint8 : Register | Direct | Indirect | Constant | ConstantIndex 449bb756ca24401e190e3b704e5d92759c7a79cc6b7Andrew Trick/// uint8 : Size in Bytes 4503d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// uint16 : Dwarf RegNum 4513d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// int32 : Offset 4523d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// } 45336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint16 : Padding 45436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint16 : NumLiveOuts 45536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// LiveOuts[NumLiveOuts] { 45636b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint16 : Dwarf RegNum 45736b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint8 : Reserved 45836b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint8 : Size in Bytes 45936b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// } 46036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines/// uint32 : Padding (only if required to align to 8 byte) 4613d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// } 4623d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// 4633d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// Location Encoding, Type, Value: 4643d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// 0x1, Register, Reg (value in register) 4653d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// 0x2, Direct, Reg + Offset (frame index) 4663d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// 0x3, Indirect, [Reg + Offset] (spilled value) 4673d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// 0x4, Constant, Offset (small constant) 4683d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick/// 0x5, ConstIndex, Constants[Offset] (large constant) 4694c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainarvoid StackMaps::emitCallsiteEntries(MCStreamer &OS) { 4704c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar DEBUG(print(dbgs())); 47136b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Callsite entries. 472dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &CSI : CSInfos) { 473dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const LocationVec &CSLocs = CSI.Locations; 474dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines const LiveOutVec &LiveOuts = CSI.LiveOuts; 4753d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 4763d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // Verify stack map entry. It's better to communicate a problem to the 4773d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // runtime than crash in case of in-process compilation. Currently, we do 4783d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // simple overflow checks, but we may eventually communicate other 4793d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // compilation errors this way. 48036b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines if (CSLocs.size() > UINT16_MAX || LiveOuts.size() > UINT16_MAX) { 481dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(UINT64_MAX, 8); // Invalid ID. 482dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitValue(CSI.CSOffsetExpr, 4); 483dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 2); // Reserved. 484dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 2); // 0 locations. 485dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 2); // padding. 486dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 2); // 0 live-out registers. 487dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 4); // padding. 4883d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick continue; 4893d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick } 4903d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 491dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(CSI.ID, 8); 492dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitValue(CSI.CSOffsetExpr, 4); 4933d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 4943d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick // Reserved for flags. 495dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 2); 496dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(CSLocs.size(), 2); 4973d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 498dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &Loc : CSLocs) { 499f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS.EmitIntValue(Loc.Type, 1); 500dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(Loc.Size, 1); 5014c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS.EmitIntValue(Loc.Reg, 2); 5024c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar OS.EmitIntValue(Loc.Offset, 4); 5033d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick } 50436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines 50536b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Num live-out registers and padding to align to 4 byte. 506dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 2); 507dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(LiveOuts.size(), 2); 508dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 509dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines for (const auto &LO : LiveOuts) { 510f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar OS.EmitIntValue(LO.DwarfRegNum, 2); 511dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(0, 1); 512dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitIntValue(LO.Size, 1); 51336b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines } 51436b56886974eae4f9c5ebc96befd3e7bfe5de338Stephen Hines // Emit alignment to 8 byte. 515dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.EmitValueToAlignment(8); 5163d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick } 517dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines} 518dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 519dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines/// Serialize the stackmap data. 520dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hinesvoid StackMaps::serializeToStackMapSection() { 521f3ef5332fa3f4d5ec72c178a2b19dac363a19383Pirama Arumuga Nainar (void)WSMP; 522dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Bail out if there's no stack map data. 523de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert((!CSInfos.empty() || ConstPool.empty()) && 524dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Expected empty constant pool too!"); 525de2d8694e25a814696358e95141f4b1aa4d8847ePirama Arumuga Nainar assert((!CSInfos.empty() || FnStackSize.empty()) && 526dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines "Expected empty function record too!"); 527dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines if (CSInfos.empty()) 528dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines return; 5293d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 5306948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCContext &OutContext = AP.OutStreamer->getContext(); 5316948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCStreamer &OS = *AP.OutStreamer; 532dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 533dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Create the section. 5346948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar MCSection *StackMapSection = 5356948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OutContext.getObjectFileInfo()->getStackMapSection(); 536dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.SwitchSection(StackMapSection); 537dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 538dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Emit a dummy symbol to force section inclusion. 5396948897e478cbd66626159776a8017b3c18579b9Pirama Arumuga Nainar OS.EmitLabel(OutContext.getOrCreateSymbol(Twine("__LLVM_StackMaps"))); 540dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines 541dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Serialize data. 542dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines DEBUG(dbgs() << "********** Stack Map Output **********\n"); 543dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitStackmapHeader(OS); 544dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitFunctionFrameRecords(OS); 545dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines emitConstantPoolEntries(OS); 5464c5e43da7792f75567b693105cc53e3f1992ad98Pirama Arumuga Nainar emitCallsiteEntries(OS); 547dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines OS.AddBlankLine(); 5483d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick 549dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines // Clean up. 5503d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick CSInfos.clear(); 551dce4a407a24b04eebc6a376f8e62b41aaa7b071fStephen Hines ConstPool.clear(); 5523d74dea4bddc84d1881efc21eb5eefbddbfa9aedAndrew Trick} 553