]> gitweb.factorcode.org Git - factor.git/commitdiff
Merge branch 'master' into global_optimization
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Mon, 1 Jun 2009 08:12:32 +0000 (03:12 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Mon, 1 Jun 2009 08:12:32 +0000 (03:12 -0500)
1  2 
basis/compiler/cfg/alias-analysis/alias-analysis.factor
basis/compiler/cfg/iterator/iterator.factor
basis/compiler/cfg/linear-scan/linear-scan-tests.factor
basis/compiler/cfg/useless-blocks/useless-blocks.factor
basis/cpu/x86/32/32.factor
core/assocs/assocs-tests.factor
core/assocs/assocs.factor

index 2385a4c65a0f40da8c868139f781c79d885360bf,2a9d2579e33b69531258ea35777720050c6ac9f5..d0bb792f72864acb4f0fb59146de75fb79ea67f7
@@@ -1,13 -1,15 +1,13 @@@
 -! Copyright (C) 2008 Slava Pestov.
 +! Copyright (C) 2008, 2009 Slava Pestov.
  ! See http://factorcode.org/license.txt for BSD license.
  USING: kernel math namespaces assocs hashtables sequences arrays
  accessors vectors combinators sets classes compiler.cfg
  compiler.cfg.registers compiler.cfg.instructions
 -compiler.cfg.copy-prop ;
 +compiler.cfg.copy-prop compiler.cfg.rpo
 +compiler.cfg.liveness compiler.cfg.local ;
  IN: compiler.cfg.alias-analysis
  
 -! Alias analysis -- assumes compiler.cfg.height has already run.
 -!
 -! We try to eliminate redundant slot and stack
 -! traffic using some simple heuristics.
 +! We try to eliminate redundant slot operations using some simple heuristics.
  ! 
  ! All heap-allocated objects which are loaded from the stack, or
  ! other object slots are pessimistically assumed to belong to
@@@ -15,6 -17,9 +15,6 @@@
  !
  ! Freshly-allocated objects get their own alias class.
  !
 -! The data and retain stack pointer registers are treated
 -! uniformly, and each one gets its own alias class.
 -! 
  ! Simple pseudo-C example showing load elimination:
  ! 
  ! int *x, *y, z: inputs
  ! Map vregs -> alias classes
  SYMBOL: vregs>acs
  
 -: check ( obj -- obj )
 -    [ "BUG: static type error detected" throw ] unless* ; inline
 - 
 +ERROR: vreg-ac-not-set vreg ;
 +
  : vreg>ac ( vreg -- ac )
      #! Only vregs produced by ##allot, ##peek and ##slot can
      #! ever be used as valid inputs to ##slot and ##set-slot,
      #! so we assert this fact by not giving alias classes to
      #! other vregs.
 -    vregs>acs get at check ;
 +    vregs>acs get ?at [ vreg-ac-not-set ] unless ;
  
  ! Map alias classes -> sequence of vregs
  SYMBOL: acs>vregs
@@@ -116,10 -122,8 +116,10 @@@ SYMBOL: historie
      #! value.
      over [ live-slots get at at ] [ 2drop f ] if ;
  
 +ERROR: vreg-has-no-slots vreg ;
 +
  : load-constant-slot ( value slot# vreg -- )
 -    live-slots get at check set-at ;
 +    live-slots get ?at [ vreg-has-no-slots ] unless set-at ;
  
  : load-slot ( value slot#/f vreg -- )
      over [ load-constant-slot ] [ 3drop ] if ;
@@@ -161,7 -165,7 +161,7 @@@ SYMBOL: heap-a
  
  : record-constant-set-slot ( slot# vreg -- )
      history [
-         dup empty? [ dup peek store? [ dup pop* ] when ] unless
+         dup empty? [ dup last store? [ dup pop* ] when ] unless
          store new-action swap ?push
      ] change-at ;
  
@@@ -185,49 -189,67 +185,49 @@@ SYMBOL: constant
  GENERIC: insn-slot# ( insn -- slot#/f )
  GENERIC: insn-object ( insn -- vreg )
  
 -M: ##peek insn-slot# loc>> n>> ;
 -M: ##replace insn-slot# loc>> n>> ;
  M: ##slot insn-slot# slot>> constant ;
  M: ##slot-imm insn-slot# slot>> ;
  M: ##set-slot insn-slot# slot>> constant ;
  M: ##set-slot-imm insn-slot# slot>> ;
  M: ##alien-global insn-slot# [ library>> ] [ symbol>> ] bi 2array ;
  
 -M: ##peek insn-object loc>> class ;
 -M: ##replace insn-object loc>> class ;
  M: ##slot insn-object obj>> resolve ;
  M: ##slot-imm insn-object obj>> resolve ;
  M: ##set-slot insn-object obj>> resolve ;
  M: ##set-slot-imm insn-object obj>> resolve ;
  M: ##alien-global insn-object drop \ ##alien-global ;
  
 -: init-alias-analysis ( -- )
 +: init-alias-analysis ( live-in -- )
      H{ } clone histories set
      H{ } clone vregs>acs set
      H{ } clone acs>vregs set
      H{ } clone live-slots set
      H{ } clone constants set
      H{ } clone copies set
 -
 +    
      0 ac-counter set
      next-ac heap-ac set
  
 -    ds-loc next-ac set-ac
 -    rs-loc next-ac set-ac ;
 +    [ set-heap-ac ] each ;
  
  GENERIC: analyze-aliases* ( insn -- insn' )
  
  M: ##load-immediate analyze-aliases*
      dup [ val>> ] [ dst>> ] bi constants get set-at ;
  
 -M: ##load-reference analyze-aliases*
 +M: ##flushable analyze-aliases*
      dup dst>> set-heap-ac ;
  
 -M: ##alien-global analyze-aliases*
 -    dup dst>> set-heap-ac ;
 -
 -M: ##allot analyze-aliases*
 -    #! A freshly allocated object is distinct from any other
 -    #! object.
 -    dup dst>> set-new-ac ;
 -
 -M: ##box-float analyze-aliases*
 -    #! A freshly allocated object is distinct from any other
 -    #! object.
 -    dup dst>> set-new-ac ;
 -
 -M: ##box-alien analyze-aliases*
 +M: ##allocation analyze-aliases*
      #! A freshly allocated object is distinct from any other
      #! object.
      dup dst>> set-new-ac ;
  
  M: ##read analyze-aliases*
 -    dup dst>> set-heap-ac
 +    call-next-method
      dup [ dst>> ] [ insn-slot# ] [ insn-object ] tri
      2dup live-slot dup [
 -        2nip f \ ##copy boa analyze-aliases* nip
 +        2nip \ ##copy new-insn analyze-aliases* nip
      ] [
          drop remember-slot
      ] if ;
@@@ -270,6 -292,15 +270,6 @@@ GENERIC: eliminate-dead-stores* ( insn 
          ] unless
      ] when ;
  
 -M: ##replace eliminate-dead-stores*
 -    #! Writes to above the top of the stack can be pruned also.
 -    #! This is sound since any such writes are not observable
 -    #! after the basic block, and any reads of those locations
 -    #! will have been converted to copies by analyze-slot,
 -    #! and the final stack height of the basic block is set at
 -    #! the beginning by compiler.cfg.stack.
 -    dup loc>> n>> 0 < [ drop f ] [ (eliminate-dead-stores) ] if ;
 -
  M: ##set-slot eliminate-dead-stores* (eliminate-dead-stores) ;
  
  M: ##set-slot-imm eliminate-dead-stores* (eliminate-dead-stores) ;
@@@ -279,10 -310,8 +279,10 @@@ M: insn eliminate-dead-stores* 
  : eliminate-dead-stores ( insns -- insns' )
      [ insn# set eliminate-dead-stores* ] map-index sift ;
  
 -: alias-analysis ( insns -- insns' )
 -    init-alias-analysis
 +: alias-analysis-step ( insns -- insns' )
      analyze-aliases
      compute-live-stores
      eliminate-dead-stores ;
 +
 +: alias-analysis ( cfg -- cfg' )
 +    [ init-alias-analysis ] [ alias-analysis-step ] local-optimization ;
index c12e5bdd862eeeadf63fade277a6daa3b33415c2,a8958733a74f239c2607d09e33060a8b7bd1b034..9daf27451c3575db9af693fa62581970906aff8b
@@@ -7,7 -7,7 +7,7 @@@ SYMBOL: node-stac
  
  : >node ( cursor -- ) node-stack get push ;
  : node> ( -- cursor ) node-stack get pop ;
- : node@ ( -- cursor ) node-stack get peek ;
+ : node@ ( -- cursor ) node-stack get last ;
  : current-node ( -- node ) node@ first ;
  : iterate-next ( -- cursor ) node@ rest-slice ;
  : skip-next ( -- next ) node> rest-slice [ first ] [ >node ] bi ;
@@@ -37,9 -37,9 +37,9 @@@ DEFER: (tail-call?
  : tail-call? ( -- ? )
      node-stack get [
          rest-slice
 -        [ t ] [
 -            [ (tail-call?) ]
 -            [ first #terminate? not ]
 -            bi and
 -        ] if-empty
 +        [ t ] [ (tail-call?) ] if-empty
      ] all? ;
 +
 +: terminate-call? ( -- ? )
 +    node-stack get peek
 +    rest-slice [ f ] [ first #terminate? ] if-empty ;
index bfbc8248462e56a5e2dac52cdd03354a8d0697fa,65b932c4a2d492b1754f86b6bf7fda5becc7a5cd..030d8503e9645a6b876a0976500633c18a8fc764
@@@ -3,8 -3,6 +3,8 @@@ USING: tools.test random sorting sequen
  kernel fry arrays splitting namespaces math accessors vectors
  math.order grouping
  cpu.architecture
 +compiler.cfg
 +compiler.cfg.optimizer
  compiler.cfg.instructions
  compiler.cfg.registers
  compiler.cfg.linear-scan
@@@ -246,7 -244,7 +246,7 @@@ SYMBOL: max-use
                  swap int-regs swap vreg boa >>vreg
                  max-uses get random 2 max [ not-taken ] replicate natural-sort
                  [ >>uses ] [ first >>start ] bi
-                 dup uses>> peek >>end
+                 dup uses>> last >>end
          ] map
      ] with-scope ;
  
  
  USING: math.private compiler.cfg.debugger ;
  
 -[ ] [ [ float+ float>fixnum 3 fixnum*fast ] test-mr first linear-scan drop ] unit-test
 +[ ] [
 +    [ float+ float>fixnum 3 fixnum*fast ]
 +    test-cfg first optimize-cfg linear-scan drop
 +] unit-test
  
  [ f ] [
 -    T{ ##allot
 -        f
 -        T{ vreg f int-regs 1 }
 -        40
 -        array
 -        T{ vreg f int-regs 2 }
 -        f
 -    } clone
 -    1array (linear-scan) first regs>> values all-equal?
 +    T{ basic-block
 +       { instructions
 +         V{
 +             T{ ##allot
 +                f
 +                T{ vreg f int-regs 1 }
 +                40
 +                array
 +                T{ vreg f int-regs 2 }
 +                f
 +             }
 +         }
 +       }
 +    } clone [ [ clone ] map ] change-instructions
 +    dup 1array (linear-scan) instructions>> first regs>> values all-equal?
  ] unit-test
  
  [ 0 1 ] [
index 91c337e43ad613026f4cde19ea90d18b8cf00b21,05cb13748b3120cbefb5dec542e1a4314424708b..cbe006b4d7b893048e59cd60ddae75a2ff4452cc
@@@ -1,12 -1,10 +1,12 @@@
 -! Copyright (C) 2008 Slava Pestov.
 +! Copyright (C) 2008, 2009 Slava Pestov.
  ! See http://factorcode.org/license.txt for BSD license.
 -USING: kernel accessors sequences combinators classes vectors
 -compiler.cfg compiler.cfg.rpo compiler.cfg.instructions ;
 +USING: kernel accessors sequences combinators combinators.short-circuit
 +classes vectors compiler.cfg compiler.cfg.instructions compiler.cfg.rpo ;
  IN: compiler.cfg.useless-blocks
  
  : update-predecessor-for-delete ( bb -- )
 +    ! We have to replace occurrences of bb with bb's successor
 +    ! in bb's predecessor's list of successors.
      dup predecessors>> first [
          [
              2dup eq? [ drop successors>> first ] [ nip ] if
      ] change-successors drop ;
  
  : update-successor-for-delete ( bb -- )
 -    [ predecessors>> first ]
 -    [ successors>> first predecessors>> ]
 -    bi set-first ;
 +    ! We have to replace occurrences of bb with bb's predecessor
 +    ! in bb's sucessor's list of predecessors.
 +    dup successors>> first [
 +        [
 +            2dup eq? [ drop predecessors>> first ] [ nip ] if
 +        ] with map
 +    ] change-predecessors drop ;
  
  : delete-basic-block ( bb -- )
      [ update-predecessor-for-delete ]
  
  : delete-basic-block? ( bb -- ? )
      {
 -        { [ dup instructions>> length 1 = not ] [ f ] }
 -        { [ dup predecessors>> length 1 = not ] [ f ] }
 -        { [ dup successors>> length 1 = not ] [ f ] }
 -        { [ dup instructions>> first ##branch? not ] [ f ] }
 -        [ t ]
 -    } cond nip ;
 +        [ instructions>> length 1 = ]
 +        [ predecessors>> length 1 = ]
 +        [ successors>> length 1 = ]
 +        [ instructions>> first ##branch? ]
 +    } 1&& ;
  
  : delete-useless-blocks ( cfg -- cfg' )
      dup [
          dup delete-basic-block? [ delete-basic-block ] [ drop ] if
 -    ] each-basic-block ;
 +    ] each-basic-block
 +    f >>post-order ;
  
  : delete-conditional? ( bb -- ? )
      dup instructions>> [ drop f ] [
-         peek class {
+         last class {
              ##compare-branch
              ##compare-imm-branch
              ##compare-float-branch
  
  : delete-conditional ( bb -- )
      dup successors>> first 1vector >>successors
 -    [ but-last f \ ##branch boa suffix ] change-instructions
 +    [ but-last \ ##branch new-insn suffix ] change-instructions
      drop ;
  
  : delete-useless-conditionals ( cfg -- cfg' )
      dup [
          dup delete-conditional? [ delete-conditional ] [ drop ] if
 -    ] each-basic-block ;
 +    ] each-basic-block
 +    f >>post-order ;
index 4492a3d7625d0aa20841a73e4364687a2ae31a26,95b65912d14e672add1b7bfa72c63481670f2d7b..cf84b083fe59ac60d05282bf6d7ed028f21dc65e
@@@ -26,10 -26,10 +26,10 @@@ M: x86.32 stack-reg ESP 
  M: x86.32 temp-reg-1 ECX ;
  M: x86.32 temp-reg-2 EDX ;
  
 -M:: x86.32 %dispatch ( src temp offset -- )
 +M:: x86.32 %dispatch ( src temp -- )
      ! Load jump table base.
      src HEX: ffffffff ADD
 -    offset cells rc-absolute-cell rel-here
 +    0 rc-absolute-cell rel-here
      ! Go
      src HEX: 7f [+] JMP
      ! Fix up the displacement above
@@@ -305,10 -305,7 +305,7 @@@ os windows? 
      4 "double" c-type (>>align)
  ] unless
  
- FUNCTION: bool check_sse2 ( ) ;
- : sse2? ( -- ? )
-     check_sse2 ;
+ USING: cpu.x86.features cpu.x86.features.private ;
  
  "-no-sse2" (command-line) member? [
      [ { check_sse2 } compile ] with-optimizer
index c21cac263242adc6ad0d67417e1010714d463df9,c473ac0dfa1747e16a629ce5b43db61641b6e53c..75607b0258cb317c05168e30031593f03e9061c8
@@@ -119,18 -119,6 +119,6 @@@ unit-tes
      } extract-keys
  ] unit-test
  
- [ f ] [
-     "a" H{ { "a" f } } at-default
- ] unit-test
- [ "b" ] [
-     "b" H{ { "a" f } } at-default
- ] unit-test
- [ "x" ] [
-     "a" H{ { "a" "x" } } at-default
- ] unit-test
  [ H{ { "b" [ 2 ] } { "d" [ 4 ] } } H{ { "a" [ 1 ] } { "c" [ 3 ] } } ] [
      H{
          { "a" [ 1 ] }
  
  [ 1 f ] [ 1 H{ } ?at ] unit-test
  [ 2 t ] [ 1 H{ { 1 2 } } ?at ] unit-test
 +
 +[ f ] [ 1 2 H{ { 2 1 } } maybe-set-at ] unit-test
 +[ t ] [ 1 3 H{ { 2 1 } } clone maybe-set-at ] unit-test
 +[ t ] [ 3 2 H{ { 2 1 } } clone maybe-set-at ] unit-test
index 7fc3eae00cf2c35ba966569927b5188a538438b2,d655b99c3045ca16bbea780c8050e4583bf0c14a..62ab9f86ae9711f2285deaad9df9128680cd558c
@@@ -22,9 -22,6 +22,9 @@@ M: assoc assoc-like drop 
  : ?at ( key assoc -- value/key ? )
      2dup at* [ 2nip t ] [ 2drop f ] if ; inline
  
 +: maybe-set-at ( value key assoc -- changed? )
 +    3dup at* [ = [ 3drop f ] [ set-at t ] if ] [ 2drop set-at t ] if ;
 +
  <PRIVATE
  
  : (assoc-each) ( assoc quot -- seq quot' )
@@@ -85,9 -82,6 +85,6 @@@ PRIVATE
  : at ( key assoc -- value/f )
      at* drop ; inline
  
- : at-default ( key assoc -- value/key )
-     ?at drop ; inline
  M: assoc assoc-clone-like ( assoc exemplar -- newassoc )
      [ dup assoc-size ] dip new-assoc
      [ [ set-at ] with-assoc assoc-each ] keep ;