StackMaps.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463
  1. //===---------------------------- StackMaps.cpp ---------------------------===//
  2. //
  3. // The LLVM Compiler Infrastructure
  4. //
  5. // This file is distributed under the University of Illinois Open Source
  6. // License. See LICENSE.TXT for details.
  7. //
  8. //===----------------------------------------------------------------------===//
  9. #define DEBUG_TYPE "stackmaps"
  10. #include "llvm/CodeGen/StackMaps.h"
  11. #include "llvm/CodeGen/AsmPrinter.h"
  12. #include "llvm/CodeGen/MachineInstr.h"
  13. #include "llvm/IR/DataLayout.h"
  14. #include "llvm/MC/MCContext.h"
  15. #include "llvm/MC/MCExpr.h"
  16. #include "llvm/MC/MCObjectFileInfo.h"
  17. #include "llvm/MC/MCSectionMachO.h"
  18. #include "llvm/MC/MCStreamer.h"
  19. #include "llvm/Support/Debug.h"
  20. #include "llvm/Support/raw_ostream.h"
  21. #include "llvm/Target/TargetOpcodes.h"
  22. #include "llvm/Target/TargetMachine.h"
  23. #include "llvm/Target/TargetRegisterInfo.h"
  24. #include <iterator>
  25. using namespace llvm;
  26. PatchPointOpers::PatchPointOpers(const MachineInstr *MI):
  27. MI(MI),
  28. HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
  29. !MI->getOperand(0).isImplicit()),
  30. IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() == CallingConv::AnyReg) {
  31. #ifndef NDEBUG
  32. {
  33. unsigned CheckStartIdx = 0, e = MI->getNumOperands();
  34. while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() &&
  35. MI->getOperand(CheckStartIdx).isDef() &&
  36. !MI->getOperand(CheckStartIdx).isImplicit())
  37. ++CheckStartIdx;
  38. assert(getMetaIdx() == CheckStartIdx &&
  39. "Unexpected additonal definition in Patchpoint intrinsic.");
  40. }
  41. #endif
  42. }
  43. unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const {
  44. if (!StartIdx)
  45. StartIdx = getVarIdx();
  46. // Find the next scratch register (implicit def and early clobber)
  47. unsigned ScratchIdx = StartIdx, e = MI->getNumOperands();
  48. while (ScratchIdx < e &&
  49. !(MI->getOperand(ScratchIdx).isReg() &&
  50. MI->getOperand(ScratchIdx).isDef() &&
  51. MI->getOperand(ScratchIdx).isImplicit() &&
  52. MI->getOperand(ScratchIdx).isEarlyClobber()))
  53. ++ScratchIdx;
  54. assert(ScratchIdx != e && "No scratch register available");
  55. return ScratchIdx;
  56. }
  57. std::pair<StackMaps::Location, MachineInstr::const_mop_iterator>
  58. StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
  59. MachineInstr::const_mop_iterator MOE) const {
  60. const MachineOperand &MOP = *MOI;
  61. assert((!MOP.isReg() || !MOP.isImplicit()) &&
  62. "Implicit operands should not be processed.");
  63. if (MOP.isImm()) {
  64. // Verify anyregcc
  65. // [<def>], <id>, <numBytes>, <target>, <numArgs>, <cc>, ...
  66. switch (MOP.getImm()) {
  67. default: llvm_unreachable("Unrecognized operand type.");
  68. case StackMaps::DirectMemRefOp: {
  69. unsigned Size = AP.TM.getDataLayout()->getPointerSizeInBits();
  70. assert((Size % 8) == 0 && "Need pointer size in bytes.");
  71. Size /= 8;
  72. unsigned Reg = (++MOI)->getReg();
  73. int64_t Imm = (++MOI)->getImm();
  74. return std::make_pair(
  75. Location(StackMaps::Location::Direct, Size, Reg, Imm), ++MOI);
  76. }
  77. case StackMaps::IndirectMemRefOp: {
  78. int64_t Size = (++MOI)->getImm();
  79. assert(Size > 0 && "Need a valid size for indirect memory locations.");
  80. unsigned Reg = (++MOI)->getReg();
  81. int64_t Imm = (++MOI)->getImm();
  82. return std::make_pair(
  83. Location(StackMaps::Location::Indirect, Size, Reg, Imm), ++MOI);
  84. }
  85. case StackMaps::ConstantOp: {
  86. ++MOI;
  87. assert(MOI->isImm() && "Expected constant operand.");
  88. int64_t Imm = MOI->getImm();
  89. return std::make_pair(
  90. Location(Location::Constant, sizeof(int64_t), 0, Imm), ++MOI);
  91. }
  92. }
  93. }
  94. if (MOP.isRegMask() || MOP.isRegLiveOut())
  95. return std::make_pair(Location(), ++MOI);
  96. // Otherwise this is a reg operand. The physical register number will
  97. // ultimately be encoded as a DWARF regno. The stack map also records the size
  98. // of a spill slot that can hold the register content. (The runtime can
  99. // track the actual size of the data type if it needs to.)
  100. assert(MOP.isReg() && "Expected register operand here.");
  101. assert(TargetRegisterInfo::isPhysicalRegister(MOP.getReg()) &&
  102. "Virtreg operands should have been rewritten before now.");
  103. const TargetRegisterClass *RC =
  104. AP.TM.getRegisterInfo()->getMinimalPhysRegClass(MOP.getReg());
  105. assert(!MOP.getSubReg() && "Physical subreg still around.");
  106. return std::make_pair(
  107. Location(Location::Register, RC->getSize(), MOP.getReg(), 0), ++MOI);
  108. }
  109. /// Go up the super-register chain until we hit a valid dwarf register number.
  110. static short getDwarfRegNum(unsigned Reg, const MCRegisterInfo &MCRI,
  111. const TargetRegisterInfo *TRI) {
  112. int RegNo = MCRI.getDwarfRegNum(Reg, false);
  113. for (MCSuperRegIterator SR(Reg, TRI);
  114. SR.isValid() && RegNo < 0; ++SR)
  115. RegNo = TRI->getDwarfRegNum(*SR, false);
  116. assert(RegNo >= 0 && "Invalid Dwarf register number.");
  117. return (unsigned short) RegNo;
  118. }
  119. /// Create a live-out register record for the given register Reg.
  120. StackMaps::LiveOutReg
  121. StackMaps::createLiveOutReg(unsigned Reg, const MCRegisterInfo &MCRI,
  122. const TargetRegisterInfo *TRI) const {
  123. unsigned RegNo = getDwarfRegNum(Reg, MCRI, TRI);
  124. unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize();
  125. unsigned LLVMRegNo = MCRI.getLLVMRegNum(RegNo, false);
  126. unsigned SubRegIdx = MCRI.getSubRegIndex(LLVMRegNo, Reg);
  127. unsigned Offset = 0;
  128. if (SubRegIdx)
  129. Offset = MCRI.getSubRegIdxOffset(SubRegIdx) / 8;
  130. return LiveOutReg(Reg, RegNo, Offset + Size);
  131. }
  132. /// Parse the register live-out mask and return a vector of live-out registers
  133. /// that need to be recorded in the stackmap.
  134. StackMaps::LiveOutVec
  135. StackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const {
  136. assert(Mask && "No register mask specified");
  137. const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
  138. MCContext &OutContext = AP.OutStreamer.getContext();
  139. const MCRegisterInfo &MCRI = *OutContext.getRegisterInfo();
  140. LiveOutVec LiveOuts;
  141. for (unsigned Reg = 0, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg)
  142. if ((Mask[Reg / 32] >> Reg % 32) & 1)
  143. LiveOuts.push_back(createLiveOutReg(Reg, MCRI, TRI));
  144. std::sort(LiveOuts.begin(), LiveOuts.end());
  145. for (LiveOutVec::iterator I = LiveOuts.begin(), E = LiveOuts.end();
  146. I != E; ++I) {
  147. if (!I->Reg)
  148. continue;
  149. for (LiveOutVec::iterator II = next(I); II != E; ++II) {
  150. if (I->RegNo != II->RegNo)
  151. break;
  152. I->Size = std::max(I->Size, II->Size);
  153. if (TRI->isSuperRegister(I->Reg, II->Reg))
  154. I->Reg = II->Reg;
  155. II->Reg = 0;
  156. }
  157. }
  158. LiveOuts.erase(std::remove_if(LiveOuts.begin(), LiveOuts.end(),
  159. LiveOutReg::isInvalid), LiveOuts.end());
  160. return LiveOuts;
  161. }
  162. void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint32_t ID,
  163. MachineInstr::const_mop_iterator MOI,
  164. MachineInstr::const_mop_iterator MOE,
  165. bool recordResult) {
  166. MCContext &OutContext = AP.OutStreamer.getContext();
  167. MCSymbol *MILabel = OutContext.CreateTempSymbol();
  168. AP.OutStreamer.EmitLabel(MILabel);
  169. LocationVec Locations;
  170. LiveOutVec LiveOuts;
  171. if (recordResult) {
  172. std::pair<Location, MachineInstr::const_mop_iterator> ParseResult =
  173. parseOperand(MI.operands_begin(), llvm::next(MI.operands_begin()));
  174. Location &Loc = ParseResult.first;
  175. assert(Loc.LocType == Location::Register &&
  176. "Stackmap return location must be a register.");
  177. Locations.push_back(Loc);
  178. }
  179. while (MOI != MOE) {
  180. Location Loc;
  181. tie(Loc, MOI) = parseOperand(MOI, MOE);
  182. // Move large constants into the constant pool.
  183. if (Loc.LocType == Location::Constant && (Loc.Offset & ~0xFFFFFFFFULL)) {
  184. Loc.LocType = Location::ConstantIndex;
  185. Loc.Offset = ConstPool.getConstantIndex(Loc.Offset);
  186. }
  187. // Skip the register mask and register live-out mask
  188. if (Loc.LocType != Location::Unprocessed)
  189. Locations.push_back(Loc);
  190. }
  191. const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub(
  192. MCSymbolRefExpr::Create(MILabel, OutContext),
  193. MCSymbolRefExpr::Create(AP.CurrentFnSym, OutContext),
  194. OutContext);
  195. if (MOI->isRegLiveOut())
  196. LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
  197. CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, Locations, LiveOuts));
  198. }
  199. static MachineInstr::const_mop_iterator
  200. getStackMapEndMOP(MachineInstr::const_mop_iterator MOI,
  201. MachineInstr::const_mop_iterator MOE) {
  202. for (; MOI != MOE; ++MOI)
  203. if (MOI->isRegLiveOut() || (MOI->isReg() && MOI->isImplicit()))
  204. break;
  205. return MOI;
  206. }
  207. void StackMaps::recordStackMap(const MachineInstr &MI) {
  208. assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
  209. int64_t ID = MI.getOperand(0).getImm();
  210. assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
  211. recordStackMapOpers(MI, ID, llvm::next(MI.operands_begin(), 2),
  212. getStackMapEndMOP(MI.operands_begin(),
  213. MI.operands_end()));
  214. }
  215. void StackMaps::recordPatchPoint(const MachineInstr &MI) {
  216. assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint");
  217. PatchPointOpers opers(&MI);
  218. int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm();
  219. assert((int32_t)ID == ID && "Stack maps hold 32-bit IDs");
  220. MachineInstr::const_mop_iterator MOI =
  221. llvm::next(MI.operands_begin(), opers.getStackMapStartIdx());
  222. recordStackMapOpers(MI, ID, MOI, getStackMapEndMOP(MOI, MI.operands_end()),
  223. opers.isAnyReg() && opers.hasDef());
  224. #ifndef NDEBUG
  225. // verify anyregcc
  226. LocationVec &Locations = CSInfos.back().Locations;
  227. if (opers.isAnyReg()) {
  228. unsigned NArgs = opers.getMetaOper(PatchPointOpers::NArgPos).getImm();
  229. for (unsigned i = 0, e = (opers.hasDef() ? NArgs+1 : NArgs); i != e; ++i)
  230. assert(Locations[i].LocType == Location::Register &&
  231. "anyreg arg must be in reg.");
  232. }
  233. #endif
  234. }
  235. /// serializeToStackMapSection conceptually populates the following fields:
  236. ///
  237. /// uint32 : Reserved (header)
  238. /// uint32 : NumConstants
  239. /// int64 : Constants[NumConstants]
  240. /// uint32 : NumRecords
  241. /// StkMapRecord[NumRecords] {
  242. /// uint32 : PatchPoint ID
  243. /// uint32 : Instruction Offset
  244. /// uint16 : Reserved (record flags)
  245. /// uint16 : NumLocations
  246. /// Location[NumLocations] {
  247. /// uint8 : Register | Direct | Indirect | Constant | ConstantIndex
  248. /// uint8 : Size in Bytes
  249. /// uint16 : Dwarf RegNum
  250. /// int32 : Offset
  251. /// }
  252. /// uint16 : NumLiveOuts
  253. /// LiveOuts[NumLiveOuts]
  254. /// uint16 : Dwarf RegNum
  255. /// uint8 : Reserved
  256. /// uint8 : Size in Bytes
  257. /// }
  258. ///
  259. /// Location Encoding, Type, Value:
  260. /// 0x1, Register, Reg (value in register)
  261. /// 0x2, Direct, Reg + Offset (frame index)
  262. /// 0x3, Indirect, [Reg + Offset] (spilled value)
  263. /// 0x4, Constant, Offset (small constant)
  264. /// 0x5, ConstIndex, Constants[Offset] (large constant)
  265. ///
  266. void StackMaps::serializeToStackMapSection() {
  267. // Bail out if there's no stack map data.
  268. if (CSInfos.empty())
  269. return;
  270. MCContext &OutContext = AP.OutStreamer.getContext();
  271. const TargetRegisterInfo *TRI = AP.TM.getRegisterInfo();
  272. // Create the section.
  273. const MCSection *StackMapSection =
  274. OutContext.getObjectFileInfo()->getStackMapSection();
  275. AP.OutStreamer.SwitchSection(StackMapSection);
  276. // Emit a dummy symbol to force section inclusion.
  277. AP.OutStreamer.EmitLabel(
  278. OutContext.GetOrCreateSymbol(Twine("__LLVM_StackMaps")));
  279. // Serialize data.
  280. const char *WSMP = "Stack Maps: ";
  281. (void)WSMP;
  282. const MCRegisterInfo &MCRI = *OutContext.getRegisterInfo();
  283. DEBUG(dbgs() << "********** Stack Map Output **********\n");
  284. // Header.
  285. AP.OutStreamer.EmitIntValue(0, 4);
  286. // Num constants.
  287. AP.OutStreamer.EmitIntValue(ConstPool.getNumConstants(), 4);
  288. // Constant pool entries.
  289. for (unsigned i = 0; i < ConstPool.getNumConstants(); ++i)
  290. AP.OutStreamer.EmitIntValue(ConstPool.getConstant(i), 8);
  291. DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << "\n");
  292. AP.OutStreamer.EmitIntValue(CSInfos.size(), 4);
  293. for (CallsiteInfoList::const_iterator CSII = CSInfos.begin(),
  294. CSIE = CSInfos.end();
  295. CSII != CSIE; ++CSII) {
  296. unsigned CallsiteID = CSII->ID;
  297. const LocationVec &CSLocs = CSII->Locations;
  298. const LiveOutVec &LiveOuts = CSII->LiveOuts;
  299. DEBUG(dbgs() << WSMP << "callsite " << CallsiteID << "\n");
  300. // Verify stack map entry. It's better to communicate a problem to the
  301. // runtime than crash in case of in-process compilation. Currently, we do
  302. // simple overflow checks, but we may eventually communicate other
  303. // compilation errors this way.
  304. if (CSLocs.size() > UINT16_MAX || LiveOuts.size() > UINT16_MAX) {
  305. AP.OutStreamer.EmitIntValue(UINT32_MAX, 4); // Invalid ID.
  306. AP.OutStreamer.EmitValue(CSII->CSOffsetExpr, 4);
  307. AP.OutStreamer.EmitIntValue(0, 2); // Reserved.
  308. AP.OutStreamer.EmitIntValue(0, 2); // 0 locations.
  309. AP.OutStreamer.EmitIntValue(0, 2); // 0 live-out registers.
  310. continue;
  311. }
  312. AP.OutStreamer.EmitIntValue(CallsiteID, 4);
  313. AP.OutStreamer.EmitValue(CSII->CSOffsetExpr, 4);
  314. // Reserved for flags.
  315. AP.OutStreamer.EmitIntValue(0, 2);
  316. DEBUG(dbgs() << WSMP << " has " << CSLocs.size() << " locations\n");
  317. AP.OutStreamer.EmitIntValue(CSLocs.size(), 2);
  318. unsigned operIdx = 0;
  319. for (LocationVec::const_iterator LocI = CSLocs.begin(), LocE = CSLocs.end();
  320. LocI != LocE; ++LocI, ++operIdx) {
  321. const Location &Loc = *LocI;
  322. unsigned RegNo = 0;
  323. int Offset = Loc.Offset;
  324. if(Loc.Reg) {
  325. RegNo = MCRI.getDwarfRegNum(Loc.Reg, false);
  326. for (MCSuperRegIterator SR(Loc.Reg, TRI);
  327. SR.isValid() && (int)RegNo < 0; ++SR) {
  328. RegNo = TRI->getDwarfRegNum(*SR, false);
  329. }
  330. // If this is a register location, put the subregister byte offset in
  331. // the location offset.
  332. if (Loc.LocType == Location::Register) {
  333. assert(!Loc.Offset && "Register location should have zero offset");
  334. unsigned LLVMRegNo = MCRI.getLLVMRegNum(RegNo, false);
  335. unsigned SubRegIdx = MCRI.getSubRegIndex(LLVMRegNo, Loc.Reg);
  336. if (SubRegIdx)
  337. Offset = MCRI.getSubRegIdxOffset(SubRegIdx);
  338. }
  339. }
  340. else {
  341. assert(Loc.LocType != Location::Register &&
  342. "Missing location register");
  343. }
  344. DEBUG(
  345. dbgs() << WSMP << " Loc " << operIdx << ": ";
  346. switch (Loc.LocType) {
  347. case Location::Unprocessed:
  348. dbgs() << "<Unprocessed operand>";
  349. break;
  350. case Location::Register:
  351. dbgs() << "Register " << MCRI.getName(Loc.Reg);
  352. break;
  353. case Location::Direct:
  354. dbgs() << "Direct " << MCRI.getName(Loc.Reg);
  355. if (Loc.Offset)
  356. dbgs() << " + " << Loc.Offset;
  357. break;
  358. case Location::Indirect:
  359. dbgs() << "Indirect " << MCRI.getName(Loc.Reg)
  360. << " + " << Loc.Offset;
  361. break;
  362. case Location::Constant:
  363. dbgs() << "Constant " << Loc.Offset;
  364. break;
  365. case Location::ConstantIndex:
  366. dbgs() << "Constant Index " << Loc.Offset;
  367. break;
  368. }
  369. dbgs() << " [encoding: .byte " << Loc.LocType
  370. << ", .byte " << Loc.Size
  371. << ", .short " << RegNo
  372. << ", .int " << Offset << "]\n";
  373. );
  374. AP.OutStreamer.EmitIntValue(Loc.LocType, 1);
  375. AP.OutStreamer.EmitIntValue(Loc.Size, 1);
  376. AP.OutStreamer.EmitIntValue(RegNo, 2);
  377. AP.OutStreamer.EmitIntValue(Offset, 4);
  378. }
  379. DEBUG(dbgs() << WSMP << " has " << LiveOuts.size()
  380. << " live-out registers\n");
  381. AP.OutStreamer.EmitIntValue(LiveOuts.size(), 2);
  382. operIdx = 0;
  383. for (LiveOutVec::const_iterator LI = LiveOuts.begin(), LE = LiveOuts.end();
  384. LI != LE; ++LI, ++operIdx) {
  385. DEBUG(dbgs() << WSMP << " LO " << operIdx << ": "
  386. << MCRI.getName(LI->Reg)
  387. << " [encoding: .short " << LI->RegNo
  388. << ", .byte 0, .byte " << LI->Size << "]\n");
  389. AP.OutStreamer.EmitIntValue(LI->RegNo, 2);
  390. AP.OutStreamer.EmitIntValue(0, 1);
  391. AP.OutStreamer.EmitIntValue(LI->Size, 1);
  392. }
  393. }
  394. AP.OutStreamer.AddBlankLine();
  395. CSInfos.clear();
  396. }