factor/basis/compiler/cfg/stacks/local/local-docs.factor

138 lines
5.9 KiB
Factor

USING: assocs compiler.cfg compiler.cfg.instructions
compiler.cfg.registers compiler.cfg.stacks hash-sets hashtables
help.markup help.syntax kernel math sequences ;
IN: compiler.cfg.stacks.local
HELP: begin-local-analysis
{ $values { "basic-block" basic-block } }
{ $description "Begins the local analysis of the block. The height slot of the block is initialized with the resulting height of the last block." } ;
HELP: emit-insns
{ $values { "replaces" sequence } { "state" sequence } }
{ $description "Insert height and stack changes prior to the last instruction." } ;
HELP: end-local-analysis
{ $values { "basic-block" basic-block } }
{ $description "Called to end the local analysis of a block. The word fills in the blocks slots " { $slot "replaces" } ", " { $slot "peeks" } " and " { $slot "kills" } " with what the blocks replaces, peeks and kill locations are." } ;
HELP: global-loc>local
{ $values { "loc" loc } { "height-state" height-state } { "loc'" loc } }
{ $description "Translates an absolute stack location to one that is relative to the given height state." }
{ $examples
{ $example
"USING: compiler.cfg.stacks.local compiler.cfg.registers namespaces prettyprint ;"
"D: 7 T{ height-state f 3 0 0 0 } global-loc>local ."
"D: 4"
}
}
{ $see-also height-state local-loc>global } ;
HELP: height-state
{ $description "A tuple which keeps track of the stacks heights and increments of a " { $link basic-block } " during local analysis. The idea is that if the stack change instructions are tracked, then multiple changes can be folded into one. It has the following slots:"
{ $table
{
{ $slot "ds-begin" }
"Datastack height at the beginning of the block."
}
{
{ $slot "rs-begin" }
"Retainstack height at the beginning of the block."
}
{
{ $slot "ds-inc" }
"Datastack change during the block."
}
{
{ $slot "rs-inc" }
"Retainstack change during the block."
}
}
}
{ $see-also inc-stack reset-incs } ;
HELP: height-state>insns
{ $values { "state" sequence } { "insns" sequence } }
{ $description "Converts a " { $link height-state } " tuple to 0-2 stack height change instructions." }
{ $examples
"In this example the datastacks height is increased by 4 and the retainstacks decreased by 2."
{ $example
"USING: compiler.cfg.stacks.local prettyprint ;"
"T{ height-state f 0 0 4 -2 } height-state>insns ."
"{ T{ ##inc { loc D: 4 } } T{ ##inc { loc R: -2 } } }"
}
} ;
HELP: inc-stack
{ $values { "loc" loc } }
{ $description "Increases or decreases the data or retain stack depending on if loc is a " { $link ds-loc } " or " { $link rs-loc } " instance. An " { $link ##inc } " instruction will later be inserted." } ;
HELP: local-loc>global
{ $values { "loc" loc } { "bb" basic-block } { "loc'" loc } }
{ $description "Translates a stack location relative to a block to an absolute one. The word does the opposite to " { $link global-loc>local } "." } ;
HELP: loc>vreg
{ $values { "loc" loc } { "vreg" "virtual register" } }
{ $description "Maps a stack location to a virtual register." } ;
HELP: local-kill-set
{ $values
{ "ds-height" integer }
{ "ds-inc" integer }
{ "rs-height" integer }
{ "rs-inc" integer }
}
{ $description "The set of stack locations that was killed. Locations on a stack are deemed killed if that stacks height is decremented." }
{ $see-also compute-local-kill-set } ;
HELP: local-peek-set
{ $var-description "A " { $link hash-set } " used during local block analysis to keep track of peeked stack locations." } ;
HELP: peek-loc
{ $values { "loc" loc } { "vreg" "virtual register" } }
{ $description "Retrieves the virtual register at the given stack location. If no register has been stored at that location, then a new vreg is returned." } ;
HELP: replace-loc
{ $values { "vreg" "virtual register" } { "loc" loc } }
{ $description "Registers that the absolute stack location " { $snippet "loc" } " should be overwritten with the contents of the virtual register." }
{ $see-also replaces } ;
HELP: replaces
{ $var-description "An " { $link assoc } " that maps from stack locations to virtual registers that were put on the stack during the local analysis phase. " { $link ds-push } " and similar words writes to it." }
{ $see-also replace-loc } ;
ARTICLE: "compiler.cfg.stacks.local" "Local stack analysis"
"For each " { $link basic-block } " in the " { $link cfg } ", local stack analysis is performed. The analysis is started right after the block is created with " { $link begin-local-analysis } " and finished with " { $link end-local-analysis } ", when the construction of the block is complete. During the analysis, three sets containing stack locations are built:"
{ $list
{ { $slot "peeks" } " all stack locations that the block reads before writing" }
{ { $slot "replaces" } " all stack locations that the block writes" }
{ { $slot "kills" } " all stack locations which become unavailable after the block ends because of the stack height being decremented. For example, if the block contains " { $link 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 " { $link end-stack-analysis } " word to emit optimal sequences of " { $link ##peek } " and " { $link ##replace } " instructions to the cfg."
$nl
"For example, the code [ dup dup dup ] will only execute ##peek once, instead of three time which a 'non-lazy' method would."
$nl
"Words for reading the stack state:"
{ $subsections
peek-loc
global-loc>local
local-loc>global
}
"Words for writing the stack state:"
{ $subsections
inc-stack
replace-loc
}
"Beginning and ending analysis:"
{ $subsections
begin-local-analysis
end-local-analysis
}
"Temporary variables that keeps track of the block's read and written stack locations:"
{ $subsections
local-peek-set
replaces
} ;
ABOUT: "compiler.cfg.stacks.local"