LLVM API Documentation
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 }