[LLVMdev] [RFC] New StackMap format proposal (StackMap v2)

Swaroop Sridhar Swaroop.Sridhar at microsoft.com
Thu Jul 9 15:33:48 PDT 2015


Regarding Call-site size specification:

CoreCLR (https://github.com/dotnet/coreclr) requires the size of the Call-instruction to be reported in the GCInfo encoding.

The runtime performs querries for StackMap records using instruction offsets as follows:

1)      Offset at the end of the call instruction (offset of next instruction-1) if the call instruction occurs in code where GC can only take control at safe-points.

2)      Offset of the start of the call instruction if the call instruction occurs within a code-range that allows full interruption (that is, all instructions in a range are considered safe-points)

LLVM/statepoint GC does not support option (2), but the CoreCLR's GC-table Encoding has an interface designed to suite both modes.
void DefineCallSites(UINT32* pCallSites, BYTE* pCallSiteSizes, UINT32 numCallSites)

Therefore, it is helpful to have Call-Site size specified in StackMapRecord.
I agree with Andy, that the call-site size should include all bytes between the start of the call instruction and the start of the next instruction.

Thanks,
Swaroop.

From: Juergen Ributzka [mailto:juergen at apple.com]
Sent: Thursday, July 9, 2015 2:04 PM
To: LLVM Dev
Cc: Lang Hames; Andrew Trick; Phil Pizlo; Philip Reames; Sanjoy Das; Swaroop Sridhar; Russell Hadley
Subject: [RFC] New StackMap format proposal (StackMap v2)

Hi @ll,

over the past year we gained more experience with the patchpoint/stackmap/statepoint intrinsics and it exposed limitations in the stackmap format.
The following proposal includes feedback and request from several interested parties and I would like to hear your feedback.

Missing correlation between functions and stackmap records:
Originally the client had to keep track of the ID to know which stackmap record belongs to which function, but this would stop working once functions are inlined.
The new format fixes that by adding a direct reference from the function to the stackmap records.

Call Size and Function Size:
These are additional information that are of interest and have been added to the format.
@Swaroop: Could you please provide a little more detailed explanation on the "Call Size" field and what exactly is there recorded. Is it just the call instruction
or also the materialization code for the address? For what is this used for?

Flat format:
We think moving to a flat form will make parsing easier, because every record has a fixed size and offsets can be calculated easily. The plan is to also
provide parsers for both stackmap versions (there is already one for the first format in tree) and a corresponding C-API to make it easier for clients to
adopt the new format. There is no plan to drop the original format and we will continue to support both formats. I will ask for feedback on the C API in a
separate RFC.

Another benefit we hope to achieve from this format is to optimize for size by uniquing entries - but that is independent optimization and not required.

More detailed frame record:
Clients require more information about the function frame, such as spilled registers, etc. The frame base register i.e. might change when dynamic stack
realignment is performed on X86.


If there is anything missing please let me know.

Thanks

Cheers,
Juergen


Header v2 {
  uint8  : Stack Map Version (2)
  uint8  : Reserved [3] (0)
  uint32 : Constants Offset (bytes)
  uint32 : Frame Records Offset (bytes)
  uint32 : Frame Registers Offset (bytes)
  uint32 : StackMap Records Offset (bytes)
  uint32 : Locations Offset (bytes)
  uint32 : LiveOuts Offset (bytes)
}

align to 8 bytes
Constants[] {
  uint64 : LargeConstant
}

align to 8 bytes
FrameRecord[] {
  uint64 : Function Address
  uint32 : Function Size
  uint32 : Stack Size
  uint16 : Flags {
    bool : HasFrame
    bool : HasVariableSizeAlloca
    bool : HasStackRealignment
    bool : HasLiveOutInfo
    bool : Reserved [12]
  }
  uint16 : Frame Base Register Dwarf RegNum
  uint16 : Num Frame Registers
  uint16 : Frame Register Index
  uint16 : Num StackMap Records
  uint16 : StackMap Record Index
}

align to 4 bytes
FrameRegister[] {
  uint16 : Dwarf RegNum
  int16  : Offset
  uint8  : Size in Bytes
  uint8  : Flags {
    bool : IsSpilled
    bool : Reserved [7]
  }
}

align to 8 bytes
StackMapRecord[] {
  uint64 : PatchPoint ID
  uint32 : Instruction Offset
  uint8  : Call size (bytes)
  uint8  : Flags {
    bool : HasLiveOutInfo
    bool : Reserved [7]
  }
  uint16 : Num Locations
  uint16 : Location Index
  uint16 : Num LiveOuts
  uint16 : LiveOut Index
}

align to 4 bytes
Location[] {
  uint8  : Register | Direct | Indirect | Constant | ConstantIndex
  uint8  : Reserved (location flags)
  uint16 : Dwarf RegNum
  int32  : Offset or SmallConstant
}

align to 2 bytes
LiveOuts[] {
  uint16 : Dwarf RegNum
  uint8  : Reserved
  uint8  : Size in Bytes
}

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-dev/attachments/20150709/a29d6dbe/attachment.html>


More information about the llvm-dev mailing list