llvm.org GIT mirror llvm / 9becdee
[Stackmap] Added callsite counts to emitted function information. Summary: It was previously not possible for tools to use solely the stackmap information emitted to reconstruct the return addresses of callsites in the map, which is necessary to use the information to walk a stack. This patch adds per-function callsite counts when emitting the stackmap section in order to resolve the problem. Note that this slightly alters the stackmap format, so external tools parsing these maps will need to be updated. **Problem Details:** Records only store their offset from the beginning of the function they belong to. While these records and the functions are output in program order, it is not possible to determine where the end of one function's records are without the callsite count when processing the records to compute return addresses. Patch by Kavon Farvardin! Reviewers: atrick, ributzka, sanjoy Subscribers: nemanjai Differential Revision: https://reviews.llvm.org/D23487 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281532 91177308-0d34-0410-b5e6-96231b3b80d8 Sanjoy Das 3 years ago
23 changed file(s) with 319 addition(s) and 68 deletion(s). Raw diff Collapse all Expand all
318318 .. code-block:: none
319319
320320 Header {
321 uint8 : Stack Map Version (current version is 1)
321 uint8 : Stack Map Version (current version is 2)
322322 uint8 : Reserved (expected to be 0)
323323 uint16 : Reserved (expected to be 0)
324324 }
328328 StkSizeRecord[NumFunctions] {
329329 uint64 : Function Address
330330 uint64 : Stack Size
331 uint64 : Record Count
331332 }
332333 Constants[NumConstants] {
333334 uint64 : LargeConstant
433434 the code. LLVM does not maintain any mapping between those values and
434435 any higher-level entity. The runtime must be able to interpret the
435436 stack map record given only the ID, offset, and the order of the
436 locations, which LLVM preserves.
437 locations, records, and functions, which LLVM preserves.
437438
438439 Note that this is quite different from the goal of debug information,
439440 which is a best-effort attempt to track the location of named
507508 some code for each backend. Today, only a subset of LLVM's backends
508509 are supported. The currently supported architectures are X86_64,
509510 PowerPC, and Aarch64.
510
218218 void reset() {
219219 CSInfos.clear();
220220 ConstPool.clear();
221 FnStackSize.clear();
221 FnInfos.clear();
222222 }
223223
224224 /// \brief Generate a stackmap record for a stackmap instruction.
242242 typedef SmallVector LocationVec;
243243 typedef SmallVector LiveOutVec;
244244 typedef MapVector ConstantPool;
245 typedef MapVector FnStackSizeMap;
245
246 struct FunctionInfo {
247 uint64_t StackSize;
248 uint64_t RecordCount;
249 FunctionInfo() : StackSize(0), RecordCount(1) {}
250 explicit FunctionInfo(uint64_t StackSize) : StackSize(StackSize), RecordCount(1) {}
251 };
246252
247253 struct CallsiteInfo {
248254 const MCExpr *CSOffsetExpr;
256262 LiveOuts(std::move(LiveOuts)) {}
257263 };
258264
265 typedef MapVector FnInfoMap;
259266 typedef std::vector CallsiteInfoList;
260267
261268 AsmPrinter ≈
262269 CallsiteInfoList CSInfos;
263270 ConstantPool ConstPool;
264 FnStackSizeMap FnStackSize;
271 FnInfoMap FnInfos;
265272
266273 MachineInstr::const_mop_iterator
267274 parseOperand(MachineInstr::const_mop_iterator MOI,
1616 namespace llvm {
1717
1818 template
19 class StackMapV1Parser {
19 class StackMapV2Parser {
2020 public:
2121
2222 template
4646
4747 /// Accessor for function records.
4848 class FunctionAccessor {
49 friend class StackMapV1Parser;
49 friend class StackMapV2Parser;
5050 public:
5151
5252 /// Get the function address.
5555 }
5656
5757 /// Get the function's stack size.
58 uint32_t getStackSize() const {
58 uint64_t getStackSize() const {
5959 return read(P + sizeof(uint64_t));
6060 }
61
62 /// Get the number of callsite records.
63 uint64_t getRecordCount() const {
64 return read(P + (2 * sizeof(uint64_t)));
65 }
6166
6267 private:
6368 FunctionAccessor(const uint8_t *P) : P(P) {}
6469
65 const static int FunctionAccessorSize = 2 * sizeof(uint64_t);
70 const static int FunctionAccessorSize = 3 * sizeof(uint64_t);
6671
6772 FunctionAccessor next() const {
6873 return FunctionAccessor(P + FunctionAccessorSize);
7378
7479 /// Accessor for constants.
7580 class ConstantAccessor {
76 friend class StackMapV1Parser;
81 friend class StackMapV2Parser;
7782 public:
7883
7984 /// Return the value of this constant.
102107
103108 /// Accessor for location records.
104109 class LocationAccessor {
105 friend class StackMapV1Parser;
110 friend class StackMapV2Parser;
106111 friend class RecordAccessor;
107112 public:
108113
155160
156161 /// Accessor for stackmap live-out fields.
157162 class LiveOutAccessor {
158 friend class StackMapV1Parser;
163 friend class StackMapV2Parser;
159164 friend class RecordAccessor;
160165 public:
161166
187192
188193 /// Accessor for stackmap records.
189194 class RecordAccessor {
190 friend class StackMapV1Parser;
195 friend class StackMapV2Parser;
191196 public:
192197
193198 typedef AccessorIterator location_iterator;
291296 const uint8_t *P;
292297 };
293298
294 /// Construct a parser for a version-1 stackmap. StackMap data will be read
299 /// Construct a parser for a version-2 stackmap. StackMap data will be read
295300 /// from the given array.
296 StackMapV1Parser(ArrayRef StackMapSection)
301 StackMapV2Parser(ArrayRef StackMapSection)
297302 : StackMapSection(StackMapSection) {
298303 ConstantsListOffset = FunctionListOffset + getNumFunctions() * FunctionSize;
299304
300 assert(StackMapSection[0] == 1 &&
301 "StackMapV1Parser can only parse version 1 stackmaps");
305 assert(StackMapSection[0] == 2 &&
306 "StackMapV2Parser can only parse version 2 stackmaps");
302307
303308 unsigned CurrentRecordOffset =
304309 ConstantsListOffset + getNumConstants() * ConstantSize;
314319 typedef AccessorIterator constant_iterator;
315320 typedef AccessorIterator record_iterator;
316321
317 /// Get the version number of this stackmap. (Always returns 1).
318 unsigned getVersion() const { return 1; }
322 /// Get the version number of this stackmap. (Always returns 2).
323 unsigned getVersion() const { return 2; }
319324
320325 /// Get the number of functions in the stack map.
321326 uint32_t getNumFunctions() const {
419424 static const unsigned NumRecordsOffset = NumConstantsOffset + sizeof(uint32_t);
420425 static const unsigned FunctionListOffset = NumRecordsOffset + sizeof(uint32_t);
421426
422 static const unsigned FunctionSize = 2 * sizeof(uint64_t);
427 static const unsigned FunctionSize = 3 * sizeof(uint64_t);
423428 static const unsigned ConstantSize = sizeof(uint64_t);
424429
425430 std::size_t getFunctionOffset(unsigned FunctionIndex) const {
2929 #define DEBUG_TYPE "stackmaps"
3030
3131 static cl::opt StackMapVersion(
32 "stackmap-version", cl::init(1),
33 cl::desc("Specify the stackmap encoding version (default = 1)"));
32 "stackmap-version", cl::init(2),
33 cl::desc("Specify the stackmap encoding version (default = 2)"));
3434
3535 const char *StackMaps::WSMP = "Stack Maps: ";
3636
7373 }
7474
7575 StackMaps::StackMaps(AsmPrinter &AP) : AP(AP) {
76 if (StackMapVersion != 1)
76 if (StackMapVersion != 2)
7777 llvm_unreachable("Unsupported stackmap version!");
7878 }
7979
334334 CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations),
335335 std::move(LiveOuts));
336336
337 // Record the stack size of the current function.
337 // Record the stack size of the current function and update callsite count.
338338 const MachineFrameInfo &MFI = AP.MF->getFrameInfo();
339339 const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo();
340340 bool HasDynamicFrameSize =
341341 MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(*(AP.MF));
342 FnStackSize[AP.CurrentFnSym] =
343 HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize();
342 uint64_t FrameSize = HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize();
343
344 auto CurrentIt = FnInfos.find(AP.CurrentFnSym);
345 if (CurrentIt != FnInfos.end())
346 CurrentIt->second.RecordCount++;
347 else
348 FnInfos.insert(std::make_pair(AP.CurrentFnSym, FunctionInfo(FrameSize)));
344349 }
345350
346351 void StackMaps::recordStackMap(const MachineInstr &MI) {
386391 /// Emit the stackmap header.
387392 ///
388393 /// Header {
389 /// uint8 : Stack Map Version (currently 1)
394 /// uint8 : Stack Map Version (currently 2)
390395 /// uint8 : Reserved (expected to be 0)
391396 /// uint16 : Reserved (expected to be 0)
392397 /// }
400405 OS.EmitIntValue(0, 2); // Reserved.
401406
402407 // Num functions.
403 DEBUG(dbgs() << WSMP << "#functions = " << FnStackSize.size() << '\n');
404 OS.EmitIntValue(FnStackSize.size(), 4);
408 DEBUG(dbgs() << WSMP << "#functions = " << FnInfos.size() << '\n');
409 OS.EmitIntValue(FnInfos.size(), 4);
405410 // Num constants.
406411 DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n');
407412 OS.EmitIntValue(ConstPool.size(), 4);
415420 /// StkSizeRecord[NumFunctions] {
416421 /// uint64 : Function Address
417422 /// uint64 : Stack Size
423 /// uint64 : Record Count
418424 /// }
419425 void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) {
420426 // Function Frame records.
421427 DEBUG(dbgs() << WSMP << "functions:\n");
422 for (auto const &FR : FnStackSize) {
428 for (auto const &FR : FnInfos) {
423429 DEBUG(dbgs() << WSMP << "function addr: " << FR.first
424 << " frame size: " << FR.second);
430 << " frame size: " << FR.second.StackSize
431 << " callsite count: " << FR.second.RecordCount << '\n');
425432 OS.EmitSymbolValue(FR.first, 8);
426 OS.EmitIntValue(FR.second, 8);
433 OS.EmitIntValue(FR.second.StackSize, 8);
434 OS.EmitIntValue(FR.second.RecordCount, 8);
427435 }
428436 }
429437
524532 // Bail out if there's no stack map data.
525533 assert((!CSInfos.empty() || ConstPool.empty()) &&
526534 "Expected empty constant pool too!");
527 assert((!CSInfos.empty() || FnStackSize.empty()) &&
535 assert((!CSInfos.empty() || FnInfos.empty()) &&
528536 "Expected empty function record too!");
529537 if (CSInfos.empty())
530538 return;
33 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
44 ; CHECK-NEXT: __LLVM_StackMaps:
55 ; Header
6 ; CHECK-NEXT: .byte 1
6 ; CHECK-NEXT: .byte 2
77 ; CHECK-NEXT: .byte 0
88 ; CHECK-NEXT: .short 0
99 ; Num Functions
1616 ; Functions and stack size
1717 ; CHECK-NEXT: .quad _test
1818 ; CHECK-NEXT: .quad 16
19 ; CHECK-NEXT: .quad 1
1920 ; CHECK-NEXT: .quad _property_access1
2021 ; CHECK-NEXT: .quad 16
22 ; CHECK-NEXT: .quad 1
2123 ; CHECK-NEXT: .quad _property_access2
2224 ; CHECK-NEXT: .quad 32
25 ; CHECK-NEXT: .quad 1
2326 ; CHECK-NEXT: .quad _property_access3
2427 ; CHECK-NEXT: .quad 32
28 ; CHECK-NEXT: .quad 1
2529 ; CHECK-NEXT: .quad _anyreg_test1
2630 ; CHECK-NEXT: .quad 16
31 ; CHECK-NEXT: .quad 1
2732 ; CHECK-NEXT: .quad _anyreg_test2
2833 ; CHECK-NEXT: .quad 16
34 ; CHECK-NEXT: .quad 1
2935 ; CHECK-NEXT: .quad _patchpoint_spilldef
3036 ; CHECK-NEXT: .quad 112
37 ; CHECK-NEXT: .quad 1
3138 ; CHECK-NEXT: .quad _patchpoint_spillargs
3239 ; CHECK-NEXT: .quad 128
40 ; CHECK-NEXT: .quad 1
3341
3442
3543 ; test
99 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
1010 ; CHECK-NEXT: __LLVM_StackMaps:
1111 ; Header
12 ; CHECK-NEXT: .byte 1
12 ; CHECK-NEXT: .byte 2
1313 ; CHECK-NEXT: .byte 0
1414 ; CHECK-NEXT: .short 0
1515 ; Num Functions
2222 ; Functions and stack size
2323 ; CHECK-NEXT: .quad _constantargs
2424 ; CHECK-NEXT: .quad 16
25 ; CHECK-NEXT: .quad 1
2526 ; CHECK-NEXT: .quad _osrinline
2627 ; CHECK-NEXT: .quad 32
28 ; CHECK-NEXT: .quad 1
2729 ; CHECK-NEXT: .quad _osrcold
2830 ; CHECK-NEXT: .quad 16
31 ; CHECK-NEXT: .quad 1
2932 ; CHECK-NEXT: .quad _propertyRead
3033 ; CHECK-NEXT: .quad 16
34 ; CHECK-NEXT: .quad 1
3135 ; CHECK-NEXT: .quad _propertyWrite
3236 ; CHECK-NEXT: .quad 16
37 ; CHECK-NEXT: .quad 1
3338 ; CHECK-NEXT: .quad _jsVoidCall
3439 ; CHECK-NEXT: .quad 16
40 ; CHECK-NEXT: .quad 1
3541 ; CHECK-NEXT: .quad _jsIntCall
3642 ; CHECK-NEXT: .quad 16
43 ; CHECK-NEXT: .quad 1
3744 ; CHECK-NEXT: .quad _spilledValue
3845 ; CHECK-NEXT: .quad 160
46 ; CHECK-NEXT: .quad 1
3947 ; CHECK-NEXT: .quad _spilledStackMapValue
4048 ; CHECK-NEXT: .quad 128
49 ; CHECK-NEXT: .quad 1
4150 ; CHECK-NEXT: .quad _liveConstant
4251 ; CHECK-NEXT: .quad 16
52 ; CHECK-NEXT: .quad 1
4353 ; CHECK-NEXT: .quad _clobberLR
4454 ; CHECK-NEXT: .quad 112
55 ; CHECK-NEXT: .quad 1
4556
4657 ; Num LargeConstants
4758 ; CHECK-NEXT: .quad 4294967295
44 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
55 ; CHECK-NEXT: __LLVM_StackMaps:
66 ; Header
7 ; CHECK-NEXT: .byte 1
7 ; CHECK-NEXT: .byte 2
88 ; CHECK-NEXT: .byte 0
99 ; CHECK-NEXT: .short 0
1010 ; Num Functions
4343 }
4444
4545 declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
46
3030 ; CHECK-LABEL: .section .llvm_stackmaps
3131 ; CHECK-NEXT: __LLVM_StackMaps:
3232 ; Header
33 ; CHECK-NEXT: .byte 1
33 ; CHECK-NEXT: .byte 2
3434 ; CHECK-NEXT: .byte 0
3535 ; CHECK-NEXT: .short 0
3636 ; Num Functions
4343 ; Functions and stack size
4444 ; CHECK-NEXT: .quad test
4545 ; CHECK-NEXT: .quad 128
46 ; CHECK-NEXT: .quad 1
4647 ; CHECK-NEXT: .quad property_access1
4748 ; CHECK-NEXT: .quad 128
49 ; CHECK-NEXT: .quad 1
4850 ; CHECK-NEXT: .quad property_access2
4951 ; CHECK-NEXT: .quad 128
52 ; CHECK-NEXT: .quad 1
5053 ; CHECK-NEXT: .quad property_access3
5154 ; CHECK-NEXT: .quad 128
55 ; CHECK-NEXT: .quad 1
5256 ; CHECK-NEXT: .quad anyreg_test1
5357 ; CHECK-NEXT: .quad 144
58 ; CHECK-NEXT: .quad 1
5459 ; CHECK-NEXT: .quad anyreg_test2
5560 ; CHECK-NEXT: .quad 144
61 ; CHECK-NEXT: .quad 1
5662 ; CHECK-NEXT: .quad patchpoint_spilldef
5763 ; CHECK-NEXT: .quad 256
64 ; CHECK-NEXT: .quad 1
5865 ; CHECK-NEXT: .quad patchpoint_spillargs
5966 ; CHECK-NEXT: .quad 288
67 ; CHECK-NEXT: .quad 1
6068
6169
6270 ; test
4343 ; CHECK-LABEL: .section .llvm_stackmaps
4444 ; CHECK-NEXT: __LLVM_StackMaps:
4545 ; Header
46 ; CHECK-NEXT: .byte 1
46 ; CHECK-NEXT: .byte 2
4747 ; CHECK-NEXT: .byte 0
4848 ; CHECK-NEXT: .short 0
4949 ; Num Functions
5656 ; Functions and stack size
5757 ; CHECK-NEXT: .quad constantargs
5858 ; CHECK-NEXT: .quad 128
59 ; CHECK-NEXT: .quad 1
5960 ; CHECK-NEXT: .quad osrinline
6061 ; CHECK-NEXT: .quad 144
62 ; CHECK-NEXT: .quad 1
6163 ; CHECK-NEXT: .quad osrcold
6264 ; CHECK-NEXT: .quad 128
65 ; CHECK-NEXT: .quad 1
6366 ; CHECK-NEXT: .quad propertyRead
6467 ; CHECK-NEXT: .quad 128
68 ; CHECK-NEXT: .quad 1
6569 ; CHECK-NEXT: .quad propertyWrite
6670 ; CHECK-NEXT: .quad 128
71 ; CHECK-NEXT: .quad 1
6772 ; CHECK-NEXT: .quad jsVoidCall
6873 ; CHECK-NEXT: .quad 128
74 ; CHECK-NEXT: .quad 1
6975 ; CHECK-NEXT: .quad jsIntCall
7076 ; CHECK-NEXT: .quad 128
77 ; CHECK-NEXT: .quad 1
7178 ; CHECK-NEXT: .quad spilledValue
7279 ; CHECK-NEXT: .quad 304
80 ; CHECK-NEXT: .quad 1
7381 ; CHECK-NEXT: .quad spilledStackMapValue
7482 ; CHECK-NEXT: .quad 224
83 ; CHECK-NEXT: .quad 1
7584 ; CHECK-NEXT: .quad liveConstant
7685 ; CHECK-NEXT: .quad 64
86 ; CHECK-NEXT: .quad 1
7787 ; CHECK-NEXT: .quad clobberLR
7888 ; CHECK-NEXT: .quad 208
89 ; CHECK-NEXT: .quad 1
7990
8091 ; Num LargeConstants
8192 ; CHECK-NEXT: .quad 4294967295
66 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
77 ; CHECK-NEXT: __LLVM_StackMaps:
88 ; Header
9 ; CHECK-NEXT: .byte 1
9 ; CHECK-NEXT: .byte 2
1010 ; CHECK-NEXT: .byte 0
1111 ; CHECK-NEXT: .short 0
1212 ; Num Functions
1919 ; Functions and stack size
2020 ; CHECK-NEXT: .quad _test
2121 ; CHECK-NEXT: .quad 8
22 ; CHECK-NEXT: .quad 1
2223 ; CHECK-NEXT: .quad _property_access1
2324 ; CHECK-NEXT: .quad 8
25 ; CHECK-NEXT: .quad 1
2426 ; CHECK-NEXT: .quad _property_access2
2527 ; CHECK-NEXT: .quad 24
28 ; CHECK-NEXT: .quad 1
2629 ; CHECK-NEXT: .quad _property_access3
2730 ; CHECK-NEXT: .quad 24
31 ; CHECK-NEXT: .quad 1
2832 ; CHECK-NEXT: .quad _anyreg_test1
2933 ; CHECK-NEXT: .quad 56
34 ; CHECK-NEXT: .quad 1
3035 ; CHECK-NEXT: .quad _anyreg_test2
3136 ; CHECK-NEXT: .quad 56
37 ; CHECK-NEXT: .quad 1
3238 ; CHECK-NEXT: .quad _patchpoint_spilldef
3339 ; CHECK-NEXT: .quad 56
40 ; CHECK-NEXT: .quad 1
3441 ; CHECK-NEXT: .quad _patchpoint_spillargs
3542 ; CHECK-NEXT: .quad 88
43 ; CHECK-NEXT: .quad 1
3644
3745 ; No constants
3846
4444 ; Verify that the stackmap section got emitted:
4545 ; CHECK-LABEL: __LLVM_StackMaps:
4646 ; Header
47 ; CHECK-NEXT: .byte 1
47 ; CHECK-NEXT: .byte 2
4848 ; CHECK-NEXT: .byte 0
4949 ; CHECK-NEXT: .short 0
5050 ; Num Functions
33 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
44 ; CHECK-NEXT: __LLVM_StackMaps:
55 ; Header
6 ; CHECK-NEXT: .byte 1
6 ; CHECK-NEXT: .byte 2
77 ; CHECK-NEXT: .byte 0
88 ; CHECK-NEXT: .short 0
99 ; Num Functions
1616 ; Functions and stack size
1717 ; CHECK-NEXT: .quad _constantargs
1818 ; CHECK-NEXT: .quad 8
19 ; CHECK-NEXT: .quad 1
1920 ; CHECK-NEXT: .quad _liveConstant
2021 ; CHECK-NEXT: .quad 8
22 ; CHECK-NEXT: .quad 1
2123 ; CHECK-NEXT: .quad _directFrameIdx
2224 ; CHECK-NEXT: .quad 40
25 ; CHECK-NEXT: .quad 1
2326 ; CHECK-NEXT: .quad _longid
2427 ; CHECK-NEXT: .quad 8
28 ; CHECK-NEXT: .quad 4
2529
2630 ; Large Constants
2731 ; CHECK-NEXT: .quad 2147483648
22 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
33 ; CHECK-NEXT: __LLVM_StackMaps:
44 ; version
5 ; CHECK-NEXT: .byte 1
5 ; CHECK-NEXT: .byte 2
66 ; reserved
77 ; CHECK-NEXT: .byte 0
88 ; reserved
1616 ; function address & stack size
1717 ; CHECK-NEXT: .quad _foo
1818 ; CHECK-NEXT: .quad 8
19 ; CHECK-NEXT: .quad 1
1920 ; function address & stack size
2021 ; CHECK-NEXT: .quad _bar
2122 ; CHECK-NEXT: .quad 8
23 ; CHECK-NEXT: .quad 1
2224
2325 ; Constants Array:
2426 ; CHECK-NEXT: .quad 9223372036854775807
55 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
66 ; CHECK-NEXT: __LLVM_StackMaps:
77 ; Header
8 ; CHECK-NEXT: .byte 1
8 ; CHECK-NEXT: .byte 2
99 ; CHECK-NEXT: .byte 0
1010 ; CHECK-NEXT: .short 0
1111 ; Num Functions
1818 ; Functions and stack size
1919 ; CHECK-NEXT: .quad _stackmap_liveness
2020 ; CHECK-NEXT: .quad 8
21 ; CHECK-NEXT: .quad 3
2122 ; CHECK-NEXT: .quad _mixed_liveness
2223 ; CHECK-NEXT: .quad 8
24 ; CHECK-NEXT: .quad 2
2325
2426 define void @stackmap_liveness() {
2527 entry:
44 ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps
55 ; CHECK-NEXT: __LLVM_StackMaps:
66 ; Header
7 ; CHECK-NEXT: .byte 1
7 ; CHECK-NEXT: .byte 2
88 ; CHECK-NEXT: .byte 0
99 ; CHECK-NEXT: .short 0
1010 ; Num Functions
1717 ; Functions and stack size
1818 ; CHECK-NEXT: .quad _constantargs
1919 ; CHECK-NEXT: .quad 8
20 ; CHECK-NEXT: .quad 1
2021 ; CHECK-NEXT: .quad _osrinline
2122 ; CHECK-NEXT: .quad 24
23 ; CHECK-NEXT: .quad 1
2224 ; CHECK-NEXT: .quad _osrcold
2325 ; CHECK-NEXT: .quad 8
26 ; CHECK-NEXT: .quad 1
2427 ; CHECK-NEXT: .quad _propertyRead
2528 ; CHECK-NEXT: .quad 8
29 ; CHECK-NEXT: .quad 1
2630 ; CHECK-NEXT: .quad _propertyWrite
2731 ; CHECK-NEXT: .quad 8
32 ; CHECK-NEXT: .quad 1
2833 ; CHECK-NEXT: .quad _jsVoidCall
2934 ; CHECK-NEXT: .quad 8
35 ; CHECK-NEXT: .quad 1
3036 ; CHECK-NEXT: .quad _jsIntCall
3137 ; CHECK-NEXT: .quad 8
38 ; CHECK-NEXT: .quad 1
3239 ; CHECK-NEXT: .quad _spilledValue
3340 ; CHECK-NEXT: .quad 56
41 ; CHECK-NEXT: .quad 1
3442 ; CHECK-NEXT: .quad _spilledStackMapValue
3543 ; CHECK-NEXT: .quad 56
44 ; CHECK-NEXT: .quad 1
3645 ; CHECK-NEXT: .quad _spillSubReg
3746 ; CHECK-NEXT: .quad 56
47 ; CHECK-NEXT: .quad 1
3848 ; CHECK-NEXT: .quad _subRegOffset
3949 ; CHECK-NEXT: .quad 56
50 ; CHECK-NEXT: .quad 1
4051 ; CHECK-NEXT: .quad _liveConstant
4152 ; CHECK-NEXT: .quad 8
53 ; CHECK-NEXT: .quad 1
4254 ; CHECK-NEXT: .quad _directFrameIdx
4355 ; CHECK-NEXT: .quad 56
56 ; CHECK-NEXT: .quad 2
4457 ; CHECK-NEXT: .quad _longid
4558 ; CHECK-NEXT: .quad 8
59 ; CHECK-NEXT: .quad 4
4660 ; CHECK-NEXT: .quad _clobberScratch
4761 ; CHECK-NEXT: .quad 56
62 ; CHECK-NEXT: .quad 1
4863 ; CHECK-NEXT: .quad _needsStackRealignment
4964 ; CHECK-NEXT: .quad -1
65 ; CHECK-NEXT: .quad 1
5066
5167 ; Large Constants
5268 ; CHECK-NEXT: .quad 2147483648
4747 ; CHECK-LABEL: .section .llvm_stackmaps
4848 ; CHECK-NEXT: __LLVM_StackMaps:
4949 ; Header
50 ; CHECK-NEXT: .byte 1
50 ; CHECK-NEXT: .byte 2
5151 ; CHECK-NEXT: .byte 0
5252 ; CHECK-NEXT: .short 0
5353 ; Num Functions
6060 ; Functions and stack size
6161 ; CHECK-NEXT: .quad test
6262 ; CHECK-NEXT: .quad 8
63 ; CHECK-NEXT: .quad 1
6364 ; CHECK-NEXT: .quad test2
6465 ; CHECK-NEXT: .quad 8
66 ; CHECK-NEXT: .quad 1
6567
6668 ; Large Constants
6769 ; Statepoint ID only
126128 ; CHECK: .short 0
127129 ; CHECK: .short 0
128130 ; CHECK: .p2align 3
129
7878 ; CHECK-LABEL: .section .llvm_stackmaps
7979 ; CHECK-NEXT: __LLVM_StackMaps:
8080 ; Header
81 ; CHECK-NEXT: .byte 1
81 ; CHECK-NEXT: .byte 2
8282 ; CHECK-NEXT: .byte 0
8383 ; CHECK-NEXT: .short 0
8484 ; Num Functions
9191 ; Functions and stack size
9292 ; CHECK-NEXT: .quad test
9393 ; CHECK-NEXT: .quad 40
94 ; CHECK-NEXT: .quad 1
9495 ; CHECK-NEXT: .quad test_derived_arg
9596 ; CHECK-NEXT: .quad 40
97 ; CHECK-NEXT: .quad 1
9698 ; CHECK-NEXT: .quad test_id
9799 ; CHECK-NEXT: .quad 8
100 ; CHECK-NEXT: .quad 1
98101
99102 ;
100103 ; test
275278 ; CHECK: .short 0
276279 ; CHECK: .short 0
277280 ; CHECK: .p2align 3
278
0 RUN: llvm-readobj -stackmap %p/Inputs/stackmap-test.macho-x86-64 | FileCheck %s
11
2 CHECK: LLVM StackMap Version: 1
3 CHECK-NEXT: Num Functions: 1
4 CHECK-NEXT: Function address: 0, stack size: 16
5 CHECK-NEXT: Num Constants: 1
6 CHECK-NEXT: #1: 10000000000
7 CHECK-NEXT: Num Records: 1
8 CHECK-NEXT: Record ID: 2, instruction offset: 1
9 CHECK-NEXT: 5 locations:
2 ; Note: the macho object file in this test was generated in the following way:
3 ; llc -mtriple=x86_64-apple-darwin %p/test/CodeGen/X86/stackmap.ll -o stackmap.s
4 ; clang -c stackmap.s -o %p/test/Object/Inputs/stackmap-test.macho-x86-64
5
6 CHECK: LLVM StackMap Version: 2
7 CHECK-NEXT: Num Functions: 16
8 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1
9 CHECK-NEXT: Function address: 0, stack size: 24, callsite record count: 1
10 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1
11 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1
12 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1
13 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1
14 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1
15 CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1
16 CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1
17 CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1
18 CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1
19 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1
20 CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 2
21 CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 4
22 CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1
23 CHECK-NEXT: Function address: 0, stack size: 18446744073709551615, callsite record count: 1
24 CHECK-NEXT: Num Constants: 3
25 CHECK-NEXT: #1: 2147483648
26 CHECK-NEXT: #2: 4294967295
27 CHECK-NEXT: #3: 4294967296
28 CHECK-NEXT: Num Records: 20
29 CHECK-NEXT: Record ID: 1, instruction offset: 4
30 CHECK-NEXT: 12 locations:
31 CHECK-NEXT: #1: Constant 4294967295
32 CHECK-NEXT: #2: Constant 4294967295
33 CHECK-NEXT: #3: Constant 65536
34 CHECK-NEXT: #4: Constant 2000000000
35 CHECK-NEXT: #5: Constant 2147483647
36 CHECK-NEXT: #6: Constant 4294967295
37 CHECK-NEXT: #7: Constant 4294967295
38 CHECK-NEXT: #8: Constant 0
39 CHECK-NEXT: #9: ConstantIndex #0 (2147483648)
40 CHECK-NEXT: #10: ConstantIndex #1 (4294967295)
41 CHECK-NEXT: #11: ConstantIndex #2 (4294967296)
42 CHECK-NEXT: #12: Constant 4294967295
43 CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ]
44
45 CHECK: Record ID: 3, instruction offset: 22
46 CHECK-NEXT: 2 locations:
47 CHECK-NEXT: #1: Register R#3
48 CHECK-NEXT: #2: Register R#14
49 CHECK-NEXT: 0 live-outs: [ ]
50
51 CHECK: Record ID: 4, instruction offset: 10
52 CHECK-NEXT: 2 locations:
1053 CHECK-NEXT: #1: Register R#5
11 CHECK-NEXT: #2: Constant 10
12 CHECK-NEXT: #3: ConstantIndex #0 (10000000000)
13 CHECK-NEXT: #4: Direct R#4 + -8
14 CHECK-NEXT: #5: Indirect [R#6 + -16]
54 CHECK-NEXT: #2: Register R#4
55 CHECK-NEXT: 0 live-outs: [ ]
56
57 CHECK: Record ID: 5, instruction offset: 4
58 CHECK-NEXT: 2 locations:
59 CHECK-NEXT: #1: Register R#0
60 CHECK-NEXT: #2: Register R#5
61 CHECK-NEXT: 2 live-outs: [ R#0 (8-bytes) R#7 (8-bytes) ]
62
63 CHECK: Record ID: 6, instruction offset: 4
64 CHECK-NEXT: 2 locations:
65 CHECK-NEXT: #1: Register R#4
66 CHECK-NEXT: #2: Register R#2
1567 CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ]
68
69 CHECK: Record ID: 7, instruction offset: 10
70 CHECK-NEXT: 2 locations:
71 CHECK-NEXT: #1: Register R#2
72 CHECK-NEXT: #2: Register R#8
73 CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ]
74
75 CHECK: Record ID: 8, instruction offset: 10
76 CHECK-NEXT: 2 locations:
77 CHECK-NEXT: #1: Register R#2
78 CHECK-NEXT: #2: Register R#8
79 CHECK-NEXT: 2 live-outs: [ R#0 (8-bytes) R#7 (8-bytes) ]
80
81 CHECK: Record ID: 11, instruction offset: 42
82 CHECK-NEXT: 17 locations:
83 CHECK-NEXT: #1: Register R#9
84 CHECK-NEXT: #2: Register R#14
85 CHECK-NEXT: #3: Register R#10
86 CHECK-NEXT: #4: Register R#3
87 CHECK-NEXT: #5: Register R#0
88 CHECK-NEXT: #6: Register R#13
89 CHECK-NEXT: #7: Register R#12
90 CHECK-NEXT: #8: Register R#15
91 CHECK-NEXT: #9: Indirect [R#6 + 72]
92 CHECK-NEXT: #10: Indirect [R#6 + 80]
93 CHECK-NEXT: #11: Indirect [R#6 + 88]
94 CHECK-NEXT: #12: Indirect [R#6 + 96]
95 CHECK-NEXT: #13: Indirect [R#6 + 104]
96 CHECK-NEXT: #14: Indirect [R#6 + 112]
97 CHECK-NEXT: #15: Indirect [R#6 + 120]
98 CHECK-NEXT: #16: Indirect [R#6 + 128]
99 CHECK-NEXT: #17: Indirect [R#6 + 136]
100 CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ]
101
102 CHECK: Record ID: 12, instruction offset: 62
103 CHECK-NEXT: 17 locations:
104 CHECK-NEXT: #1: Register R#0
105 CHECK-NEXT: #2: Register R#14
106 CHECK-NEXT: #3: Register R#10
107 CHECK-NEXT: #4: Register R#9
108 CHECK-NEXT: #5: Register R#8
109 CHECK-NEXT: #6: Register R#4
110 CHECK-NEXT: #7: Register R#1
111 CHECK-NEXT: #8: Register R#2
112 CHECK-NEXT: #9: Register R#5
113 CHECK-NEXT: #10: Register R#3
114 CHECK-NEXT: #11: Register R#13
115 CHECK-NEXT: #12: Register R#12
116 CHECK-NEXT: #13: Register R#15
117 CHECK-NEXT: #14: Indirect [R#6 + 112]
118 CHECK-NEXT: #15: Indirect [R#6 + 120]
119 CHECK-NEXT: #16: Indirect [R#6 + 128]
120 CHECK-NEXT: #17: Indirect [R#6 + 136]
121 CHECK-NEXT: 0 live-outs: [ ]
122
123 CHECK: Record ID: 13, instruction offset: 50
124 CHECK-NEXT: 1 locations:
125 CHECK-NEXT: #1: Indirect [R#6 + -48]
126 CHECK-NEXT: 0 live-outs: [ ]
127
128 CHECK: Record ID: 14, instruction offset: 24
129 CHECK-NEXT: 2 locations:
130 CHECK-NEXT: #1: Register R#0
131 CHECK-NEXT: #2: Register R#3
132 CHECK-NEXT: 0 live-outs: [ ]
133
134 CHECK: Record ID: 15, instruction offset: 4
135 CHECK-NEXT: 1 locations:
136 CHECK-NEXT: #1: Constant 33
137 CHECK-NEXT: 0 live-outs: [ ]
138
139 CHECK: Record ID: 16, instruction offset: 32
140 CHECK-NEXT: 1 locations:
141 CHECK-NEXT: #1: Direct R#6 + -32
142 CHECK-NEXT: 0 live-outs: [ ]
143
144 CHECK: Record ID: 17, instruction offset: 32
145 CHECK-NEXT: 2 locations:
146 CHECK-NEXT: #1: Direct R#6 + -8
147 CHECK-NEXT: #2: Direct R#6 + -40
148 CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ]
149
150 CHECK: Record ID: 4294967295, instruction offset: 4
151 CHECK-NEXT: 0 locations:
152 CHECK-NEXT: 0 live-outs: [ ]
153
154 CHECK: Record ID: 4294967296, instruction offset: 4
155 CHECK-NEXT: 0 locations:
156 CHECK-NEXT: 0 live-outs: [ ]
157
158 CHECK: Record ID: 9223372036854775807, instruction offset: 4
159 CHECK-NEXT: 0 locations:
160 CHECK-NEXT: 0 live-outs: [ ]
161
162 CHECK: Record ID: 18446744073709551615, instruction offset: 4
163 CHECK-NEXT: 0 locations:
164 CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ]
165
166 CHECK: Record ID: 16, instruction offset: 18
167 CHECK-NEXT: 1 locations:
168 CHECK-NEXT: #1: Indirect [R#6 + -44]
169 CHECK-NEXT: 0 live-outs: [ ]
170
171 CHECK: Record ID: 0, instruction offset: 26
172 CHECK-NEXT: 0 locations:
173 CHECK-NEXT: 0 live-outs: [ ]
15261526 if (Obj->isLittleEndian())
15271527 prettyPrintStackMap(
15281528 llvm::outs(),
1529 StackMapV1Parser(StackMapContentsArray));
1529 StackMapV2Parser(StackMapContentsArray));
15301530 else
15311531 prettyPrintStackMap(llvm::outs(),
1532 StackMapV1Parser(StackMapContentsArray));
1532 StackMapV2Parser(StackMapContentsArray));
15331533 }
15341534
15351535 void llvm::dumpCodeViewMergedTypes(
23652365 ArrayRef StackMapContentsArray =
23662366 unwrapOrError(Obj->getSectionContents(StackMapSection));
23672367
2368 prettyPrintStackMap(llvm::outs(), StackMapV1Parser(
2368 prettyPrintStackMap(llvm::outs(), StackMapV2Parser(
23692369 StackMapContentsArray));
23702370 }
23712371
668668 if (Obj->isLittleEndian())
669669 prettyPrintStackMap(
670670 llvm::outs(),
671 StackMapV1Parser(StackMapContentsArray));
671 StackMapV2Parser(StackMapContentsArray));
672672 else
673673 prettyPrintStackMap(llvm::outs(),
674 StackMapV1Parser(StackMapContentsArray));
674 StackMapV2Parser(StackMapContentsArray));
675675 }
676676
677677 void MachODumper::printMachODataInCode() {
2323 // Functions:
2424 for (const auto &F : SMP.functions())
2525 OS << "\n Function address: " << F.getFunctionAddress()
26 << ", stack size: " << F.getStackSize();
26 << ", stack size: " << F.getStackSize()
27 << ", callsite record count: " << F.getRecordCount();
2728
2829 // Constants:
2930 OS << "\nNum Constants: " << SMP.getNumConstants();