-
Notifications
You must be signed in to change notification settings - Fork 52
Open
Labels
epic-tier2-optimizerLinear code region optimizer for 3.13 and beyond.Linear code region optimizer for 3.13 and beyond.
Description
This pass defers the creation and update of objects, including the frame stack.
By maintaining a "shadow frame stack" we can defer operations that create new objects, or modify the frame stack, only materializing the frame stack when needed.
Doing so for SAVE_IP
is trivial, we just record the current prev_instr
on the shadow frame.
I will omit the SAVE_IP
s for clarity in the following example.
Taking the code from the specialization example:
POP_TOP
LOAD_CONST (typing.cast)
LOAD_CONST (int)
LOAD_FAST 0 (x)
PUSH_FRAME 2
CHECK_EVAL_BREAKER
LOAD_FAST 1 (val)
RETURN_VALUE
STORE_FAST 0 (x)
LOAD_GLOBAL_MODULE_UNCHECKED (unpredicable)
EXIT # Can't predict where we are going
This produces the following superblock with commented shadow frame stack:
NOP # stack: [ typing ]
NOP # stack: [ ]
NOP # stack: [ typing.cast ]
NOP # stack: [ typing.cast, int ]
NOP # stack: [ typing.cast, int, LOCAL(0) ]
NOP # prev_frame: [] frame: (locals=(int, LOCAL(0)), stack: []) We push a shadow frame instead of a real one
CHECK_EVAL_BREAKER # We still need to check the eval breaker, but only once per superblock or loop.
NOP # prev_frame: [] frame: (locals=(int, LOCAL(0)), stack: [ LOCAL(0) ])
NOP # stack: [ LOCAL(0) ] The return is performed on the shadow stack.
NOP # stack: [] (this is a NOP as we are storing a value to itself)
LOAD_GLOBAL_MODULE_UNCHECKED (unpredicable)
SAVE_IP
EXIT # Can't predict where we are going
Which after the cleanup pass is:
CHECK_EVAL_BREAKER
LOAD_GLOBAL_MODULE_UNCHECKED (unpredicable)
SAVE_IP
EXIT # Can't predict where we are going
This is obviously a somewhat contrived example, but you get the idea.
Metadata
Metadata
Assignees
Labels
epic-tier2-optimizerLinear code region optimizer for 3.13 and beyond.Linear code region optimizer for 3.13 and beyond.