comparison lib/CodeGen/StackMaps.cpp @ 120:1172e4bd9c6f

update 4.0.0
author mir3636
date Fri, 25 Nov 2016 19:14:25 +0900
parents afa8332a0e37
children 803732b1fca8
comparison
equal deleted inserted replaced
101:34baf5011add 120:1172e4bd9c6f
28 using namespace llvm; 28 using namespace llvm;
29 29
30 #define DEBUG_TYPE "stackmaps" 30 #define DEBUG_TYPE "stackmaps"
31 31
32 static cl::opt<int> StackMapVersion( 32 static cl::opt<int> StackMapVersion(
33 "stackmap-version", cl::init(1), 33 "stackmap-version", cl::init(2),
34 cl::desc("Specify the stackmap encoding version (default = 1)")); 34 cl::desc("Specify the stackmap encoding version (default = 2)"));
35 35
36 const char *StackMaps::WSMP = "Stack Maps: "; 36 const char *StackMaps::WSMP = "Stack Maps: ";
37
38 StackMapOpers::StackMapOpers(const MachineInstr *MI)
39 : MI(MI) {
40 assert(getVarIdx() <= MI->getNumOperands() &&
41 "invalid stackmap definition");
42 }
37 43
38 PatchPointOpers::PatchPointOpers(const MachineInstr *MI) 44 PatchPointOpers::PatchPointOpers(const MachineInstr *MI)
39 : MI(MI), HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() && 45 : MI(MI), HasDef(MI->getOperand(0).isReg() && MI->getOperand(0).isDef() &&
40 !MI->getOperand(0).isImplicit()), 46 !MI->getOperand(0).isImplicit()) {
41 IsAnyReg(MI->getOperand(getMetaIdx(CCPos)).getImm() ==
42 CallingConv::AnyReg) {
43 #ifndef NDEBUG 47 #ifndef NDEBUG
44 unsigned CheckStartIdx = 0, e = MI->getNumOperands(); 48 unsigned CheckStartIdx = 0, e = MI->getNumOperands();
45 while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() && 49 while (CheckStartIdx < e && MI->getOperand(CheckStartIdx).isReg() &&
46 MI->getOperand(CheckStartIdx).isDef() && 50 MI->getOperand(CheckStartIdx).isDef() &&
47 !MI->getOperand(CheckStartIdx).isImplicit()) 51 !MI->getOperand(CheckStartIdx).isImplicit())
68 assert(ScratchIdx != e && "No scratch register available"); 72 assert(ScratchIdx != e && "No scratch register available");
69 return ScratchIdx; 73 return ScratchIdx;
70 } 74 }
71 75
72 StackMaps::StackMaps(AsmPrinter &AP) : AP(AP) { 76 StackMaps::StackMaps(AsmPrinter &AP) : AP(AP) {
73 if (StackMapVersion != 1) 77 if (StackMapVersion != 2)
74 llvm_unreachable("Unsupported stackmap version!"); 78 llvm_unreachable("Unsupported stackmap version!");
75 } 79 }
76 80
77 /// Go up the super-register chain until we hit a valid dwarf register number. 81 /// Go up the super-register chain until we hit a valid dwarf register number.
78 static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) { 82 static unsigned getDwarfRegNum(unsigned Reg, const TargetRegisterInfo *TRI) {
270 II->Reg = 0; // mark for deletion. 274 II->Reg = 0; // mark for deletion.
271 } 275 }
272 } 276 }
273 277
274 LiveOuts.erase( 278 LiveOuts.erase(
275 std::remove_if(LiveOuts.begin(), LiveOuts.end(), 279 remove_if(LiveOuts, [](const LiveOutReg &LO) { return LO.Reg == 0; }),
276 [](const LiveOutReg &LO) { return LO.Reg == 0; }),
277 LiveOuts.end()); 280 LiveOuts.end());
278 281
279 return LiveOuts; 282 return LiveOuts;
280 } 283 }
281 284
330 MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext); 333 MCSymbolRefExpr::create(AP.CurrentFnSymForSize, OutContext), OutContext);
331 334
332 CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations), 335 CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations),
333 std::move(LiveOuts)); 336 std::move(LiveOuts));
334 337
335 // Record the stack size of the current function. 338 // Record the stack size of the current function and update callsite count.
336 const MachineFrameInfo *MFI = AP.MF->getFrameInfo(); 339 const MachineFrameInfo &MFI = AP.MF->getFrameInfo();
337 const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo(); 340 const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo();
338 bool HasDynamicFrameSize = 341 bool HasDynamicFrameSize =
339 MFI->hasVarSizedObjects() || RegInfo->needsStackRealignment(*(AP.MF)); 342 MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(*(AP.MF));
340 FnStackSize[AP.CurrentFnSym] = 343 uint64_t FrameSize = HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize();
341 HasDynamicFrameSize ? UINT64_MAX : MFI->getStackSize(); 344
345 auto CurrentIt = FnInfos.find(AP.CurrentFnSym);
346 if (CurrentIt != FnInfos.end())
347 CurrentIt->second.RecordCount++;
348 else
349 FnInfos.insert(std::make_pair(AP.CurrentFnSym, FunctionInfo(FrameSize)));
342 } 350 }
343 351
344 void StackMaps::recordStackMap(const MachineInstr &MI) { 352 void StackMaps::recordStackMap(const MachineInstr &MI) {
345 assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap"); 353 assert(MI.getOpcode() == TargetOpcode::STACKMAP && "expected stackmap");
346 354
347 int64_t ID = MI.getOperand(0).getImm(); 355 StackMapOpers opers(&MI);
348 recordStackMapOpers(MI, ID, std::next(MI.operands_begin(), 2), 356 const int64_t ID = MI.getOperand(PatchPointOpers::IDPos).getImm();
357 recordStackMapOpers(MI, ID, std::next(MI.operands_begin(), opers.getVarIdx()),
349 MI.operands_end()); 358 MI.operands_end());
350 } 359 }
351 360
352 void StackMaps::recordPatchPoint(const MachineInstr &MI) { 361 void StackMaps::recordPatchPoint(const MachineInstr &MI) {
353 assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint"); 362 assert(MI.getOpcode() == TargetOpcode::PATCHPOINT && "expected patchpoint");
354 363
355 PatchPointOpers opers(&MI); 364 PatchPointOpers opers(&MI);
356 int64_t ID = opers.getMetaOper(PatchPointOpers::IDPos).getImm(); 365 const int64_t ID = opers.getID();
357
358 auto MOI = std::next(MI.operands_begin(), opers.getStackMapStartIdx()); 366 auto MOI = std::next(MI.operands_begin(), opers.getStackMapStartIdx());
359 recordStackMapOpers(MI, ID, MOI, MI.operands_end(), 367 recordStackMapOpers(MI, ID, MOI, MI.operands_end(),
360 opers.isAnyReg() && opers.hasDef()); 368 opers.isAnyReg() && opers.hasDef());
361 369
362 #ifndef NDEBUG 370 #ifndef NDEBUG
363 // verify anyregcc 371 // verify anyregcc
364 auto &Locations = CSInfos.back().Locations; 372 auto &Locations = CSInfos.back().Locations;
365 if (opers.isAnyReg()) { 373 if (opers.isAnyReg()) {
366 unsigned NArgs = opers.getMetaOper(PatchPointOpers::NArgPos).getImm(); 374 unsigned NArgs = opers.getNumCallArgs();
367 for (unsigned i = 0, e = (opers.hasDef() ? NArgs + 1 : NArgs); i != e; ++i) 375 for (unsigned i = 0, e = (opers.hasDef() ? NArgs + 1 : NArgs); i != e; ++i)
368 assert(Locations[i].Type == Location::Register && 376 assert(Locations[i].Type == Location::Register &&
369 "anyreg arg must be in reg."); 377 "anyreg arg must be in reg.");
370 } 378 }
371 #endif 379 #endif
382 } 390 }
383 391
384 /// Emit the stackmap header. 392 /// Emit the stackmap header.
385 /// 393 ///
386 /// Header { 394 /// Header {
387 /// uint8 : Stack Map Version (currently 1) 395 /// uint8 : Stack Map Version (currently 2)
388 /// uint8 : Reserved (expected to be 0) 396 /// uint8 : Reserved (expected to be 0)
389 /// uint16 : Reserved (expected to be 0) 397 /// uint16 : Reserved (expected to be 0)
390 /// } 398 /// }
391 /// uint32 : NumFunctions 399 /// uint32 : NumFunctions
392 /// uint32 : NumConstants 400 /// uint32 : NumConstants
396 OS.EmitIntValue(StackMapVersion, 1); // Version. 404 OS.EmitIntValue(StackMapVersion, 1); // Version.
397 OS.EmitIntValue(0, 1); // Reserved. 405 OS.EmitIntValue(0, 1); // Reserved.
398 OS.EmitIntValue(0, 2); // Reserved. 406 OS.EmitIntValue(0, 2); // Reserved.
399 407
400 // Num functions. 408 // Num functions.
401 DEBUG(dbgs() << WSMP << "#functions = " << FnStackSize.size() << '\n'); 409 DEBUG(dbgs() << WSMP << "#functions = " << FnInfos.size() << '\n');
402 OS.EmitIntValue(FnStackSize.size(), 4); 410 OS.EmitIntValue(FnInfos.size(), 4);
403 // Num constants. 411 // Num constants.
404 DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n'); 412 DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n');
405 OS.EmitIntValue(ConstPool.size(), 4); 413 OS.EmitIntValue(ConstPool.size(), 4);
406 // Num callsites. 414 // Num callsites.
407 DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n'); 415 DEBUG(dbgs() << WSMP << "#callsites = " << CSInfos.size() << '\n');
411 /// Emit the function frame record for each function. 419 /// Emit the function frame record for each function.
412 /// 420 ///
413 /// StkSizeRecord[NumFunctions] { 421 /// StkSizeRecord[NumFunctions] {
414 /// uint64 : Function Address 422 /// uint64 : Function Address
415 /// uint64 : Stack Size 423 /// uint64 : Stack Size
424 /// uint64 : Record Count
416 /// } 425 /// }
417 void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) { 426 void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) {
418 // Function Frame records. 427 // Function Frame records.
419 DEBUG(dbgs() << WSMP << "functions:\n"); 428 DEBUG(dbgs() << WSMP << "functions:\n");
420 for (auto const &FR : FnStackSize) { 429 for (auto const &FR : FnInfos) {
421 DEBUG(dbgs() << WSMP << "function addr: " << FR.first 430 DEBUG(dbgs() << WSMP << "function addr: " << FR.first
422 << " frame size: " << FR.second); 431 << " frame size: " << FR.second.StackSize
432 << " callsite count: " << FR.second.RecordCount << '\n');
423 OS.EmitSymbolValue(FR.first, 8); 433 OS.EmitSymbolValue(FR.first, 8);
424 OS.EmitIntValue(FR.second, 8); 434 OS.EmitIntValue(FR.second.StackSize, 8);
435 OS.EmitIntValue(FR.second.RecordCount, 8);
425 } 436 }
426 } 437 }
427 438
428 /// Emit the constant pool. 439 /// Emit the constant pool.
429 /// 440 ///
518 529
519 /// Serialize the stackmap data. 530 /// Serialize the stackmap data.
520 void StackMaps::serializeToStackMapSection() { 531 void StackMaps::serializeToStackMapSection() {
521 (void)WSMP; 532 (void)WSMP;
522 // Bail out if there's no stack map data. 533 // Bail out if there's no stack map data.
523 assert((!CSInfos.empty() || (CSInfos.empty() && ConstPool.empty())) && 534 assert((!CSInfos.empty() || ConstPool.empty()) &&
524 "Expected empty constant pool too!"); 535 "Expected empty constant pool too!");
525 assert((!CSInfos.empty() || (CSInfos.empty() && FnStackSize.empty())) && 536 assert((!CSInfos.empty() || FnInfos.empty()) &&
526 "Expected empty function record too!"); 537 "Expected empty function record too!");
527 if (CSInfos.empty()) 538 if (CSInfos.empty())
528 return; 539 return;
529 540
530 MCContext &OutContext = AP.OutStreamer->getContext(); 541 MCContext &OutContext = AP.OutStreamer->getContext();