]> gitweb.factorcode.org Git - factor.git/commitdiff
New approach to stack dead load/store elimination
authorslava <slava@factorcode.org>
Wed, 19 Apr 2006 20:19:26 +0000 (20:19 +0000)
committerslava <slava@factorcode.org>
Wed, 19 Apr 2006 20:19:26 +0000 (20:19 +0000)
library/bootstrap/boot-stage1.factor
library/compiler/intrinsics.factor
library/compiler/linearizer.factor
library/compiler/stack.factor [new file with mode: 0644]
library/compiler/templates.factor

index 3fe721874dd769e50130b33a1d7e93126d2265fb..e063ee395efd6ed7527510dd7f7130924f72b1e9 100644 (file)
@@ -129,6 +129,7 @@ vectors words ;
         "/library/compiler/vops.factor"
         "/library/compiler/templates.factor"
         "/library/compiler/linearizer.factor"
+        "/library/compiler/stack.factor"
         "/library/compiler/xt.factor"
         "/library/compiler/intrinsics.factor"
         "/library/compiler/generator.factor"
index fdd72faddebd42311e719f6fe6a5dff2530075a6..a08fe2d53b5077a652e8f75890d62b8b35616fa1 100644 (file)
@@ -6,52 +6,47 @@ inference kernel kernel-internals lists math math-internals
 namespaces sequences words ;
 
 \ slot [
-    drop
     { { any-reg "obj" } { any-reg "n" } } { "obj" } [
-        "obj" %get %untag ,
-        "n" %get "obj" %get %slot ,
+        "obj" get %untag ,
+        "n" get "obj" get %slot ,
     ] with-template
 ] "intrinsic" set-word-prop
 
 \ set-slot [
-    drop
     { { any-reg "val" } { any-reg "obj" } { any-reg "slot" } }
     { } [
-        "obj" %get %untag ,
-        "val" %get "obj" %get "slot" %get %set-slot ,
+        "obj" get %untag ,
+        "val" get "obj" get "slot" get %set-slot ,
         end-basic-block
         "obj" get %write-barrier ,
     ] with-template
 ] "intrinsic" set-word-prop
 
 \ char-slot [
-    drop
     { { any-reg "n" } { any-reg "str" } } { "str" } [
-        "n" %get "str" %get %char-slot ,
+        "n" get "str" get %char-slot ,
     ] with-template
 ] "intrinsic" set-word-prop
 
 \ set-char-slot [
-    drop
     { { any-reg "ch" } { any-reg "n" } { any-reg "str" } } { } [
-        "ch" %get "str" %get "n" %get %set-char-slot ,
+        "ch" get "str" get "n" get %set-char-slot ,
     ] with-template
 ] "intrinsic" set-word-prop
 
 \ type [
-    drop
     { { any-reg "in" } } { "in" }
-    [ end-basic-block "in" %get %type , ] with-template
+    [ end-basic-block "in" get %type , ] with-template
 ] "intrinsic" set-word-prop
 
 \ tag [
-    drop
-    { { any-reg "in" } } { "in" } [ "in" %get %tag , ] with-template
+    { { any-reg "in" } } { "in" }
+    [ "in" get %tag , ] with-template
 ] "intrinsic" set-word-prop
 
 : binary-op ( op -- )
     { { 0 "x" } { 1 "y" } } { "x" } [
-        end-basic-block >r "y" %get "x" %get dup r> execute ,
+        end-basic-block >r "y" get "x" get dup r> execute ,
     ] with-template ; inline
 
 {
@@ -63,13 +58,13 @@ namespaces sequences words ;
     { fixnum/i      %fixnum/i      }
     { fixnum*       %fixnum*       }
 } [
-    first2 [ binary-op drop ] curry
+    first2 [ binary-op ] curry
     "intrinsic" set-word-prop
 ] each
 
 : binary-jump ( label op -- )
     { { any-reg "x" } { any-reg "y" } } { } [
-        end-basic-block >r >r "y" %get "x" %get r> r> execute ,
+        end-basic-block >r >r "y" get "x" get r> r> execute ,
     ] with-template ; inline
 
 {
@@ -79,37 +74,34 @@ namespaces sequences words ;
     { fixnum>  %jump-fixnum>  }
     { eq?      %jump-eq?      }
 } [
-    first2 [ binary-jump drop ] curry
+    first2 [ binary-jump ] curry
     "if-intrinsic" set-word-prop
 ] each
 
 \ fixnum-mod [
-    drop
     ! This is not clever. Because of x86, %fixnum-mod is
     ! hard-coded to put its output in vreg 2, which happends to
     ! be EDX there.
     { { 0 "x" } { 1 "y" } } { "out" } [
         end-basic-block
         T{ vreg f 2 } "out" set
-        "y" %get "x" %get "out" %get %fixnum-mod ,
+        "y" get "x" get "out" get %fixnum-mod ,
     ] with-template
 ] "intrinsic" set-word-prop
 
 \ fixnum/mod [
-    drop
     ! See the remark on fixnum-mod for vreg usage
     { { 0 "x" } { 1 "y" } } { "quo" "rem" } [
         end-basic-block
         T{ vreg f 0 } "quo" set
         T{ vreg f 2 } "rem" set
-        "y" %get "x" %get 2array
-        "rem" %get "quo" %get 2array %fixnum/mod ,
+        "y" get "x" get 2array
+        "rem" get "quo" get 2array %fixnum/mod ,
     ] with-template
 ] "intrinsic" set-word-prop
 
 \ fixnum-bitnot [
-    drop
     { { any-reg "x" } } { "x" } [
-        "x" %get dup %fixnum-bitnot ,
+        "x" get dup %fixnum-bitnot ,
     ] with-template
 ] "intrinsic" set-word-prop
