Local stack analysis


For each basic-block in the cfg, local stack analysis is performed. The analysis is started right after the block is created with begin-local-analysis and finished with end-local-analysis, when the construction of the block is complete. During the analysis, three sets containing stack locations are built:
peeks all stack locations that the block reads before writing
replaces all stack locations that the block writes
kills all stack locations which become unavailable after the block ends because of the stack height being decremented. For example, if the block contains drop, then D: 0 will be contained in kills because that stack location will not be live anymore.

This is done while constructing the CFG. These sets are then used by the end-stack-analysis word to emit optimal sequences of ##peek and ##replace instructions to the cfg.

For example, the code [ dup dup dup ] will only execute ##peek once, instead of three time which a 'non-lazy' method would.

Words for reading the stack state:
peek-loc ( loc -- vreg )

global-loc>local ( loc height-state -- loc' )

local-loc>global ( loc height-state -- loc' )


Words for writing the stack state:
inc-stack ( loc -- )

replace-loc ( vreg loc -- )


Beginning and ending analysis:
begin-local-analysis ( basic-block -- )

end-local-analysis ( basic-block -- )


Temporary variables that keeps track of the block's read and written stack locations:
local-peek-set

replaces