Index: llvm/trunk/docs/StackMaps.rst =================================================================== --- llvm/trunk/docs/StackMaps.rst +++ llvm/trunk/docs/StackMaps.rst @@ -319,7 +319,7 @@ .. code-block:: none Header { - uint8 : Stack Map Version (current version is 1) + uint8 : Stack Map Version (current version is 2) uint8 : Reserved (expected to be 0) uint16 : Reserved (expected to be 0) } @@ -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: llvm/trunk/include/llvm/CodeGen/StackMaps.h =================================================================== --- llvm/trunk/include/llvm/CodeGen/StackMaps.h +++ llvm/trunk/include/llvm/CodeGen/StackMaps.h @@ -219,7 +219,7 @@ void reset() { CSInfos.clear(); ConstPool.clear(); - FnStackSize.clear(); + FnInfos.clear(); } /// \brief Generate a stackmap record for a stackmap instruction. @@ -243,7 +243,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) {} + explicit FunctionInfo(uint64_t StackSize) : StackSize(StackSize), RecordCount(1) {} + }; struct CallsiteInfo { const MCExpr *CSOffsetExpr; @@ -257,12 +263,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: llvm/trunk/include/llvm/Object/StackMapParser.h =================================================================== --- llvm/trunk/include/llvm/Object/StackMapParser.h +++ llvm/trunk/include/llvm/Object/StackMapParser.h @@ -17,7 +17,7 @@ namespace llvm { template -class StackMapV1Parser { +class StackMapV2Parser { public: template @@ -47,7 +47,7 @@ /// Accessor for function records. class FunctionAccessor { - friend class StackMapV1Parser; + friend class StackMapV2Parser; public: /// Get the function address. @@ -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); @@ -74,7 +79,7 @@ /// Accessor for constants. class ConstantAccessor { - friend class StackMapV1Parser; + friend class StackMapV2Parser; public: /// Return the value of this constant. @@ -103,7 +108,7 @@ /// Accessor for location records. class LocationAccessor { - friend class StackMapV1Parser; + friend class StackMapV2Parser; friend class RecordAccessor; public: @@ -156,7 +161,7 @@ /// Accessor for stackmap live-out fields. class LiveOutAccessor { - friend class StackMapV1Parser; + friend class StackMapV2Parser; friend class RecordAccessor; public: @@ -188,7 +193,7 @@ /// Accessor for stackmap records. class RecordAccessor { - friend class StackMapV1Parser; + friend class StackMapV2Parser; public: typedef AccessorIterator location_iterator; @@ -292,14 +297,14 @@ const uint8_t *P; }; - /// Construct a parser for a version-1 stackmap. StackMap data will be read + /// Construct a parser for a version-2 stackmap. StackMap data will be read /// from the given array. - StackMapV1Parser(ArrayRef StackMapSection) + StackMapV2Parser(ArrayRef StackMapSection) : StackMapSection(StackMapSection) { ConstantsListOffset = FunctionListOffset + getNumFunctions() * FunctionSize; - assert(StackMapSection[0] == 1 && - "StackMapV1Parser can only parse version 1 stackmaps"); + assert(StackMapSection[0] == 2 && + "StackMapV2Parser can only parse version 2 stackmaps"); unsigned CurrentRecordOffset = ConstantsListOffset + getNumConstants() * ConstantSize; @@ -315,8 +320,8 @@ typedef AccessorIterator constant_iterator; typedef AccessorIterator record_iterator; - /// Get the version number of this stackmap. (Always returns 1). - unsigned getVersion() const { return 1; } + /// Get the version number of this stackmap. (Always returns 2). + unsigned getVersion() const { return 2; } /// Get the number of functions in the stack map. uint32_t getNumFunctions() const { @@ -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: llvm/trunk/lib/CodeGen/StackMaps.cpp =================================================================== --- llvm/trunk/lib/CodeGen/StackMaps.cpp +++ llvm/trunk/lib/CodeGen/StackMaps.cpp @@ -30,8 +30,8 @@ #define DEBUG_TYPE "stackmaps" static cl::opt StackMapVersion( - "stackmap-version", cl::init(1), - cl::desc("Specify the stackmap encoding version (default = 1)")); + "stackmap-version", cl::init(2), + cl::desc("Specify the stackmap encoding version (default = 2)")); const char *StackMaps::WSMP = "Stack Maps: "; @@ -74,7 +74,7 @@ } StackMaps::StackMaps(AsmPrinter &AP) : AP(AP) { - if (StackMapVersion != 1) + if (StackMapVersion != 2) llvm_unreachable("Unsupported stackmap version!"); } @@ -335,13 +335,18 @@ 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(); + + auto CurrentIt = FnInfos.find(AP.CurrentFnSym); + if (CurrentIt != FnInfos.end()) + CurrentIt->second.RecordCount++; + else + FnInfos.insert(std::make_pair(AP.CurrentFnSym, FunctionInfo(FrameSize))); } void StackMaps::recordStackMap(const MachineInstr &MI) { @@ -387,7 +392,7 @@ /// Emit the stackmap header. /// /// Header { -/// uint8 : Stack Map Version (currently 1) +/// uint8 : Stack Map Version (currently 2) /// uint8 : Reserved (expected to be 0) /// uint16 : Reserved (expected to be 0) /// } @@ -401,8 +406,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); @@ -416,15 +421,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); } } @@ -525,7 +533,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: llvm/trunk/test/CodeGen/AArch64/arm64-anyregcc.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/arm64-anyregcc.ll +++ llvm/trunk/test/CodeGen/AArch64/arm64-anyregcc.ll @@ -4,7 +4,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/AArch64/arm64-stackmap.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/arm64-stackmap.ll +++ llvm/trunk/test/CodeGen/AArch64/arm64-stackmap.ll @@ -10,7 +10,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/AArch64/stackmap-liveness.ll =================================================================== --- llvm/trunk/test/CodeGen/AArch64/stackmap-liveness.ll +++ llvm/trunk/test/CodeGen/AArch64/stackmap-liveness.ll @@ -5,7 +5,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -44,4 +44,3 @@ } declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...) - Index: llvm/trunk/test/CodeGen/PowerPC/ppc64-anyregcc.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc64-anyregcc.ll +++ llvm/trunk/test/CodeGen/PowerPC/ppc64-anyregcc.ll @@ -31,7 +31,7 @@ ; CHECK-LABEL: .section .llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/PowerPC/ppc64-stackmap.ll =================================================================== --- llvm/trunk/test/CodeGen/PowerPC/ppc64-stackmap.ll +++ llvm/trunk/test/CodeGen/PowerPC/ppc64-stackmap.ll @@ -44,7 +44,7 @@ ; CHECK-LABEL: .section .llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/X86/anyregcc.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/anyregcc.ll +++ llvm/trunk/test/CodeGen/X86/anyregcc.ll @@ -7,7 +7,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/X86/patchpoint-invoke.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/patchpoint-invoke.ll +++ llvm/trunk/test/CodeGen/X86/patchpoint-invoke.ll @@ -45,7 +45,7 @@ ; Verify that the stackmap section got emitted: ; CHECK-LABEL: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions Index: llvm/trunk/test/CodeGen/X86/stackmap-fast-isel.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/stackmap-fast-isel.ll +++ llvm/trunk/test/CodeGen/X86/stackmap-fast-isel.ll @@ -4,7 +4,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/X86/stackmap-large-constants.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/stackmap-large-constants.ll +++ llvm/trunk/test/CodeGen/X86/stackmap-large-constants.ll @@ -3,7 +3,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; version -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; reserved ; CHECK-NEXT: .byte 0 ; reserved @@ -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: llvm/trunk/test/CodeGen/X86/stackmap-liveness.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/stackmap-liveness.ll +++ llvm/trunk/test/CodeGen/X86/stackmap-liveness.ll @@ -6,7 +6,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/X86/stackmap.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/stackmap.ll +++ llvm/trunk/test/CodeGen/X86/stackmap.ll @@ -5,7 +5,7 @@ ; CHECK-LABEL: .section __LLVM_STACKMAPS,__llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/X86/statepoint-allocas.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/statepoint-allocas.ll +++ llvm/trunk/test/CodeGen/X86/statepoint-allocas.ll @@ -48,7 +48,7 @@ ; CHECK-LABEL: .section .llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll =================================================================== --- llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll +++ llvm/trunk/test/CodeGen/X86/statepoint-stackmap-format.ll @@ -79,7 +79,7 @@ ; CHECK-LABEL: .section .llvm_stackmaps ; CHECK-NEXT: __LLVM_StackMaps: ; Header -; CHECK-NEXT: .byte 1 +; CHECK-NEXT: .byte 2 ; CHECK-NEXT: .byte 0 ; CHECK-NEXT: .short 0 ; Num Functions @@ -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: llvm/trunk/test/Object/stackmap-dump.test =================================================================== --- llvm/trunk/test/Object/stackmap-dump.test +++ llvm/trunk/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: 2 +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: llvm/trunk/tools/llvm-readobj/COFFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/COFFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/COFFDumper.cpp @@ -1527,10 +1527,10 @@ if (Obj->isLittleEndian()) prettyPrintStackMap( llvm::outs(), - StackMapV1Parser(StackMapContentsArray)); + StackMapV2Parser(StackMapContentsArray)); else prettyPrintStackMap(llvm::outs(), - StackMapV1Parser(StackMapContentsArray)); + StackMapV2Parser(StackMapContentsArray)); } void llvm::dumpCodeViewMergedTypes( Index: llvm/trunk/tools/llvm-readobj/ELFDumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/ELFDumper.cpp +++ llvm/trunk/tools/llvm-readobj/ELFDumper.cpp @@ -2366,7 +2366,7 @@ ArrayRef StackMapContentsArray = unwrapOrError(Obj->getSectionContents(StackMapSection)); - prettyPrintStackMap(llvm::outs(), StackMapV1Parser( + prettyPrintStackMap(llvm::outs(), StackMapV2Parser( StackMapContentsArray)); } Index: llvm/trunk/tools/llvm-readobj/MachODumper.cpp =================================================================== --- llvm/trunk/tools/llvm-readobj/MachODumper.cpp +++ llvm/trunk/tools/llvm-readobj/MachODumper.cpp @@ -669,10 +669,10 @@ if (Obj->isLittleEndian()) prettyPrintStackMap( llvm::outs(), - StackMapV1Parser(StackMapContentsArray)); + StackMapV2Parser(StackMapContentsArray)); else prettyPrintStackMap(llvm::outs(), - StackMapV1Parser(StackMapContentsArray)); + StackMapV2Parser(StackMapContentsArray)); } void MachODumper::printMachODataInCode() { Index: llvm/trunk/tools/llvm-readobj/StackMapPrinter.h =================================================================== --- llvm/trunk/tools/llvm-readobj/StackMapPrinter.h +++ llvm/trunk/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();