index aaaa28257dded5cecfa7557b1163d4b55a02f1c9..f87c778fe8fcca8c6a8a915eec6ca2cc36be43bf 100644 (file)
@@ -88,46 +88,16 @@ M: #label linearize* ( node -- next )
 
 M: #call linearize* ( node -- next )
     dup if-intrinsic [
-        >r <label> 2dup r> call
+        >r <label> dup r> call
         >r node-successor r> linearize-if node-successor
     ] [
         dup intrinsic
-        [ call iterate-next ] [ node-param linearize-call ] if*
+        [ call iterate-next ] [ node-param linearize-call ] ?if
     ] if* ;
 
 M: #call-label linearize* ( node -- next )
     node-param renamed-label linearize-call ;
 
-SYMBOL: live-d
-SYMBOL: live-r
-
-: value-dropped? ( value -- ? )
-    dup live-d get member? not
-    swap live-r get member? not and ;
-
-: shuffle-in-template ( values -- template )
-    [
-        dup value-dropped? [ drop f ] when any-reg swap 2array
-    ] map ;
-
-: shuffle-out-template ( instack outstack -- stack )
-    #! Avoid storing a value into its former position.
-    dup length [
-        pick ?nth dupd ( eq? ) 2drop f [ <clean> ] when
-    ] 2map nip ;
-
-: linearize-shuffle ( shuffle -- )
-    dup shuffle-in-d over shuffle-out-d
-    shuffle-out-template live-d set
-    dup shuffle-in-r over shuffle-out-r
-    shuffle-out-template live-r set
-    dup shuffle-in-d shuffle-in-template
-    swap shuffle-in-r shuffle-in-template template-inputs
-    live-d get live-r get template-outputs ;
-
-M: #shuffle linearize* ( #shuffle -- )
-    node-shuffle linearize-shuffle iterate-next ;
-
 : ensure-vregs ( n -- )
     sufficient-vregs?
     [ end-basic-block compute-free-vregs ] unless ;
@@ -145,14 +115,14 @@ M: #push linearize* ( #push -- )
 M: #if linearize* ( node -- next )
     { { 0 "flag" } } { } [
         end-basic-block
-        <label> dup "flag" %get %jump-t ,
+        <label> dup "flag" get %jump-t ,
     ] with-template linearize-if ;
 
 : dispatch-head ( node -- label/node )
     #! Output the jump table insn and return a list of
     #! label/branch pairs.
     { { 0 "n" } } { }
-    [ end-basic-block "n" %get %dispatch , ] with-template
+    [ end-basic-block "n" get %dispatch , ] with-template
     node-children [ <label> dup %target-label ,  2array ] map ;
 
 : dispatch-body ( label/node -- )
