! Copyright (C) 2010 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays assocs byte-arrays combinators compiler.cfg compiler.cfg.instructions compiler.cfg.loop-detection compiler.cfg.registers compiler.cfg.representations.coalescing compiler.cfg.representations.preferred compiler.cfg.rpo compiler.cfg.utilities compiler.utilities cpu.architecture disjoint-sets fry kernel locals math math.functions namespaces sequences sets ; IN: compiler.cfg.representations.selection SYMBOL: tagged-vregs SYMBOL: vreg-reps : handle-def ( vreg rep -- ) swap vreg>scc vreg-reps get [ [ intersect ] when* ] change-at ; : handle-use ( vreg rep -- ) int-rep eq? [ drop ] [ vreg>scc tagged-vregs get adjoin ] if ; GENERIC: (collect-vreg-reps) ( insn -- ) M: ##load-reference (collect-vreg-reps) [ dst>> ] [ obj>> ] bi { { [ dup float? ] [ drop { float-rep double-rep } ] } { [ dup byte-array? ] [ drop vector-reps ] } [ drop { } ] } cond handle-def ; M: vreg-insn (collect-vreg-reps) [ [ handle-use ] each-use-rep ] [ [ 1array handle-def ] each-def-rep ] [ [ 1array handle-def ] each-temp-rep ] tri ; M: insn (collect-vreg-reps) drop ; : collect-vreg-reps ( cfg -- ) H{ } clone vreg-reps namespaces:set HS{ } clone tagged-vregs namespaces:set [ [ (collect-vreg-reps) ] each-non-phi ] each-basic-block ; SYMBOL: possibilities : possible-reps ( vreg reps -- vreg reps ) { tagged-rep } union 2dup [ tagged-vregs get in? not ] [ { tagged-rep } = ] bi* and [ drop { tagged-rep int-rep } ] when ; : compute-possibilities ( cfg -- ) collect-vreg-reps vreg-reps get [ possible-reps ] assoc-map possibilities namespaces:set ; ! For every vreg, compute the cost of keeping it in every possible ! representation. SYMBOL: costs : init-costs ( -- ) possibilities get [ [ 0 ] H{ } map>assoc ] assoc-map costs namespaces:set ; : increase-cost ( rep scc factor -- ) [ costs get at 2dup key? ] dip '[ [ current-loop-nesting 10^ _ * + ] change-at ] [ 2drop ] if ; :: increase-costs ( vreg preferred factor -- ) vreg vreg>scc :> scc scc possibilities get at [ dup preferred eq? [ drop ] [ scc factor increase-cost ] if ] each ; inline UNION: inert-tag-untag-insn ##add ##sub ##and ##or ##xor ##min ##max ; UNION: inert-arithmetic-tag-untag-insn ##add-imm ##sub-imm ; UNION: inert-bitwise-tag-untag-insn ##and-imm ##or-imm ##xor-imm ; UNION: peephole-optimizable ##load-integer ##load-reference ##neg ##not inert-tag-untag-insn inert-arithmetic-tag-untag-insn inert-bitwise-tag-untag-insn ##mul-imm ##shl-imm ##shr-imm ##sar-imm ##compare-integer-imm ##compare-integer ##compare-integer-imm-branch ##compare-integer-branch ##test-imm ##test ##test-imm-branch ##test-branch ; GENERIC: compute-insn-costs ( insn -- ) M: insn compute-insn-costs drop ; M: vreg-insn compute-insn-costs dup peephole-optimizable? 2 5 ? '[ _ increase-costs ] each-rep ; : compute-costs ( cfg -- ) init-costs [ [ basic-block namespaces:set ] [ [ compute-insn-costs ] each-non-phi ] bi ] each-basic-block ; : minimize-costs ( costs -- representations ) [ nip assoc-empty? ] assoc-reject [ >alist alist-min first ] assoc-map ; : compute-representations ( cfg -- ) compute-costs costs get minimize-costs [ components get [ disjoint-set-members ] keep ] dip '[ dup _ representative _ at ] H{ } map>assoc representations namespaces:set ;