From a4cb242396bc129a5b92559b476e994f7b2408c8 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 28 Jul 2009 06:48:20 -0500 Subject: [PATCH] compiler.cfg.coalescing: Only run if CFG has ##phi nodes, fix interference for case where value is not used in a block and is not live-in, forgot to run liveness analysis first --- .../compiler/cfg/coalescing/coalescing.factor | 31 ++++++++++--------- .../interference/interference.factor | 8 +++-- .../coalescing/live-ranges/live-ranges.factor | 26 +++++++++++++--- basis/compiler/cfg/utilities/utilities.factor | 3 ++ 4 files changed, 47 insertions(+), 21 deletions(-) diff --git a/basis/compiler/cfg/coalescing/coalescing.factor b/basis/compiler/cfg/coalescing/coalescing.factor index a9637088a3..86dee8a3be 100644 --- a/basis/compiler/cfg/coalescing/coalescing.factor +++ b/basis/compiler/cfg/coalescing/coalescing.factor @@ -7,6 +7,7 @@ compiler.cfg.def-use compiler.cfg.utilities compiler.cfg.dominance compiler.cfg.instructions +compiler.cfg.liveness.ssa compiler.cfg.critical-edges compiler.cfg.coalescing.state compiler.cfg.coalescing.forest @@ -36,10 +37,7 @@ SYMBOL: seen V{ } clone seen set renaming-sets get [| dst assoc | assoc [| src bb | - src seen get key? - [ dst assoc src bb visit-renaming ] - [ src seen get conjoin ] - if + dst assoc src bb visit-renaming ] assoc-each ] assoc-each ; @@ -50,14 +48,17 @@ SYMBOL: seen [ [ remove-phis-from-block ] if-has-phis ] each-basic-block ; : coalesce ( cfg -- cfg' ) - init-coalescing - dup split-critical-edges - dup compute-def-use - dup compute-dominance - dup compute-dfs - dup compute-live-ranges - dup process-blocks - break-interferences - dup perform-renaming - insert-copies - dup remove-phis ; \ No newline at end of file + dup cfg-has-phis? [ + init-coalescing + compute-ssa-live-sets + dup split-critical-edges + dup compute-def-use + dup compute-dominance + dup compute-dfs + dup compute-live-ranges + dup process-blocks + break-interferences + dup perform-renaming + insert-copies + dup remove-phis + ] when ; \ No newline at end of file diff --git a/basis/compiler/cfg/coalescing/interference/interference.factor b/basis/compiler/cfg/coalescing/interference/interference.factor index ff5e6319e6..4e0ca99834 100644 --- a/basis/compiler/cfg/coalescing/interference/interference.factor +++ b/basis/compiler/cfg/coalescing/interference/interference.factor @@ -8,8 +8,12 @@ IN: compiler.cfg.coalescing.interference = ; + ! If first register is used after second one is defined, they interfere. + ! If they are used in the same instruction, no interference. If the + ! instruction is a def-is-use-insn, then there will be a use at +1 + ! (instructions are 2 apart) and so outputs will interfere with + ! inputs. + [ kill-index ] [ def-index ] bi-curry bi* > ; : interferes-same-block? ( vreg1 vreg2 bb1 bb2 -- ? ) ! If both are defined in the same basic block, they interfere if their diff --git a/basis/compiler/cfg/coalescing/live-ranges/live-ranges.factor b/basis/compiler/cfg/coalescing/live-ranges/live-ranges.factor index f35a752ea6..c0eafc00fd 100644 --- a/basis/compiler/cfg/coalescing/live-ranges/live-ranges.factor +++ b/basis/compiler/cfg/coalescing/live-ranges/live-ranges.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2009 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors assocs fry kernel namespaces sequences +USING: accessors assocs fry kernel namespaces sequences math compiler.cfg.def-use compiler.cfg.instructions compiler.cfg.liveness compiler.cfg.rpo ; IN: compiler.cfg.coalescing.live-ranges @@ -18,9 +18,15 @@ SYMBOLS: local-def-indices local-kill-indices ; local-kill-indices get '[ _ set-at ] with each ; : visit-insn ( insn n -- ) + ! Instructions are numbered 2 apart. If the instruction requires + ! that outputs are in different registers than the inputs, then + ! a use will be registered for every output immediately after + ! this instruction and before the next one, ensuring that outputs + ! interfere with inputs. + 2 * [ swap defs-vregs record-defs ] [ swap uses-vregs record-uses ] - [ over def-is-use-insn? [ swap defs-vregs record-uses ] [ 2drop ] if ] + [ over def-is-use-insn? [ 1 + swap defs-vregs record-uses ] [ 2drop ] if ] 2tri ; SYMBOLS: def-indices kill-indices ; @@ -28,15 +34,27 @@ SYMBOLS: def-indices kill-indices ; : compute-local-live-ranges ( bb -- ) H{ } clone local-def-indices set H{ } clone local-kill-indices set - instructions>> [ visit-insn ] each-index ; + [ instructions>> [ visit-insn ] each-index ] + [ [ local-def-indices get ] dip def-indices get set-at ] + [ [ local-kill-indices get ] dip kill-indices get set-at ] + tri ; PRIVATE> : compute-live-ranges ( cfg -- ) + H{ } clone def-indices set + H{ } clone kill-indices set [ compute-local-live-ranges ] each-basic-block ; : def-index ( vreg bb -- n ) def-indices get at at ; +ERROR: bad-kill-index vreg bb ; + : kill-index ( vreg bb -- n ) - 2dup live-out key? [ 2drop 1/0. ] [ kill-indices get at at ] if ; + 2dup live-out key? [ 2drop 1/0. ] [ + 2dup kill-indices get at at* [ 2nip ] [ + drop 2dup live-in key? + [ bad-kill-index ] [ 2drop -1/0. ] if + ] if + ] if ; diff --git a/basis/compiler/cfg/utilities/utilities.factor b/basis/compiler/cfg/utilities/utilities.factor index 2be805bd20..48c8ce06b3 100644 --- a/basis/compiler/cfg/utilities/utilities.factor +++ b/basis/compiler/cfg/utilities/utilities.factor @@ -48,5 +48,8 @@ SYMBOL: visited : has-phis? ( bb -- ? ) instructions>> first ##phi? ; +: cfg-has-phis? ( cfg -- ) + post-order [ has-phis? ] any? ; + : if-has-phis ( bb quot: ( bb -- ) -- ) [ dup has-phis? ] dip [ drop ] if ; inline