diff --git a/library/compiler/stack.factor b/library/compiler/stack.factor
new file mode 100644 (file)
index 0000000..4583328
--- /dev/null
@@ -0,0 +1,37 @@
+! Copyright (C) 2006 Slava Pestov.
+! See http://factorcode.org/license.txt for BSD license.
+IN: compiler
+USING: arrays generic inference io kernel math
+namespaces prettyprint sequences vectors words ;
+
+: phantom-shuffle-input ( n phantom -- seq )
+    2dup length <= [
+        cut-phantom
+    ] [
+        [ phantom-locs ] keep [ length swap tail-slice ] keep
+        append
+    ] if ;
+
+: phantom-shuffle-inputs ( shuffle -- locs locs )
+    dup shuffle-in-d length phantom-d get phantom-shuffle-input
+    swap shuffle-in-r length phantom-r get phantom-shuffle-input ;
+
+: adjust-shuffle ( shuffle -- )
+    dup shuffle-in-d length neg phantom-d get adjust-phantom
+    shuffle-in-r length neg phantom-r get adjust-phantom ;
+
+: sufficient-shuffle-vregs? ( shuffle -- ? )
+    dup shuffle-in-d length phantom-d get length - 0 max
+    over shuffle-in-r length phantom-r get length - 0 max +
+    free-vregs get length <= ;
+
+: phantom-shuffle ( shuffle -- )
+    ! compute-free-vregs sufficient-shuffle-vregs? [
+        end-basic-block compute-free-vregs
+    ! ] unless
+    [ phantom-shuffle-inputs ] keep
+    [ shuffle* ] keep adjust-shuffle
+    (template-outputs) ;
+
+M: #shuffle linearize* ( #shuffle -- )
+    node-shuffle phantom-shuffle iterate-next ;
index 6070e1f69c815115e92be4aad05e2fe8a652b42a..1126c4f8c9bed400e95cb47d78a5e73be764140f 100644 (file)
@@ -4,17 +4,14 @@ IN: compiler
 USING: arrays generic inference io kernel math
 namespaces prettyprint sequences vectors words ;
 
+SYMBOL: free-vregs
+
 ! A data stack location.
 TUPLE: ds-loc n ;
 
 ! A call stack location.
 TUPLE: cs-loc n ;
 
-! A marker for values which are already stored in this location
-TUPLE: clean ;
-
-C: clean [ set-delegate ] keep ;
-
 TUPLE: phantom-stack height ;
 
 C: phantom-stack ( -- stack )
@@ -84,35 +81,46 @@ SYMBOL: phantom-r
 : load-literal ( obj dest -- )
     over immediate? [ %immediate ] [ %indirect ] if , ;
 
-: vreg>stack ( value loc -- )
-    {
-        { [ over not ] [ 2drop ] }
-        { [ over clean? ] [ 2drop ] }
-        { [ t ] [ %replace , ] }
-    } cond ;
+: finalize-heights ( -- )
+    phantom-d get finalize-height
+    phantom-r get finalize-height ;
+
+: alloc-reg ( -- n ) free-vregs get pop ;
 
-: vregs>stack ( phantom -- )
-    dup dup phantom-locs* [ vreg>stack ] 2each
-    0 swap set-length ;
+: lazy-load ( value loc -- value )
+    over ds-loc? pick cs-loc? or [
+        dupd = [
+            drop f
+        ] [
+            >r alloc-reg <vreg> dup r> %peek ,
+        ] if
+    ] [
+        drop
+    ] if ;
 
-: finalize-phantom ( phantom -- )
-    dup finalize-height vregs>stack ;
+: vregs>stack ( values locs -- )
+    [ over [ %replace , ] [ 2drop ] if ] 2each ;
+
+: finalize-contents ( -- )
+    phantom-d get phantom-r get 2dup
+    [ dup phantom-locs* [ [ lazy-load ] 2map ] keep ] 2apply
+    vregs>stack vregs>stack
+    [ 0 swap set-length ] 2apply ;
 
 : end-basic-block ( -- )
-    phantom-d get finalize-phantom
-    phantom-r get finalize-phantom ;
+    finalize-contents finalize-heights ;
 
 : stack>vreg ( vreg loc -- operand )
-    over [ >r <vreg> dup r> %peek , ] [ 2drop f ] if ;
+    >r <vreg> dup r> %peek , ;
 
 SYMBOL: any-reg
 
-SYMBOL: free-vregs
+: used-vregs ( -- seq )
+    phantom-d get phantom-r get append
+    [ vreg? ] subset [ vreg-n ] map ;
 
 : compute-free-vregs ( -- )
-    phantom-d get phantom-r get append
-    [ vreg? ] subset [ vreg-n ] map
-    vregs length reverse diff
+    used-vregs vregs length reverse diff
     >vector free-vregs set ;
 
 : requested-vregs ( template -- n )
@@ -124,20 +132,13 @@ SYMBOL: free-vregs
     [ requested-vregs ] 2apply + ;
 
 : alloc-regs ( template -- template )
