Index: docs/StackMaps.rst =================================================================== --- docs/StackMaps.rst +++ docs/StackMaps.rst @@ -329,6 +329,7 @@ StkSizeRecord[NumFunctions] { uint64 : Function Address uint64 : Stack Size + uint64 : Record Count } Constants[NumConstants] { uint64 : LargeConstant @@ -434,7 +435,7 @@ the code. LLVM does not maintain any mapping between those values and any higher-level entity. The runtime must be able to interpret the stack map record given only the ID, offset, and the order of the -locations, which LLVM preserves. +locations, records, and functions, which LLVM preserves. Note that this is quite different from the goal of debug information, which is a best-effort attempt to track the location of named @@ -508,4 +509,3 @@ some code for each backend. Today, only a subset of LLVM's backends are supported. The currently supported architectures are X86_64, PowerPC, and Aarch64. - Index: include/llvm/CodeGen/StackMaps.h =================================================================== --- include/llvm/CodeGen/StackMaps.h +++ include/llvm/CodeGen/StackMaps.h @@ -167,7 +167,7 @@ void reset() { CSInfos.clear(); ConstPool.clear(); - FnStackSize.clear(); + FnInfos.clear(); } /// \brief Generate a stackmap record for a stackmap instruction. @@ -191,7 +191,13 @@ typedef SmallVector LocationVec; typedef SmallVector LiveOutVec; typedef MapVector ConstantPool; - typedef MapVector FnStackSizeMap; + + struct FunctionInfo { + uint64_t StackSize; + uint64_t RecordCount; + FunctionInfo() : StackSize(0), RecordCount(1) {} + FunctionInfo(uint64_t StackSize) : StackSize(StackSize), RecordCount(1) {} + }; struct CallsiteInfo { const MCExpr *CSOffsetExpr; @@ -205,12 +211,13 @@ LiveOuts(std::move(LiveOuts)) {} }; + typedef MapVector FnInfoMap; typedef std::vector CallsiteInfoList; AsmPrinter &AP; CallsiteInfoList CSInfos; ConstantPool ConstPool; - FnStackSizeMap FnStackSize; + FnInfoMap FnInfos; MachineInstr::const_mop_iterator parseOperand(MachineInstr::const_mop_iterator MOI, Index: include/llvm/Object/StackMapParser.h =================================================================== --- include/llvm/Object/StackMapParser.h +++ include/llvm/Object/StackMapParser.h @@ -56,14 +56,19 @@ } /// Get the function's stack size. - uint32_t getStackSize() const { + uint64_t getStackSize() const { return read(P + sizeof(uint64_t)); } + + /// Get the number of callsite records. + uint64_t getRecordCount() const { + return read(P + (2 * sizeof(uint64_t))); + } private: FunctionAccessor(const uint8_t *P) : P(P) {} - const static int FunctionAccessorSize = 2 * sizeof(uint64_t); + const static int FunctionAccessorSize = 3 * sizeof(uint64_t); FunctionAccessor next() const { return FunctionAccessor(P + FunctionAccessorSize); @@ -420,7 +425,7 @@ static const unsigned NumRecordsOffset = NumConstantsOffset + sizeof(uint32_t); static const unsigned FunctionListOffset = NumRecordsOffset + sizeof(uint32_t); - static const unsigned FunctionSize = 2 * sizeof(uint64_t); + static const unsigned FunctionSize = 3 * sizeof(uint64_t); static const unsigned ConstantSize = sizeof(uint64_t); std::size_t getFunctionOffset(unsigned FunctionIndex) const { Index: lib/CodeGen/StackMaps.cpp =================================================================== --- lib/CodeGen/StackMaps.cpp +++ lib/CodeGen/StackMaps.cpp @@ -331,13 +331,20 @@ CSInfos.emplace_back(CSOffsetExpr, ID, std::move(Locations), std::move(LiveOuts)); - // Record the stack size of the current function. + // Record the stack size of the current function and update callsite count. const MachineFrameInfo &MFI = AP.MF->getFrameInfo(); const TargetRegisterInfo *RegInfo = AP.MF->getSubtarget().getRegisterInfo(); bool HasDynamicFrameSize = MFI.hasVarSizedObjects() || RegInfo->needsStackRealignment(*(AP.MF)); - FnStackSize[AP.CurrentFnSym] = - HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize(); + uint64_t FrameSize = HasDynamicFrameSize ? UINT64_MAX : MFI.getStackSize(); + + if (FnInfos.count(AP.CurrentFnSym)) { + FunctionInfo ¤t = FnInfos[AP.CurrentFnSym]; + current.StackSize = FrameSize; + current.RecordCount = current.RecordCount + 1; + } else { + FnInfos[AP.CurrentFnSym] = FunctionInfo(FrameSize); + } } void StackMaps::recordStackMap(const MachineInstr &MI) { @@ -397,8 +404,8 @@ OS.EmitIntValue(0, 2); // Reserved. // Num functions. - DEBUG(dbgs() << WSMP << "#functions = " << FnStackSize.size() << '\n'); - OS.EmitIntValue(FnStackSize.size(), 4); + DEBUG(dbgs() << WSMP << "#functions = " << FnInfos.size() << '\n'); + OS.EmitIntValue(FnInfos.size(), 4); // Num constants. DEBUG(dbgs() << WSMP << "#constants = " << ConstPool.size() << '\n'); OS.EmitIntValue(ConstPool.size(), 4); @@ -412,15 +419,18 @@ /// StkSizeRecord[NumFunctions] { /// uint64 : Function Address /// uint64 : Stack Size +/// uint64 : Record Count /// } void StackMaps::emitFunctionFrameRecords(MCStreamer &OS) { // Function Frame records. DEBUG(dbgs() << WSMP << "functions:\n"); - for (auto const &FR : FnStackSize) { + for (auto const &FR : FnInfos) { DEBUG(dbgs() << WSMP << "function addr: " << FR.first - << " frame size: " << FR.second); + << " frame size: " << FR.second.StackSize + << " callsite count: " << FR.second.RecordCount << '\n'); OS.EmitSymbolValue(FR.first, 8); - OS.EmitIntValue(FR.second, 8); + OS.EmitIntValue(FR.second.StackSize, 8); + OS.EmitIntValue(FR.second.RecordCount, 8); } } @@ -521,7 +531,7 @@ // Bail out if there's no stack map data. assert((!CSInfos.empty() || ConstPool.empty()) && "Expected empty constant pool too!"); - assert((!CSInfos.empty() || FnStackSize.empty()) && + assert((!CSInfos.empty() || FnInfos.empty()) && "Expected empty function record too!"); if (CSInfos.empty()) return; Index: test/CodeGen/AArch64/arm64-anyregcc.ll =================================================================== --- test/CodeGen/AArch64/arm64-anyregcc.ll +++ test/CodeGen/AArch64/arm64-anyregcc.ll @@ -17,20 +17,28 @@ ; Functions and stack size ; CHECK-NEXT: .quad _test ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _property_access1 ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _property_access2 ; CHECK-NEXT: .quad 32 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _property_access3 ; CHECK-NEXT: .quad 32 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _anyreg_test1 ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _anyreg_test2 ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _patchpoint_spilldef ; CHECK-NEXT: .quad 112 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _patchpoint_spillargs ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; test Index: test/CodeGen/AArch64/arm64-stackmap.ll =================================================================== --- test/CodeGen/AArch64/arm64-stackmap.ll +++ test/CodeGen/AArch64/arm64-stackmap.ll @@ -23,26 +23,37 @@ ; Functions and stack size ; CHECK-NEXT: .quad _constantargs ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _osrinline ; CHECK-NEXT: .quad 32 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _osrcold ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _propertyRead ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _propertyWrite ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _jsVoidCall ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _jsIntCall ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _spilledValue ; CHECK-NEXT: .quad 160 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _spilledStackMapValue ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _liveConstant ; CHECK-NEXT: .quad 16 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _clobberLR ; CHECK-NEXT: .quad 112 +; CHECK-NEXT: .quad 1 ; Num LargeConstants ; CHECK-NEXT: .quad 4294967295 Index: test/CodeGen/PowerPC/ppc64-anyregcc.ll =================================================================== --- test/CodeGen/PowerPC/ppc64-anyregcc.ll +++ test/CodeGen/PowerPC/ppc64-anyregcc.ll @@ -44,20 +44,28 @@ ; Functions and stack size ; CHECK-NEXT: .quad test ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad property_access1 ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad property_access2 ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad property_access3 ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad anyreg_test1 ; CHECK-NEXT: .quad 144 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad anyreg_test2 ; CHECK-NEXT: .quad 144 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad patchpoint_spilldef ; CHECK-NEXT: .quad 256 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad patchpoint_spillargs ; CHECK-NEXT: .quad 288 +; CHECK-NEXT: .quad 1 ; test Index: test/CodeGen/PowerPC/ppc64-stackmap.ll =================================================================== --- test/CodeGen/PowerPC/ppc64-stackmap.ll +++ test/CodeGen/PowerPC/ppc64-stackmap.ll @@ -57,26 +57,37 @@ ; Functions and stack size ; CHECK-NEXT: .quad constantargs ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad osrinline ; CHECK-NEXT: .quad 144 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad osrcold ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad propertyRead ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad propertyWrite ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad jsVoidCall ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad jsIntCall ; CHECK-NEXT: .quad 128 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad spilledValue ; CHECK-NEXT: .quad 304 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad spilledStackMapValue ; CHECK-NEXT: .quad 224 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad liveConstant ; CHECK-NEXT: .quad 64 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad clobberLR ; CHECK-NEXT: .quad 208 +; CHECK-NEXT: .quad 1 ; Num LargeConstants ; CHECK-NEXT: .quad 4294967295 Index: test/CodeGen/X86/anyregcc.ll =================================================================== --- test/CodeGen/X86/anyregcc.ll +++ test/CodeGen/X86/anyregcc.ll @@ -20,20 +20,28 @@ ; Functions and stack size ; CHECK-NEXT: .quad _test ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _property_access1 ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _property_access2 ; CHECK-NEXT: .quad 24 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _property_access3 ; CHECK-NEXT: .quad 24 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _anyreg_test1 ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _anyreg_test2 ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _patchpoint_spilldef ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _patchpoint_spillargs ; CHECK-NEXT: .quad 88 +; CHECK-NEXT: .quad 1 ; No constants Index: test/CodeGen/X86/stackmap-fast-isel.ll =================================================================== --- test/CodeGen/X86/stackmap-fast-isel.ll +++ test/CodeGen/X86/stackmap-fast-isel.ll @@ -17,12 +17,16 @@ ; Functions and stack size ; CHECK-NEXT: .quad _constantargs ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _liveConstant ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _directFrameIdx ; CHECK-NEXT: .quad 40 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _longid ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 4 ; Large Constants ; CHECK-NEXT: .quad 2147483648 Index: test/CodeGen/X86/stackmap-large-constants.ll =================================================================== --- test/CodeGen/X86/stackmap-large-constants.ll +++ test/CodeGen/X86/stackmap-large-constants.ll @@ -17,9 +17,11 @@ ; function address & stack size ; CHECK-NEXT: .quad _foo ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; function address & stack size ; CHECK-NEXT: .quad _bar ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; Constants Array: ; CHECK-NEXT: .quad 9223372036854775807 Index: test/CodeGen/X86/stackmap-liveness.ll =================================================================== --- test/CodeGen/X86/stackmap-liveness.ll +++ test/CodeGen/X86/stackmap-liveness.ll @@ -19,8 +19,10 @@ ; Functions and stack size ; CHECK-NEXT: .quad _stackmap_liveness ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 3 ; CHECK-NEXT: .quad _mixed_liveness ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 2 define void @stackmap_liveness() { entry: Index: test/CodeGen/X86/stackmap.ll =================================================================== --- test/CodeGen/X86/stackmap.ll +++ test/CodeGen/X86/stackmap.ll @@ -18,36 +18,52 @@ ; Functions and stack size ; CHECK-NEXT: .quad _constantargs ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _osrinline ; CHECK-NEXT: .quad 24 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _osrcold ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _propertyRead ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _propertyWrite ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _jsVoidCall ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _jsIntCall ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _spilledValue ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _spilledStackMapValue ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _spillSubReg ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _subRegOffset ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _liveConstant ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _directFrameIdx ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 2 ; CHECK-NEXT: .quad _longid ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 4 ; CHECK-NEXT: .quad _clobberScratch ; CHECK-NEXT: .quad 56 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad _needsStackRealignment ; CHECK-NEXT: .quad -1 +; CHECK-NEXT: .quad 1 ; Large Constants ; CHECK-NEXT: .quad 2147483648 Index: test/CodeGen/X86/statepoint-allocas.ll =================================================================== --- test/CodeGen/X86/statepoint-allocas.ll +++ test/CodeGen/X86/statepoint-allocas.ll @@ -61,8 +61,10 @@ ; Functions and stack size ; CHECK-NEXT: .quad test ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad test2 ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; Large Constants ; Statepoint ID only @@ -127,4 +129,3 @@ ; CHECK: .short 0 ; CHECK: .short 0 ; CHECK: .p2align 3 - Index: test/CodeGen/X86/statepoint-stackmap-format.ll =================================================================== --- test/CodeGen/X86/statepoint-stackmap-format.ll +++ test/CodeGen/X86/statepoint-stackmap-format.ll @@ -92,10 +92,13 @@ ; Functions and stack size ; CHECK-NEXT: .quad test ; CHECK-NEXT: .quad 40 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad test_derived_arg ; CHECK-NEXT: .quad 40 +; CHECK-NEXT: .quad 1 ; CHECK-NEXT: .quad test_id ; CHECK-NEXT: .quad 8 +; CHECK-NEXT: .quad 1 ; ; test @@ -276,4 +279,3 @@ ; CHECK: .short 0 ; CHECK: .short 0 ; CHECK: .p2align 3 - Index: test/Object/stackmap-dump.test =================================================================== --- test/Object/stackmap-dump.test +++ test/Object/stackmap-dump.test @@ -1,16 +1,174 @@ RUN: llvm-readobj -stackmap %p/Inputs/stackmap-test.macho-x86-64 | FileCheck %s -CHECK: LLVM StackMap Version: 1 -CHECK-NEXT: Num Functions: 1 -CHECK-NEXT: Function address: 0, stack size: 16 -CHECK-NEXT: Num Constants: 1 -CHECK-NEXT: #1: 10000000000 -CHECK-NEXT: Num Records: 1 -CHECK-NEXT: Record ID: 2, instruction offset: 1 -CHECK-NEXT: 5 locations: +; Note: the macho object file in this test was generated in the following way: +; llc -mtriple=x86_64-apple-darwin %p/test/CodeGen/X86/stackmap.ll -o stackmap.s +; clang -c stackmap.s -o %p/test/Object/Inputs/stackmap-test.macho-x86-64 + +CHECK: LLVM StackMap Version: 1 +CHECK-NEXT: Num Functions: 16 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 24, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 2 +CHECK-NEXT: Function address: 0, stack size: 8, callsite record count: 4 +CHECK-NEXT: Function address: 0, stack size: 56, callsite record count: 1 +CHECK-NEXT: Function address: 0, stack size: 18446744073709551615, callsite record count: 1 +CHECK-NEXT: Num Constants: 3 +CHECK-NEXT: #1: 2147483648 +CHECK-NEXT: #2: 4294967295 +CHECK-NEXT: #3: 4294967296 +CHECK-NEXT: Num Records: 20 +CHECK-NEXT: Record ID: 1, instruction offset: 4 +CHECK-NEXT: 12 locations: +CHECK-NEXT: #1: Constant 4294967295 +CHECK-NEXT: #2: Constant 4294967295 +CHECK-NEXT: #3: Constant 65536 +CHECK-NEXT: #4: Constant 2000000000 +CHECK-NEXT: #5: Constant 2147483647 +CHECK-NEXT: #6: Constant 4294967295 +CHECK-NEXT: #7: Constant 4294967295 +CHECK-NEXT: #8: Constant 0 +CHECK-NEXT: #9: ConstantIndex #0 (2147483648) +CHECK-NEXT: #10: ConstantIndex #1 (4294967295) +CHECK-NEXT: #11: ConstantIndex #2 (4294967296) +CHECK-NEXT: #12: Constant 4294967295 +CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ] + +CHECK: Record ID: 3, instruction offset: 22 +CHECK-NEXT: 2 locations: +CHECK-NEXT: #1: Register R#3 +CHECK-NEXT: #2: Register R#14 +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 4, instruction offset: 10 +CHECK-NEXT: 2 locations: CHECK-NEXT: #1: Register R#5 -CHECK-NEXT: #2: Constant 10 -CHECK-NEXT: #3: ConstantIndex #0 (10000000000) -CHECK-NEXT: #4: Direct R#4 + -8 -CHECK-NEXT: #5: Indirect [R#6 + -16] +CHECK-NEXT: #2: Register R#4 +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 5, instruction offset: 4 +CHECK-NEXT: 2 locations: +CHECK-NEXT: #1: Register R#0 +CHECK-NEXT: #2: Register R#5 +CHECK-NEXT: 2 live-outs: [ R#0 (8-bytes) R#7 (8-bytes) ] + +CHECK: Record ID: 6, instruction offset: 4 +CHECK-NEXT: 2 locations: +CHECK-NEXT: #1: Register R#4 +CHECK-NEXT: #2: Register R#2 CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ] + +CHECK: Record ID: 7, instruction offset: 10 +CHECK-NEXT: 2 locations: +CHECK-NEXT: #1: Register R#2 +CHECK-NEXT: #2: Register R#8 +CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ] + +CHECK: Record ID: 8, instruction offset: 10 +CHECK-NEXT: 2 locations: +CHECK-NEXT: #1: Register R#2 +CHECK-NEXT: #2: Register R#8 +CHECK-NEXT: 2 live-outs: [ R#0 (8-bytes) R#7 (8-bytes) ] + +CHECK: Record ID: 11, instruction offset: 42 +CHECK-NEXT: 17 locations: +CHECK-NEXT: #1: Register R#9 +CHECK-NEXT: #2: Register R#14 +CHECK-NEXT: #3: Register R#10 +CHECK-NEXT: #4: Register R#3 +CHECK-NEXT: #5: Register R#0 +CHECK-NEXT: #6: Register R#13 +CHECK-NEXT: #7: Register R#12 +CHECK-NEXT: #8: Register R#15 +CHECK-NEXT: #9: Indirect [R#6 + 72] +CHECK-NEXT: #10: Indirect [R#6 + 80] +CHECK-NEXT: #11: Indirect [R#6 + 88] +CHECK-NEXT: #12: Indirect [R#6 + 96] +CHECK-NEXT: #13: Indirect [R#6 + 104] +CHECK-NEXT: #14: Indirect [R#6 + 112] +CHECK-NEXT: #15: Indirect [R#6 + 120] +CHECK-NEXT: #16: Indirect [R#6 + 128] +CHECK-NEXT: #17: Indirect [R#6 + 136] +CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ] + +CHECK: Record ID: 12, instruction offset: 62 +CHECK-NEXT: 17 locations: +CHECK-NEXT: #1: Register R#0 +CHECK-NEXT: #2: Register R#14 +CHECK-NEXT: #3: Register R#10 +CHECK-NEXT: #4: Register R#9 +CHECK-NEXT: #5: Register R#8 +CHECK-NEXT: #6: Register R#4 +CHECK-NEXT: #7: Register R#1 +CHECK-NEXT: #8: Register R#2 +CHECK-NEXT: #9: Register R#5 +CHECK-NEXT: #10: Register R#3 +CHECK-NEXT: #11: Register R#13 +CHECK-NEXT: #12: Register R#12 +CHECK-NEXT: #13: Register R#15 +CHECK-NEXT: #14: Indirect [R#6 + 112] +CHECK-NEXT: #15: Indirect [R#6 + 120] +CHECK-NEXT: #16: Indirect [R#6 + 128] +CHECK-NEXT: #17: Indirect [R#6 + 136] +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 13, instruction offset: 50 +CHECK-NEXT: 1 locations: +CHECK-NEXT: #1: Indirect [R#6 + -48] +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 14, instruction offset: 24 +CHECK-NEXT: 2 locations: +CHECK-NEXT: #1: Register R#0 +CHECK-NEXT: #2: Register R#3 +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 15, instruction offset: 4 +CHECK-NEXT: 1 locations: +CHECK-NEXT: #1: Constant 33 +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 16, instruction offset: 32 +CHECK-NEXT: 1 locations: +CHECK-NEXT: #1: Direct R#6 + -32 +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 17, instruction offset: 32 +CHECK-NEXT: 2 locations: +CHECK-NEXT: #1: Direct R#6 + -8 +CHECK-NEXT: #2: Direct R#6 + -40 +CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ] + +CHECK: Record ID: 4294967295, instruction offset: 4 +CHECK-NEXT: 0 locations: +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 4294967296, instruction offset: 4 +CHECK-NEXT: 0 locations: +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 9223372036854775807, instruction offset: 4 +CHECK-NEXT: 0 locations: +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 18446744073709551615, instruction offset: 4 +CHECK-NEXT: 0 locations: +CHECK-NEXT: 1 live-outs: [ R#7 (8-bytes) ] + +CHECK: Record ID: 16, instruction offset: 18 +CHECK-NEXT: 1 locations: +CHECK-NEXT: #1: Indirect [R#6 + -44] +CHECK-NEXT: 0 live-outs: [ ] + +CHECK: Record ID: 0, instruction offset: 26 +CHECK-NEXT: 0 locations: +CHECK-NEXT: 0 live-outs: [ ] Index: tools/llvm-readobj/StackMapPrinter.h =================================================================== --- tools/llvm-readobj/StackMapPrinter.h +++ tools/llvm-readobj/StackMapPrinter.h @@ -24,7 +24,8 @@ // Functions: for (const auto &F : SMP.functions()) OS << "\n Function address: " << F.getFunctionAddress() - << ", stack size: " << F.getStackSize(); + << ", stack size: " << F.getStackSize() + << ", callsite record count: " << F.getRecordCount(); // Constants: OS << "\nNum Constants: " << SMP.getNumConstants();