LLVM API Documentation

StackMaps.cpp
Go to the documentation of this file.
00001 //===---------------------------- StackMaps.cpp ---------------------------===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 
00010 #include "llvm/CodeGen/StackMaps.h"
00011 #include "llvm/CodeGen/AsmPrinter.h"
00012 #include "llvm/CodeGen/MachineFrameInfo.h"
00013 #include "llvm/CodeGen/MachineFunction.h"
00014 #include "llvm/CodeGen/MachineInstr.h"
00015 #include "llvm/IR/DataLayout.h"
00016 #include "llvm/MC/MCContext.h"
00017 #include "llvm/MC/MCExpr.h"
00018 #include "llvm/MC/MCObjectFileInfo.h"
00019 #include "llvm/MC/MCSectionMachO.h"
00020 #include "llvm/MC/MCStreamer.h"
00021 #include "llvm/Support/CommandLine.h"
00022 #include "llvm/Support/Debug.h"
00023 #include "llvm/Support/raw_ostream.h"
00024 #include "llvm/Target/TargetMachine.h"
00025 #include "llvm/Target/TargetOpcodes.h"
00026 #include "llvm/Target/TargetRegisterInfo.h"
00027 #include "llvm/Target/TargetSubtargetInfo.h"
00028 #include <iterator>
00029 
00030 using namespace llvm;
00031 
00032 #define DEBUG_TYPE "stackmaps"
00033 
00034 static cl::opt<int> StackMapVersion("stackmap-version", cl::init(1),
00035   cl::desc("Specify the stackmap encoding version (default = 1)"));
00036 
00037 const char *StackMaps::WSMP = "Stack Maps: ";
00038 
00039 PatchPointOpers::PatchPointOpers(const MachineInstr *MI)
00040   : MI(MI),
00041     HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
00042            !MI->getOperand(0).isImplicit()),
00043     IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() == CallingConv::AnyReg)
00044 {
00045 #ifndef NDEBUG
00046   unsigned CheckStartIdx = 0, e = MI->getNumOperands();
00047   while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() &&
00048          MI->getOperand(CheckStartIdx).isDef() &&
00049          !MI->getOperand(CheckStartIdx).isImplicit())
00050     ++CheckStartIdx;
00051 
00052   assert(getMetaIdx() == CheckStartIdx &&
00053          "Unexpected additional definition in Patchpoint intrinsic.");
00054 #endif
00055 }
00056 
00057 unsigned PatchPointOpers::getNextScratchIdx(unsigned StartIdx) const {
00058   if (!StartIdx)
00059     StartIdx = getVarIdx();
00060 
00061   // Find the next scratch register (implicit def and early clobber)
00062   unsigned ScratchIdx = StartIdx, e = MI->getNumOperands();
00063   while (ScratchIdx < e &&
00064          !(MI->getOperand(ScratchIdx).isReg() &&
00065            MI->getOperand(ScratchIdx).isDef() &&
00066            MI->getOperand(ScratchIdx).isImplicit() &&
00067            MI->getOperand(ScratchIdx).isEarlyClobber()))
00068     ++ScratchIdx;
00069 
00070   assert(ScratchIdx != e && "No scratch register available");
00071   return ScratchIdx;
00072 }
00073 
00074 StackMaps::StackMaps(AsmPrinter &AP) : AP(AP) {
00075   if (StackMapVersion != 1)
00076     llvm_unreachable("Unsupported stackmap version!");
00077 }
00078 
00079 MachineInstr::const_mop_iterator
00080 StackMaps::parseOperand(MachineInstr::const_mop_iterator MOI,
00081                         MachineInstr::const_mop_iterator MOE,
00082                         LocationVec &Locs, LiveOutVec &LiveOuts) const {
00083   if (MOI->isImm()) {
00084     switch (MOI->getImm()) {
00085     default: llvm_unreachable("Unrecognized operand type.");
00086     case StackMaps::DirectMemRefOp: {
00087       unsigned Size =
00088           AP.TM.getSubtargetImpl()->getDataLayout()->getPointerSizeInBits();
00089       assert((Size % 8) == 0 && "Need pointer size in bytes.");
00090       Size /= 8;
00091       unsigned Reg = (++MOI)->getReg();
00092       int64_t Imm = (++MOI)->getImm();
00093       Locs.push_back(Location(StackMaps::Location::Direct, Size, Reg, Imm));
00094       break;
00095     }
00096     case StackMaps::IndirectMemRefOp: {
00097       int64_t Size = (++MOI)->getImm();
00098       assert(Size > 0 && "Need a valid size for indirect memory locations.");
00099       unsigned Reg = (++MOI)->getReg();
00100       int64_t Imm = (++MOI)->getImm();
00101       Locs.push_back(Location(StackMaps::Location::Indirect, Size, Reg, Imm));
00102       break;
00103     }
00104     case StackMaps::ConstantOp: {
00105       ++MOI;
00106       assert(MOI->isImm() && "Expected constant operand.");
00107       int64_t Imm = MOI->getImm();
00108       Locs.push_back(Location(Location::Constant, sizeof(int64_t), 0, Imm));
00109       break;
00110     }
00111     }
00112     return ++MOI;
00113   }
00114 
00115   // The physical register number will ultimately be encoded as a DWARF regno.
00116   // The stack map also records the size of a spill slot that can hold the
00117   // register content. (The runtime can track the actual size of the data type
00118   // if it needs to.)
00119   if (MOI->isReg()) {
00120     // Skip implicit registers (this includes our scratch registers)
00121     if (MOI->isImplicit())
00122       return ++MOI;
00123 
00124     assert(TargetRegisterInfo::isPhysicalRegister(MOI->getReg()) &&
00125            "Virtreg operands should have been rewritten before now.");
00126     const TargetRegisterClass *RC =
00127         AP.TM.getSubtargetImpl()->getRegisterInfo()->getMinimalPhysRegClass(
00128             MOI->getReg());
00129     assert(!MOI->getSubReg() && "Physical subreg still around.");
00130     Locs.push_back(
00131       Location(Location::Register, RC->getSize(), MOI->getReg(), 0));
00132     return ++MOI;
00133   }
00134 
00135   if (MOI->isRegLiveOut())
00136     LiveOuts = parseRegisterLiveOutMask(MOI->getRegLiveOut());
00137 
00138   return ++MOI;
00139 }
00140 
00141 /// Go up the super-register chain until we hit a valid dwarf register number.
00142 static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) {
00143   int RegNo = TRI->getDwarfRegNum(Reg, false);
00144   for (MCSuperRegIterator SR(Reg, TRI); SR.isValid() && RegNo < 0; ++SR)
00145     RegNo = TRI->getDwarfRegNum(*SR, false);
00146 
00147   assert(RegNo >= 0 && "Invalid Dwarf register number.");
00148   return (unsigned) RegNo;
00149 }
00150 
00151 /// Create a live-out register record for the given register Reg.
00152 StackMaps::LiveOutReg
00153 StackMaps::createLiveOutReg(unsigned Reg, const TargetRegisterInfo *TRI) const {
00154   unsigned RegNo = getDwarfRegNum(Reg, TRI);
00155   unsigned Size = TRI->getMinimalPhysRegClass(Reg)->getSize();
00156   return LiveOutReg(Reg, RegNo, Size);
00157 }
00158 
00159 /// Parse the register live-out mask and return a vector of live-out registers
00160 /// that need to be recorded in the stackmap.
00161 StackMaps::LiveOutVec
00162 StackMaps::parseRegisterLiveOutMask(const uint32_t *Mask) const {
00163   assert(Mask && "No register mask specified");
00164   const TargetRegisterInfo *TRI = AP.TM.getSubtargetImpl()->getRegisterInfo();
00165   LiveOutVec LiveOuts;
00166 
00167   // Create a LiveOutReg for each bit that is set in the register mask.
00168   for (unsigned Reg = 0, NumRegs = TRI->getNumRegs(); Reg != NumRegs; ++Reg)
00169     if ((Mask[Reg / 32] >> Reg % 32) & 1)
00170       LiveOuts.push_back(createLiveOutReg(Reg, TRI));
00171 
00172   // We don't need to keep track of a register if its super-register is already
00173   // in the list. Merge entries that refer to the same dwarf register and use
00174   // the maximum size that needs to be spilled.
00175   std::sort(LiveOuts.begin(), LiveOuts.end());
00176   for (LiveOutVec::iterator I = LiveOuts.begin(), E = LiveOuts.end();
00177        I != E; ++I) {
00178     for (LiveOutVec::iterator II = std::next(I); II != E; ++II) {
00179       if (I->RegNo != II->RegNo) {
00180         // Skip all the now invalid entries.
00181         I = --II;
00182         break;
00183       }
00184       I->Size = std::max(I->Size, II->Size);
00185       if (TRI->isSuperRegister(I->Reg, II->Reg))
00186         I->Reg = II->Reg;
00187       II->MarkInvalid();
00188     }
00189   }
00190   LiveOuts.erase(std::remove_if(LiveOuts.begin(), LiveOuts.end(),
00191                                 LiveOutReg::IsInvalid), LiveOuts.end());
00192   return LiveOuts;
00193 }
00194 
00195 void StackMaps::recordStackMapOpers(const MachineInstr &MI, uint64_t ID,
00196                                     MachineInstr::const_mop_iterator MOI,
00197                                     MachineInstr::const_mop_iterator MOE,
00198                                     bool recordResult) {
00199 
00200   MCContext &OutContext = AP.OutStreamer.getContext();
00201   MCSymbol *MILabel = OutContext.CreateTempSymbol();
00202   AP.OutStreamer.EmitLabel(MILabel);
00203 
00204   LocationVec Locations;
00205   LiveOutVec LiveOuts;
00206 
00207   if (recordResult) {
00208     assert(PatchPointOpers(&MI).hasDef() && "Stackmap has no return value.");
00209     parseOperand(MI.operands_begin(), std::next(MI.operands_begin()),
00210                  Locations, LiveOuts);
00211   }
00212 
00213   // Parse operands.
00214   while (MOI != MOE) {
00215     MOI = parseOperand(MOI, MOE, Locations, LiveOuts);
00216   }
00217 
00218   // Move large constants into the constant pool.
00219   for (LocationVec::iterator I = Locations.begin(), E = Locations.end();
00220        I != E; ++I) {
00221     // Constants are encoded as sign-extended integers.
00222     // -1 is directly encoded as .long 0xFFFFFFFF with no constant pool.
00223     if (I->LocType == Location::Constant &&
00224         ((I->Offset + (int64_t(1)<<31)) >> 32) != 0) {
00225       I->LocType = Location::ConstantIndex;
00226       auto Result = ConstPool.insert(std::make_pair(I->Offset, I->Offset));
00227       I->Offset = Result.first - ConstPool.begin();
00228     }
00229   }
00230 
00231   // Create an expression to calculate the offset of the callsite from function
00232   // entry.
00233   const MCExpr *CSOffsetExpr = MCBinaryExpr::CreateSub(
00234     MCSymbolRefExpr::Create(MILabel, OutContext),
00235     MCSymbolRefExpr::Create(AP.CurrentFnSym, OutContext),
00236     OutContext);
00237 
00238   CSInfos.push_back(CallsiteInfo(CSOffsetExpr, ID, Locations, LiveOuts));
00239 
00240   // Record the stack size of the current function.
00241   const MachineFrameInfo *MFI = AP.MF->getFrameInfo();
00242   const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo();
00243   const bool DynamicFrameSize = MFI->hasVarSizedObjects() ||
00244     RegInfo->needsStackRealignment(*(AP.MF));
00245   FnStackSize[AP.CurrentFnSym] =
00246     DynamicFrameSize ? UINT64_MAX : MFI->getStackSize();
00247 }
00248 
00249 void StackMaps::recordStackMap(const MachineInstr &MI) {
00250   assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
00251 
00252   int64_t ID = MI.getOperand(0).getImm();
00253   recordStackMapOpers(MI, ID, std::next(MI.operands_begin(), 2),
00254                       MI.operands_end());
00255 }
00256 
00257 void StackMaps::recordPatchPoint(const MachineInstr &MI) {
00258   assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint");
00259 
00260   PatchPointOpers opers(&MI);
00261   int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm();
00262 
00263   MachineInstr::const_mop_iterator MOI =
00264     std::next(MI.operands_begin(), opers.getStackMapStartIdx());
00265   recordStackMapOpers(MI, ID, MOI, MI.operands_end(),
00266                       opers.isAnyReg() && opers.hasDef());
00267 
00268 #ifndef NDEBUG
00269   // verify anyregcc
00270   LocationVec &Locations = CSInfos.back().Locations;
00271   if (opers.isAnyReg()) {
00272     unsigned NArgs = opers.getMetaOper(PatchPointOpers::NArgPos).getImm();
00273     for (unsigned i = 0, e = (opers.hasDef() ? NArgs+1 : NArgs); i != e; ++i)
00274       assert(Locations[i].LocType == Location::Register &&
00275              "anyreg arg must be in reg.");
00276   }
00277 #endif
00278 }
00279 
00280 /// Emit the stackmap header.
00281 ///
00282 /// Header {
00283 ///   uint8  : Stack Map Version (currently 1)
00284 ///   uint8  : Reserved (expected to be 0)
00285 ///   uint16 : Reserved (expected to be 0)
00286 /// }
00287 /// uint32 : NumFunctions
00288 /// uint32 : NumConstants
00289 /// uint32 : NumRecords
00290 void StackMaps::emitStackmapHeader(MCStreamer &OS) {
00291   // Header.
00292   OS.EmitIntValue(StackMapVersion, 1); // Version.
00293   OS.EmitIntValue(0, 1); // Reserved.
00294   OS.EmitIntValue(0, 2); // Reserved.
00295 
00296   // Num functions.
00297   DEBUG(dbgs() << WSMP << "#functions = " << FnStackSize.size() << '\n');
00298   OS.EmitIntValue(FnStackSize.size(), 4);
00299   // Num constants.
00300   DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n');
00301   OS.EmitIntValue(ConstPool.size(), 4);
00302   // Num callsites.
00303   DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n');
00304   OS.EmitIntValue(CSInfos.size(), 4);
00305 }
00306 
00307 /// Emit the function frame record for each function.
00308 ///
00309 /// StkSizeRecord[NumFunctions] {
00310 ///   uint64 : Function Address
00311 ///   uint64 : Stack Size
00312 /// }
00313 void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) {
00314   // Function Frame records.
00315   DEBUG(dbgs() << WSMP << "functions:\n");
00316   for (auto const &FR : FnStackSize) {
00317     DEBUG(dbgs() << WSMP << "function addr: " << FR.first
00318                          << " frame size: " << FR.second);
00319     OS.EmitSymbolValue(FR.first, 8);
00320     OS.EmitIntValue(FR.second, 8);
00321   }
00322 }
00323 
00324 /// Emit the constant pool.
00325 ///
00326 /// int64  : Constants[NumConstants]
00327 void StackMaps::emitConstantPoolEntries(MCStreamer &OS) {
00328   // Constant pool entries.
00329   DEBUG(dbgs() << WSMP << "constants:\n");
00330   for (auto ConstEntry : ConstPool) {
00331     DEBUG(dbgs() << WSMP << ConstEntry.second << '\n');
00332     OS.EmitIntValue(ConstEntry.second, 8);
00333   }
00334 }
00335 
00336 /// Emit the callsite info for each callsite.
00337 ///
00338 /// StkMapRecord[NumRecords] {
00339 ///   uint64 : PatchPoint ID
00340 ///   uint32 : Instruction Offset
00341 ///   uint16 : Reserved (record flags)
00342 ///   uint16 : NumLocations
00343 ///   Location[NumLocations] {
00344 ///     uint8  : Register | Direct | Indirect | Constant | ConstantIndex
00345 ///     uint8  : Size in Bytes
00346 ///     uint16 : Dwarf RegNum
00347 ///     int32  : Offset
00348 ///   }
00349 ///   uint16 : Padding
00350 ///   uint16 : NumLiveOuts
00351 ///   LiveOuts[NumLiveOuts] {
00352 ///     uint16 : Dwarf RegNum
00353 ///     uint8  : Reserved
00354 ///     uint8  : Size in Bytes
00355 ///   }
00356 ///   uint32 : Padding (only if required to align to 8 byte)
00357 /// }
00358 ///
00359 /// Location Encoding, Type, Value:
00360 ///   0x1, Register, Reg                 (value in register)
00361 ///   0x2, Direct, Reg + Offset          (frame index)
00362 ///   0x3, Indirect, [Reg + Offset]      (spilled value)
00363 ///   0x4, Constant, Offset              (small constant)
00364 ///   0x5, ConstIndex, Constants[Offset] (large constant)
00365 void StackMaps::emitCallsiteEntries(MCStreamer &OS,
00366                                     const TargetRegisterInfo *TRI) {
00367   // Callsite entries.
00368   DEBUG(dbgs() << WSMP << "callsites:\n");
00369   for (const auto &CSI : CSInfos) {
00370     const LocationVec &CSLocs = CSI.Locations;
00371     const LiveOutVec &LiveOuts = CSI.LiveOuts;
00372 
00373     DEBUG(dbgs() << WSMP << "callsite " << CSI.ID << "\n");
00374 
00375     // Verify stack map entry. It's better to communicate a problem to the
00376     // runtime than crash in case of in-process compilation. Currently, we do
00377     // simple overflow checks, but we may eventually communicate other
00378     // compilation errors this way.
00379     if (CSLocs.size() > UINT16_MAX || LiveOuts.size() > UINT16_MAX) {
00380       OS.EmitIntValue(UINT64_MAX, 8); // Invalid ID.
00381       OS.EmitValue(CSI.CSOffsetExpr, 4);
00382       OS.EmitIntValue(0, 2); // Reserved.
00383       OS.EmitIntValue(0, 2); // 0 locations.
00384       OS.EmitIntValue(0, 2); // padding.
00385       OS.EmitIntValue(0, 2); // 0 live-out registers.
00386       OS.EmitIntValue(0, 4); // padding.
00387       continue;
00388     }
00389 
00390     OS.EmitIntValue(CSI.ID, 8);
00391     OS.EmitValue(CSI.CSOffsetExpr, 4);
00392 
00393     // Reserved for flags.
00394     OS.EmitIntValue(0, 2);
00395 
00396     DEBUG(dbgs() << WSMP << "  has " << CSLocs.size() << " locations\n");
00397 
00398     OS.EmitIntValue(CSLocs.size(), 2);
00399 
00400     unsigned OperIdx = 0;
00401     for (const auto &Loc : CSLocs) {
00402       unsigned RegNo = 0;
00403       int Offset = Loc.Offset;
00404       if(Loc.Reg) {
00405         RegNo = getDwarfRegNum(Loc.Reg, TRI);
00406 
00407         // If this is a register location, put the subregister byte offset in
00408         // the location offset.
00409         if (Loc.LocType == Location::Register) {
00410           assert(!Loc.Offset && "Register location should have zero offset");
00411           unsigned LLVMRegNo = TRI->getLLVMRegNum(RegNo, false);
00412           unsigned SubRegIdx = TRI->getSubRegIndex(LLVMRegNo, Loc.Reg);
00413           if (SubRegIdx)
00414             Offset = TRI->getSubRegIdxOffset(SubRegIdx);
00415         }
00416       }
00417       else {
00418         assert(Loc.LocType != Location::Register &&
00419                "Missing location register");
00420       }
00421 
00422       DEBUG(dbgs() << WSMP << "  Loc " << OperIdx << ": ";
00423             switch (Loc.LocType) {
00424             case Location::Unprocessed:
00425               dbgs() << "<Unprocessed operand>";
00426               break;
00427             case Location::Register:
00428               dbgs() << "Register " << TRI->getName(Loc.Reg);
00429               break;
00430             case Location::Direct:
00431               dbgs() << "Direct " << TRI->getName(Loc.Reg);
00432               if (Loc.Offset)
00433               dbgs() << " + " << Loc.Offset;
00434               break;
00435             case Location::Indirect:
00436               dbgs() << "Indirect " << TRI->getName(Loc.Reg)
00437               << " + " << Loc.Offset;
00438               break;
00439             case Location::Constant:
00440               dbgs() << "Constant " << Loc.Offset;
00441               break;
00442             case Location::ConstantIndex:
00443               dbgs() << "Constant Index " << Loc.Offset;
00444               break;
00445               }
00446             dbgs() << "     [encoding: .byte " << Loc.LocType
00447             << ", .byte " << Loc.Size
00448             << ", .short " << RegNo
00449             << ", .int " << Offset << "]\n";
00450             );
00451 
00452       OS.EmitIntValue(Loc.LocType, 1);
00453       OS.EmitIntValue(Loc.Size, 1);
00454       OS.EmitIntValue(RegNo, 2);
00455       OS.EmitIntValue(Offset, 4);
00456       OperIdx++;
00457     }
00458 
00459     DEBUG(dbgs() << WSMP << "  has " << LiveOuts.size()
00460                          << " live-out registers\n");
00461 
00462     // Num live-out registers and padding to align to 4 byte.
00463     OS.EmitIntValue(0, 2);
00464     OS.EmitIntValue(LiveOuts.size(), 2);
00465 
00466     OperIdx = 0;
00467     for (const auto &LO : LiveOuts) {
00468       DEBUG(dbgs() << WSMP << "  LO " << OperIdx << ": "
00469                            << TRI->getName(LO.Reg)
00470                            << "     [encoding: .short " << LO.RegNo
00471                            << ", .byte 0, .byte " << LO.Size << "]\n");
00472       OS.EmitIntValue(LO.RegNo, 2);
00473       OS.EmitIntValue(0, 1);
00474       OS.EmitIntValue(LO.Size, 1);
00475     }
00476     // Emit alignment to 8 byte.
00477     OS.EmitValueToAlignment(8);
00478   }
00479 }
00480 
00481 /// Serialize the stackmap data.
00482 void StackMaps::serializeToStackMapSection() {
00483   (void) WSMP;
00484   // Bail out if there's no stack map data.
00485   assert((!CSInfos.empty() || (CSInfos.empty() && ConstPool.empty())) &&
00486          "Expected empty constant pool too!");
00487   assert((!CSInfos.empty() || (CSInfos.empty() && FnStackSize.empty())) &&
00488          "Expected empty function record too!");
00489   if (CSInfos.empty())
00490     return;
00491 
00492   MCContext &OutContext = AP.OutStreamer.getContext();
00493   MCStreamer &OS = AP.OutStreamer;
00494   const TargetRegisterInfo *TRI = AP.TM.getSubtargetImpl()->getRegisterInfo();
00495 
00496   // Create the section.
00497   const MCSection *StackMapSection =
00498     OutContext.getObjectFileInfo()->getStackMapSection();
00499   OS.SwitchSection(StackMapSection);
00500 
00501   // Emit a dummy symbol to force section inclusion.
00502   OS.EmitLabel(OutContext.GetOrCreateSymbol(Twine("__LLVM_StackMaps")));
00503 
00504   // Serialize data.
00505   DEBUG(dbgs() << "********** Stack Map Output **********\n");
00506   emitStackmapHeader(OS);
00507   emitFunctionFrameRecords(OS);
00508   emitConstantPoolEntries(OS);
00509   emitCallsiteEntries(OS, TRI);
00510   OS.AddBlankLine();
00511 
00512   // Clean up.
00513   CSInfos.clear();
00514   ConstPool.clear();
00515 }