Making the fan-in tree generation work. Finally: a 20% reduction in spills and reloads on x86!

db4
Daniel Ehrenberg 2010-02-11 00:19:53 -06:00
parent 6fe9aa50f7
commit edae2fa2d3
1 changed files with 29 additions and 31 deletions

View File

@ -3,7 +3,7 @@
USING: accessors assocs combinators compiler.cfg.def-use USING: accessors assocs combinators compiler.cfg.def-use
compiler.cfg.instructions compiler.cfg.registers fry kernel compiler.cfg.instructions compiler.cfg.registers fry kernel
locals namespaces sequences sets sorting math.vectors locals namespaces sequences sets sorting math.vectors
make math combinators.short-circuit ; make math combinators.short-circuit vectors ;
IN: compiler.cfg.dependence IN: compiler.cfg.dependence
! Dependence graph construction ! Dependence graph construction
@ -16,6 +16,7 @@ SYMBOL: nodes
! These need to be numbered so that the same instruction ! These need to be numbered so that the same instruction
! will get distinct nodes if it occurs multiple times ! will get distinct nodes if it occurs multiple times
TUPLE: node TUPLE: node
precedes-data precedes-control
number insn precedes follows number insn precedes follows
children parent children parent
registers parent-index ; registers parent-index ;
@ -29,6 +30,8 @@ M: node hashcode* nip number>> ;
node-number counter >>number node-number counter >>number
swap >>insn swap >>insn
H{ } clone >>precedes H{ } clone >>precedes
H{ } clone >>precedes-data
H{ } clone >>precedes-control
H{ } clone >>follows ; H{ } clone >>follows ;
: ready? ( node -- ? ) precedes>> assoc-empty? ; : ready? ( node -- ? ) precedes>> assoc-empty? ;
@ -36,17 +39,25 @@ M: node hashcode* nip number>> ;
: precedes ( first second -- ) : precedes ( first second -- )
swap precedes>> conjoin ; swap precedes>> conjoin ;
: precedes-data ( first second -- )
[ precedes ]
[ swap precedes-data>> conjoin ] 2bi ;
: precedes-control ( first second -- )
[ precedes ]
[ swap precedes-control>> conjoin ] 2bi ;
:: add-data-edges ( nodes -- ) :: add-data-edges ( nodes -- )
! This builds up def-use information on the fly, since ! This builds up def-use information on the fly, since
! we only care about local def-use ! we only care about local def-use
H{ } clone :> definers H{ } clone :> definers
nodes [| node | nodes [| node |
node insn>> defs-vreg [ node swap definers set-at ] when* node insn>> defs-vreg [ node swap definers set-at ] when*
node insn>> uses-vregs [ definers at [ node precedes ] when* ] each node insn>> uses-vregs [ definers at [ node precedes-data ] when* ] each
] each ; ] each ;
: make-chain ( nodes -- ) : make-chain ( nodes -- )
[ dup rest-slice [ precedes ] 2each ] unless-empty ; [ dup rest-slice [ precedes-control ] 2each ] unless-empty ;
: instruction-chain ( nodes quot -- ) : instruction-chain ( nodes quot -- )
'[ insn>> @ ] filter make-chain ; inline '[ insn>> @ ] filter make-chain ; inline
@ -113,6 +124,9 @@ UNION: alien-call-insn
[ set-roots ] [ set-roots ]
} cleave ; } cleave ;
! Constructing fan-in trees using the
! Sethi-Ulmann numbering
:: calculate-registers ( node -- registers ) :: calculate-registers ( node -- registers )
node children>> [ 0 ] [ node children>> [ 0 ] [
[ [ calculate-registers ] map natural-sort ] [ [ calculate-registers ] map natural-sort ]
@ -122,38 +136,22 @@ UNION: alien-call-insn
node insn>> temp-vregs length + node insn>> temp-vregs length +
dup node (>>registers) ; dup node (>>registers) ;
: data-dependence? ( to from -- ? ) : attach-parent ( node parent -- )
! If this takes lots of time, then refactor code [ >>parent drop ]
! so that nodes store their data dependences [ [ ?push ] change-children drop ] 2bi ;
[ insn>> ] bi@
[ uses-vregs ] [ defs-vreg ] bi*
swap member? ;
DEFER: follow-tree : choose-parent ( node -- )
! If a node has control dependences, it has to be a root
: maybe-cut-node ( node -- ? ) ! Otherwise, choose one of the data dependences for a parent
! If this node has multiple successors dup precedes-control>> assoc-empty? [
! then it needs to be made into the head of a new tree dup precedes-data>> values [ drop ] [
[ precedes>> assoc-size 1 = dup ] keep first attach-parent
'[ _ dup , follow-tree ] when ; ] if-empty
] [ drop ] if ;
: follow-tree ( node -- )
! This is bogus: it misses nodes that aren't reachable
! from the roots because of a control dependence
dup dup follows>> values
[ data-dependence? ] with filter
[ parent>> not ] filter
[ maybe-cut-node ] filter
[ [ >>parent drop ] with each ]
[ >>children drop ] 2bi ;
: attach-parent ( node -- )
drop ;
: make-trees ( -- trees ) : make-trees ( -- trees )
nodes get nodes get
[ [ attach-parent ] each ] [ [ choose-parent ] each ]
[ [ parent>> not ] filter ] bi ; [ [ parent>> not ] filter ] bi ;
ERROR: node-missing-parent trees nodes ; ERROR: node-missing-parent trees nodes ;