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