! Copyright (C) 2009 Daniel Ehrenberg ! See http://factorcode.org/license.txt for BSD license. USING: kernel sequences assocs accessors namespaces fry math sets combinators locals compiler.cfg.rpo compiler.cfg.dominance compiler.cfg.def-use compiler.cfg.instructions ; IN: compiler.cfg.ssa.liveness ! Liveness checking on SSA IR, as described in ! "Fast Liveness Checking for SSA-Form Programs", Sebastian Hack et al. ! http://hal.archives-ouvertes.fr/docs/00/19/22/19/PDF/fast_liveness.pdf > ] [ number>> ] tri '[ number>> _ >= ] filter [ R_q ] map assoc-combine [ conjoin ] keep ; : set-R_q ( q -- ) [ next-R_q ] keep R_q-sets get set-at ; : set-back-edges ( q -- ) [ successors>> ] [ number>> ] bi '[ dup number>> _ < [ back-edge-targets get conjoin ] [ drop ] if ] each ; : init-R_q ( -- ) H{ } clone R_q-sets set H{ } clone back-edge-targets set ; : compute-R_q ( cfg -- ) init-R_q post-order [ [ set-R_q ] [ set-back-edges ] bi ] each ; ! This algorithm for computing T_q uses equation (1) ! but not the faster algorithm described in the paper : back-edges-from ( q -- edges ) R_q keys [ [ successors>> ] [ number>> ] bi '[ number>> _ < ] filter ] gather ; : T^_q ( q -- T^_q ) [ back-edges-from ] [ R_q ] bi '[ _ key? not ] filter ; : next-T_q ( q -- T_q ) dup dup T^_q [ next-T_q keys ] map concat unique [ conjoin ] keep [ swap T_q-sets get set-at ] keep ; : compute-T_q ( cfg -- ) H{ } T_q-sets set [ next-T_q drop ] each-basic-block ; PRIVATE> : precompute-liveness ( cfg -- ) [ compute-R_q ] [ compute-T_q ] bi ; : live-in? ( vreg node -- ? ) [ drop ] live? ; :: live-out? ( vreg node -- ? ) vreg def-of :> def { { [ node def eq? ] [ vreg uses-of def only? not ] } { [ def node strictly-dominates? ] [ vreg node (live-out?) ] } [ f ] } cond ;