-    free-vregs get swap [
-        dup any-reg eq? [ drop pop ] [ nip ] if
-    ] map-with ;
+    [ dup any-reg eq? [ drop alloc-reg ] when ] map ;
 
 : alloc-reg# ( n -- regs )
     free-vregs [ cut ] change ;
 
-: ?clean ( obj -- obj )
-    dup clean? [ delegate ] when ;
-
-: %get ( obj -- value )
-    get ?clean dup value? [ value-literal ] when ;
-
-: phantom-vregs ( values template -- ) [ second set ] 2each ;
+: phantom-vregs ( values template -- )
+    [ >r f lazy-load r> second set ] 2each ;
 
 : stack>vregs ( phantom template -- values )
     [
@@ -147,7 +148,9 @@ SYMBOL: free-vregs
     ] 2keep length neg swap adjust-phantom ;
 
 : compatible-values? ( value template -- ? )
-    >r ?clean r> {
+    {
+        { [ over ds-loc? ] [ 2drop t ] }
+        { [ over cs-loc? ] [ 2drop t ] }
         { [ dup not ] [ 2drop t ] }
         { [ over not ] [ 2drop f ] }
         { [ dup any-reg eq? ] [ 2drop t ] }
@@ -155,62 +158,64 @@ SYMBOL: free-vregs
     } cond ;
 
 : template-match? ( template phantom -- ? )
-    2dup [ length ] 2apply <= [
-        >r dup length r> tail-slice*
-        t [ swap first compatible-values? and ] 2reduce
-    ] [
-        2drop f
-    ] if ;
+    [ reverse-slice ] 2apply
+    t [ swap first compatible-values? and ] 2reduce ;
 
 : templates-match? ( template template -- ? )
-    2dup template-vreg# sufficient-vregs? [
-        phantom-r get template-match?
-        >r phantom-d get template-match? r> and
+    phantom-r get template-match?
+    >r phantom-d get template-match? r> and ;
+
+: split-template ( template phantom -- slow fast )
+    over length over length <= [
+        drop { } swap
     ] [
-        2drop f
+        length swap cut*
     ] if ;
 
-: optimized-input ( template phantom -- )
+: split-templates ( template template -- slow slow fast fast )
+    >r phantom-d get split-template r>
+    phantom-r get split-template swapd ;
+
+: match-templates ( template template -- slow slow fast fast )
+    2dup templates-match? [ split-templates ] [ { } { } ] if ;
+
+: (fast-input) ( template phantom -- )
     over length neg over adjust-phantom
-    over length over cut-phantom
-    >r dup empty? [ drop ] [ vregs>stack ] if r>
+    over length swap cut-phantom
     swap phantom-vregs ;
 
-: template-input ( template phantom -- )
+: fast-input ( template template -- )
+    phantom-r get (fast-input)
+    phantom-d get (fast-input) ;
+
+: (slow-input) ( template phantom -- )
     swap [ stack>vregs ] keep phantom-vregs ;
 
+: slow-input ( template template -- )
+    phantom-r get (slow-input)
+    phantom-d get (slow-input) ;
+
+: adjust-free-vregs ( -- )
+    used-vregs free-vregs [ diff ] change ;
+
 : template-inputs ( template template -- )
-    2dup templates-match? [
-        phantom-r get optimized-input
-        phantom-d get optimized-input
-        compute-free-vregs
-    ] [
-        phantom-r get vregs>stack
-        phantom-d get vregs>stack
-        compute-free-vregs
-        phantom-r get template-input
-        phantom-d get template-input
-    ] if ;
+    compute-free-vregs
+    match-templates fast-input
+    adjust-free-vregs
+    finalize-contents
+    slow-input ;
 
 : drop-phantom ( -- )
     end-basic-block -1 phantom-d get adjust-phantom ;
 
-: prep-output ( value -- value )
-    dup clean? [ delegate ] [ get ?clean ] if ;
-
 : phantom-append ( seq stack -- )
     over length over adjust-phantom swap nappend ;
 
-: template-output ( seq stack -- )
-    >r [ prep-output ] map r> phantom-append ;
-
-: trace-outputs ( stack stack -- )
-    "==== Template output:" print [ . ] 2apply ;
+: (template-outputs) ( seq stack -- )
+    phantom-r get phantom-append phantom-d get phantom-append ;
 
 : template-outputs ( stack stack -- )
-   !  2dup trace-outputs
-    phantom-r get template-output
-    phantom-d get template-output ;
+    [ [ get ] map ] 2apply (template-outputs) ;
 
 : with-template ( in out quot -- )
     swap >r >r { } template-inputs