From 9a84cfe6568f41d03d70d4dbe3eff1f78c1787eb Mon Sep 17 00:00:00 2001 From: Bruno Deferrari <utizoc@gmail.com> Date: Fri, 1 Aug 2008 19:59:18 -0300 Subject: [PATCH 1/8] irc.client: Fix user quit notification --- extra/irc/client/client-tests.factor | 17 ++++++++++++++++- extra/irc/client/client.factor | 27 +++++++-------------------- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/extra/irc/client/client-tests.factor b/extra/irc/client/client-tests.factor index e021ff4ff4..1b338df442 100644 --- a/extra/irc/client/client-tests.factor +++ b/extra/irc/client/client-tests.factor @@ -160,7 +160,7 @@ IN: irc.client.tests } cleave ] unit-test -! Namelist notification +! Namelist change notification { T{ participant-changed f f f } } [ { ":ircserver.net 353 factorbot @ #factortest :@factorbot " ":ircserver.net 366 factorbot #factortest :End of /NAMES list." } make-client @@ -172,4 +172,19 @@ IN: irc.client.tests [ listeners>> [ "#factortest" ] dip at [ read-message drop ] [ read-message ] bi ] [ terminate-irc ] } cleave + ] unit-test + +{ T{ participant-changed f "somedude" +part+ } } [ + { ":somedude!n=user@isp.net QUIT" } make-client + { [ "factorbot" set-nick ] + [ listeners>> + [ "#factortest" [ <irc-channel-listener> + H{ { "somedude" +normal+ } } clone >>participants ] keep + ] dip set-at ] + [ connect-irc ] + [ drop 0.1 seconds sleep ] + [ listeners>> [ "#factortest" ] dip at + [ read-message drop ] [ read-message drop ] [ read-message ] tri ] + [ terminate-irc ] + } cleave ] unit-test \ No newline at end of file diff --git a/extra/irc/client/client.factor b/extra/irc/client/client.factor index 813de0f57c..99922b1fb5 100644 --- a/extra/irc/client/client.factor +++ b/extra/irc/client/client.factor @@ -88,10 +88,11 @@ SYMBOL: current-irc-client : irc-stream> ( -- stream ) irc> stream>> ; : irc-write ( s -- ) irc-stream> stream-write ; : irc-print ( s -- ) irc-stream> [ stream-print ] keep stream-flush ; +: irc-send ( irc-message -- ) irc> out-messages>> mailbox-put ; : listener> ( name -- listener/f ) irc> listeners>> at ; : maybe-mailbox-get ( mailbox quot: ( irc-message -- ) -- ) - [ dup mailbox-empty? [ drop yield ] ] dip '[ mailbox-get @ ] if ; inline + [ dup mailbox-empty? [ drop 0.1 sleep ] ] dip '[ mailbox-get @ ] if ; inline GENERIC: to-listener ( message obj -- ) @@ -147,24 +148,6 @@ DEFER: me? "JOIN " irc-write [ [ " :" ] dip 3append ] when* irc-print ; -: /PART ( channel text -- ) - [ "PART " irc-write irc-write ] dip - " :" irc-write irc-print ; - -: /KICK ( channel who -- ) - [ "KICK " irc-write irc-write ] dip - " " irc-write irc-print ; - -: /PRIVMSG ( nick line -- ) - [ "PRIVMSG " irc-write irc-write ] dip - " :" irc-write irc-print ; - -: /ACTION ( nick line -- ) - [ 1 , "ACTION " % % 1 , ] "" make /PRIVMSG ; - -: /QUIT ( text -- ) - "QUIT :" irc-write irc-print ; - : /PONG ( text -- ) "PONG " irc-write irc-print ; @@ -240,10 +223,14 @@ M: kick handle-incoming-irc ( kick -- ) M: quit handle-incoming-irc ( quit -- ) [ dup prefix>> parse-name listeners-with-participant [ to-listener ] with each ] - [ prefix>> parse-name remove-participant-from-all ] [ handle-participant-change ] + [ prefix>> parse-name remove-participant-from-all ] tri ; +! FIXME: implement this +! M: mode handle-incoming-irc ( mode -- ) call-next-method ; +! M: nick handle-incoming-irc ( nick -- ) call-next-method ; + : >nick/mode ( string -- nick mode ) dup first "+@" member? [ unclip ] [ 0 ] if participant-mode ; From 710bc04b6ff9040887f0c5b7ec757da0e29d9cf5 Mon Sep 17 00:00:00 2001 From: William Schlieper <schlieper@unc.edu> Date: Sat, 2 Aug 2008 15:54:02 -0400 Subject: [PATCH 2/8] irc.ui: Fixed color bugs --- extra/irc/ui/ui.factor | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/extra/irc/ui/ui.factor b/extra/irc/ui/ui.factor index 662fca6d79..d899b75d8d 100755 --- a/extra/irc/ui/ui.factor +++ b/extra/irc/ui/ui.factor @@ -2,7 +2,7 @@ ! See http://factorcode.org/license.txt for BSD license. USING: accessors kernel threads combinators concurrency.mailboxes - sequences strings hashtables splitting fry assocs hashtables + sequences strings hashtables splitting fry assocs hashtables colors ui ui.gadgets ui.gadgets.panes ui.gadgets.editors ui.gadgets.scrollers ui.commands ui.gadgets.frames ui.gestures ui.gadgets.tabs ui.gadgets.grids ui.gadgets.packs ui.gadgets.labels @@ -24,14 +24,8 @@ TUPLE: irc-tab < frame listener client userlist ; : write-color ( str color -- ) foreground associate format ; -: red { 0.5 0 0 1 } ; -: green { 0 0.5 0 1 } ; -: blue { 0 0 1 1 } ; -: black { 0 0 0 1 } ; - -: colors H{ { +operator+ { 0 0.5 0 1 } } - { +voice+ { 0 0 1 1 } } - { +normal+ { 0 0 0 1 } } } ; +: dark-red T{ rgba f 0.5 0.0 0.0 1 } ; +: dark-green T{ rgba f 0.0 0.5 0.0 1 } ; : dot-or-parens ( string -- string ) dup empty? [ drop "." ] @@ -65,21 +59,21 @@ M: own-message write-irc message>> write ; M: join write-irc - "* " green write-color + "* " dark-green write-color prefix>> parse-name write - " has entered the channel." green write-color ; + " has entered the channel." dark-green write-color ; M: part write-irc - "* " red write-color + "* " dark-red write-color [ prefix>> parse-name write ] keep - " has left the channel" red write-color - trailing>> dot-or-parens red write-color ; + " has left the channel" dark-red write-color + trailing>> dot-or-parens dark-red write-color ; M: quit write-irc - "* " red write-color + "* " dark-red write-color [ prefix>> parse-name write ] keep - " has left IRC" red write-color - trailing>> dot-or-parens red write-color ; + " has left IRC" dark-red write-color + trailing>> dot-or-parens dark-red write-color ; : full-mode ( message -- mode ) parameters>> rest " " sjoin ; @@ -97,13 +91,13 @@ M: unhandled write-irc line>> blue write-color ; M: irc-end write-irc - drop "* You have left IRC" red write-color ; + drop "* You have left IRC" dark-red write-color ; M: irc-disconnected write-irc - drop "* Disconnected" red write-color ; + drop "* Disconnected" dark-red write-color ; M: irc-connected write-irc - drop "* Connected" green write-color ; + drop "* Connected" dark-green write-color ; M: irc-listener-end write-irc drop ; @@ -130,7 +124,7 @@ GENERIC: handle-inbox ( tab message -- ) : update-participants ( tab -- ) [ userlist>> [ clear-gadget ] keep ] [ listener>> participants>> ] bi - [ +operator+ green filter-participants ] + [ +operator+ dark-green filter-participants ] [ +voice+ blue filter-participants ] [ +normal+ black filter-participants ] tri drop ; From d14efabed37ce9c9727924fbf8be34aa72db18db Mon Sep 17 00:00:00 2001 From: Slava Pestov <slava@slava-pestovs-macbook-pro.local> Date: Sat, 2 Aug 2008 20:21:25 -0500 Subject: [PATCH 3/8] Working on escape analysis --- .../allocations/allocations.factor | 26 +++- .../escape-analysis/branches/branches.factor | 10 +- .../escape-analysis-tests.factor | 130 ++++++++++++++++++ .../escape-analysis/escape-analysis.factor | 1 + .../tree/escape-analysis/simple/simple.factor | 3 + 5 files changed, 164 insertions(+), 6 deletions(-) create mode 100644 unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor diff --git a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor index 7600a3b5a2..59febb3801 100644 --- a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor +++ b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: assocs namespaces sequences kernel math +USING: assocs namespaces sequences kernel math combinators sets stack-checker.state compiler.tree.copy-equiv ; IN: compiler.tree.escape-analysis.allocations @@ -13,7 +13,11 @@ SYMBOL: allocations resolve-copy allocations get at ; : record-allocation ( allocation value -- ) - allocations get set-at ; + { + { [ dup not ] [ 2drop ] } + { [ over not ] [ allocations get delete-at drop ] } + [ allocations get set-at ] + } cond ; : record-allocations ( allocations values -- ) [ record-allocation ] 2each ; @@ -25,4 +29,20 @@ SYMBOL: allocations SYMBOL: slot-merging : merge-slots ( values -- value ) - <value> [ introduce-value ] [ slot-merging get set-at ] [ ] tri ; + dup [ ] contains? [ + <value> + [ introduce-value ] + [ slot-merging get set-at ] + [ ] tri + ] [ drop f ] if ; + +! If an allocation's slot appears in this set, the allocation +! is disqualified from unboxing. +SYMBOL: disqualified + +: disqualify ( slot-value -- ) + [ disqualified get conjoin ] + [ slot-merging get at [ disqualify ] each ] bi ; + +: escaping-allocation? ( value -- ? ) + allocation [ [ disqualified get key? ] contains? ] [ t ] if* ; diff --git a/unfinished/compiler/tree/escape-analysis/branches/branches.factor b/unfinished/compiler/tree/escape-analysis/branches/branches.factor index 23e53fd4fe..1bd6973369 100644 --- a/unfinished/compiler/tree/escape-analysis/branches/branches.factor +++ b/unfinished/compiler/tree/escape-analysis/branches/branches.factor @@ -1,6 +1,7 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel namespaces sequences +USING: accessors kernel namespaces sequences sets +stack-checker.branches compiler.tree compiler.tree.propagation.branches compiler.tree.escape-analysis.nodes @@ -12,6 +13,9 @@ SYMBOL: children-escape-data M: #branch escape-analysis* live-children sift [ (escape-analysis) ] each ; +: disqualify-allocations ( allocations -- ) + [ [ disqualify ] each ] each ; + : (merge-allocations) ( values -- allocation ) [ [ allocation ] map dup [ ] all? [ @@ -19,8 +23,8 @@ M: #branch escape-analysis* flip [ (merge-allocations) ] [ [ merge-slots ] map ] bi [ record-allocations ] keep - ] [ drop f ] if - ] [ drop f ] if + ] [ disqualify-allocations f ] if + ] [ disqualify-allocations f ] if ] map ; : merge-allocations ( in-values out-values -- ) diff --git a/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor new file mode 100644 index 0000000000..34ecc74813 --- /dev/null +++ b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor @@ -0,0 +1,130 @@ +IN: compiler.tree.escape-analysis.tests +USING: compiler.tree.escape-analysis +compiler.tree.escape-analysis.allocations compiler.tree.builder +compiler.tree.normalization compiler.tree.copy-equiv +compiler.tree.propagation compiler.tree.cleanup +compiler.tree.combinators compiler.tree sequences math +kernel tools.test accessors slots.private quotations.private +prettyprint ; + +\ escape-analysis must-infer + +: count-unboxed-allocations ( quot -- sizes ) + build-tree + normalize + compute-copy-equiv + propagate + cleanup + escape-analysis + 0 swap [ + dup #call? + [ + out-d>> dup empty? [ drop ] [ + first escaping-allocation? [ 1+ ] unless + ] if + ] [ drop ] if + ] each-node ; + +[ 0 ] [ [ [ + ] curry ] count-unboxed-allocations ] unit-test + +[ 1 ] [ [ [ + ] curry drop ] count-unboxed-allocations ] unit-test + +[ 1 ] [ [ [ + ] curry 3 slot ] count-unboxed-allocations ] unit-test + +[ 1 ] [ [ [ + ] curry 3 slot drop ] count-unboxed-allocations ] unit-test + +[ 1 ] [ [ [ + ] curry uncurry ] count-unboxed-allocations ] unit-test + +[ 1 ] [ [ [ + ] curry call ] count-unboxed-allocations ] unit-test + +[ 1 ] [ [ [ + ] curry call ] count-unboxed-allocations ] unit-test + +[ 0 ] [ [ [ [ + ] curry ] [ drop [ ] ] if ] count-unboxed-allocations ] unit-test + +[ 2 ] [ + [ [ [ + ] curry ] [ [ * ] curry ] if uncurry ] count-unboxed-allocations +] unit-test + +[ 0 ] [ + [ [ [ + ] curry ] [ [ * ] curry ] if ] count-unboxed-allocations +] unit-test + +[ 3 ] [ + [ [ [ + ] curry ] [ dup [ [ * ] curry ] [ [ / ] curry ] if ] if uncurry ] count-unboxed-allocations +] unit-test + +[ 2 ] [ + [ [ [ + ] curry 4 ] [ dup [ [ * ] curry ] [ [ / ] curry ] if uncurry ] if ] count-unboxed-allocations +] unit-test + +[ 0 ] [ + [ [ [ + ] curry ] [ dup [ [ * ] curry ] [ [ / ] curry ] if ] if ] count-unboxed-allocations +] unit-test + +TUPLE: cons { car read-only } { cdr read-only } ; + +[ 0 ] [ + [ + dup 0 = [ + 2 cons boa + ] [ + dup 1 = [ + 3 cons boa + ] when + ] if car>> + ] count-unboxed-allocations +] unit-test + +[ 3 ] [ + [ + dup 0 = [ + 2 cons boa + ] [ + dup 1 = [ + 3 cons boa + ] [ + 4 cons boa + ] if + ] if car>> + ] count-unboxed-allocations +] unit-test + +[ 0 ] [ + [ + dup 0 = [ + dup 1 = [ + 3 cons boa + ] [ + 4 cons boa + ] if + ] unless car>> + ] count-unboxed-allocations +] unit-test + +[ 2 ] [ + [ + dup 0 = [ + 2 cons boa + ] [ + dup 1 = [ + 3 cons boa + ] [ + 4 cons boa + ] if car>> + ] if + ] count-unboxed-allocations +] unit-test + +[ 0 ] [ + [ + dup 0 = [ + 2 cons boa + ] [ + dup 1 = [ + 3 cons boa dup . + ] [ + 4 cons boa + ] if + ] if drop + ] count-unboxed-allocations +] unit-test diff --git a/unfinished/compiler/tree/escape-analysis/escape-analysis.factor b/unfinished/compiler/tree/escape-analysis/escape-analysis.factor index 490fff82ec..e8c02046f2 100644 --- a/unfinished/compiler/tree/escape-analysis/escape-analysis.factor +++ b/unfinished/compiler/tree/escape-analysis/escape-analysis.factor @@ -14,5 +14,6 @@ IN: compiler.tree.escape-analysis : escape-analysis ( node -- node ) H{ } clone slot-merging set H{ } clone allocations set + H{ } clone disqualified set <hashed-dlist> work-list set dup (escape-analysis) ; diff --git a/unfinished/compiler/tree/escape-analysis/simple/simple.factor b/unfinished/compiler/tree/escape-analysis/simple/simple.factor index cc6ac57a5e..93d0b28be3 100644 --- a/unfinished/compiler/tree/escape-analysis/simple/simple.factor +++ b/unfinished/compiler/tree/escape-analysis/simple/simple.factor @@ -24,6 +24,9 @@ IN: compiler.tree.escape-analysis.simple [ in-d>> first ] tri over fixnum? [ [ 3 - ] dip record-slot-access ] [ 3drop ] if ; +: add-escaping-values ( values -- ) + [ allocation [ disqualify ] each ] each ; + M: #call escape-analysis* dup word>> { { \ <tuple-boa> [ record-tuple-allocation ] } From d41bc716bfb26d79a579dfc669baed7026c06c70 Mon Sep 17 00:00:00 2001 From: Slava Pestov <slava@slava-pestovs-macbook-pro.local> Date: Sun, 3 Aug 2008 05:01:05 -0500 Subject: [PATCH 4/8] More escape analysis work --- .../dataflow-analysis.factor | 6 +-- .../allocations/allocations.factor | 30 ++++++++++----- .../escape-analysis-tests.factor | 8 ++-- .../escape-analysis/escape-analysis.factor | 11 +++--- .../escape-analysis/graph/graph-tests.factor | 19 ++++++++++ .../tree/escape-analysis/graph/graph.factor | 38 +++++++++++++++++++ .../tree/escape-analysis/simple/simple.factor | 1 - .../work-list/work-list.factor | 9 ----- 8 files changed, 88 insertions(+), 34 deletions(-) create mode 100644 unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor create mode 100644 unfinished/compiler/tree/escape-analysis/graph/graph.factor delete mode 100644 unfinished/compiler/tree/escape-analysis/work-list/work-list.factor diff --git a/unfinished/compiler/tree/dataflow-analysis/dataflow-analysis.factor b/unfinished/compiler/tree/dataflow-analysis/dataflow-analysis.factor index b6772650b6..c7d558f4bf 100644 --- a/unfinished/compiler/tree/dataflow-analysis/dataflow-analysis.factor +++ b/unfinished/compiler/tree/dataflow-analysis/dataflow-analysis.factor @@ -8,11 +8,9 @@ IN: compiler.tree.dataflow-analysis ! Dataflow analysis SYMBOL: work-list -: look-at-value ( values -- ) - work-list get push-front ; +: look-at-value ( values -- ) work-list get push-front ; -: look-at-values ( values -- ) - work-list get '[ , push-front ] each ; +: look-at-values ( values -- ) work-list get push-all-front ; : look-at-inputs ( node -- ) in-d>> look-at-values ; diff --git a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor index 59febb3801..09c20a93dc 100644 --- a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor +++ b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor @@ -1,7 +1,8 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: assocs namespaces sequences kernel math combinators sets -stack-checker.state compiler.tree.copy-equiv ; +fry stack-checker.state compiler.tree.copy-equiv +compiler.tree.escape-analysis.graph ; IN: compiler.tree.escape-analysis.allocations SYMBOL: escaping @@ -25,24 +26,33 @@ SYMBOL: allocations : record-slot-access ( out slot# in -- ) over zero? [ 3drop ] [ allocation ?nth swap is-copy-of ] if ; -! A map from values to sequences of values -SYMBOL: slot-merging +! We track available values +SYMBOL: slot-graph : merge-slots ( values -- value ) dup [ ] contains? [ <value> [ introduce-value ] - [ slot-merging get set-at ] + [ slot-graph get add-edges ] [ ] tri ] [ drop f ] if ; -! If an allocation's slot appears in this set, the allocation -! is disqualified from unboxing. -SYMBOL: disqualified +! A disqualified slot value is not available for unboxing. A +! tuple may be unboxed if none of its slots have been +! disqualified. : disqualify ( slot-value -- ) - [ disqualified get conjoin ] - [ slot-merging get at [ disqualify ] each ] bi ; + slot-graph get mark-vertex ; + +SYMBOL: escaping-allocations + +: compute-escaping-allocations ( -- ) + #! Any allocations involving unavailable slots are + #! potentially escaping, and cannot be unboxed. + allocations get + slot-graph get marked-components + '[ [ , key? ] contains? nip ] assoc-filter + escaping-allocations set ; : escaping-allocation? ( value -- ? ) - allocation [ [ disqualified get key? ] contains? ] [ t ] if* ; + escaping-allocations get key? ; diff --git a/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor index 34ecc74813..83cdfd980b 100644 --- a/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor +++ b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor @@ -5,7 +5,7 @@ compiler.tree.normalization compiler.tree.copy-equiv compiler.tree.propagation compiler.tree.cleanup compiler.tree.combinators compiler.tree sequences math kernel tools.test accessors slots.private quotations.private -prettyprint ; +prettyprint classes.tuple.private ; \ escape-analysis must-infer @@ -19,9 +19,9 @@ prettyprint ; 0 swap [ dup #call? [ - out-d>> dup empty? [ drop ] [ - first escaping-allocation? [ 1+ ] unless - ] if + dup word>> \ <tuple-boa> = [ + out-d>> first escaping-allocation? [ 1+ ] unless + ] [ drop ] if ] [ drop ] if ] each-node ; diff --git a/unfinished/compiler/tree/escape-analysis/escape-analysis.factor b/unfinished/compiler/tree/escape-analysis/escape-analysis.factor index e8c02046f2..c41627005b 100644 --- a/unfinished/compiler/tree/escape-analysis/escape-analysis.factor +++ b/unfinished/compiler/tree/escape-analysis/escape-analysis.factor @@ -3,17 +3,16 @@ USING: kernel namespaces search-dequeues compiler.tree compiler.tree.def-use +compiler.tree.escape-analysis.graph compiler.tree.escape-analysis.allocations compiler.tree.escape-analysis.recursive compiler.tree.escape-analysis.branches compiler.tree.escape-analysis.nodes -compiler.tree.escape-analysis.simple -compiler.tree.escape-analysis.work-list ; +compiler.tree.escape-analysis.simple ; IN: compiler.tree.escape-analysis : escape-analysis ( node -- node ) - H{ } clone slot-merging set H{ } clone allocations set - H{ } clone disqualified set - <hashed-dlist> work-list set - dup (escape-analysis) ; + <graph> slot-graph set + dup (escape-analysis) + compute-escaping-allocations ; diff --git a/unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor b/unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor new file mode 100644 index 0000000000..3a7dee58a9 --- /dev/null +++ b/unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor @@ -0,0 +1,19 @@ +IN: compiler.tree.escape-analysis.graph.tests +USING: compiler.tree.escape-analysis.graph tools.test namespaces +accessors ; + +<graph> "graph" set + +[ ] [ { 2 3 4 } 1 "graph" get add-edges ] unit-test +[ ] [ { 5 6 } 2 "graph" get add-edges ] unit-test +[ ] [ { 7 8 } 9 "graph" get add-edges ] unit-test +[ ] [ { 6 10 } 4 "graph" get add-edges ] unit-test + +[ ] [ 3 "graph" get mark-vertex ] unit-test + +[ H{ { 1 1 } { 2 2 } { 3 3 } { 4 4 } { 5 5 } { 6 6 } { 10 10 } } ] +[ "graph" get marked>> ] unit-test + +[ ] [ { 1 11 } 12 "graph" get add-edges ] unit-test + +[ t ] [ 11 "graph" get marked-vertex? ] unit-test diff --git a/unfinished/compiler/tree/escape-analysis/graph/graph.factor b/unfinished/compiler/tree/escape-analysis/graph/graph.factor new file mode 100644 index 0000000000..59ba51d99e --- /dev/null +++ b/unfinished/compiler/tree/escape-analysis/graph/graph.factor @@ -0,0 +1,38 @@ +! Copyright (C) 2008 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: kernel accessors assocs fry sequences sets +dequeues search-dequeues namespaces ; +IN: compiler.tree.escape-analysis.graph + +TUPLE: graph edges work-list ; + +: <graph> ( -- graph ) + H{ } clone <hashed-dlist> graph boa ; + +: mark-vertex ( vertex graph -- ) work-list>> push-front ; + +: add-edge ( out in graph -- ) + [ edges>> push-at ] [ swapd edges>> push-at ] 3bi ; + +: add-edges ( out-seq in graph -- ) + '[ , , add-edge ] each ; + +<PRIVATE + +SYMBOL: marked + +: (mark-vertex) ( vertex graph -- ) + over marked get key? [ 2drop ] [ + [ drop marked get conjoin ] + [ [ edges>> at ] [ work-list>> ] bi push-all-front ] + 2bi + ] if ; + +PRIVATE> + +: marked-components ( graph -- vertices ) + #! All vertices in connected components of marked vertices. + H{ } clone marked [ + [ work-list>> ] keep + '[ , (mark-vertex) ] slurp-dequeue + ] with-variable ; diff --git a/unfinished/compiler/tree/escape-analysis/simple/simple.factor b/unfinished/compiler/tree/escape-analysis/simple/simple.factor index 93d0b28be3..8329a04a61 100644 --- a/unfinished/compiler/tree/escape-analysis/simple/simple.factor +++ b/unfinished/compiler/tree/escape-analysis/simple/simple.factor @@ -6,7 +6,6 @@ combinators dequeues search-dequeues namespaces fry compiler.tree compiler.tree.propagation.info compiler.tree.escape-analysis.nodes -compiler.tree.escape-analysis.work-list compiler.tree.escape-analysis.allocations ; IN: compiler.tree.escape-analysis.simple diff --git a/unfinished/compiler/tree/escape-analysis/work-list/work-list.factor b/unfinished/compiler/tree/escape-analysis/work-list/work-list.factor deleted file mode 100644 index 8378ee43ae..0000000000 --- a/unfinished/compiler/tree/escape-analysis/work-list/work-list.factor +++ /dev/null @@ -1,9 +0,0 @@ -! Copyright (C) 2008 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: dequeues namespaces sequences fry ; -IN: compiler.tree.escape-analysis.work-list - -SYMBOL: work-list - -: add-escaping-values ( values -- ) - work-list get '[ , push-front ] each ; From 64bed4e44e9f4eb495ed5196b4408bd4ca19714f Mon Sep 17 00:00:00 2001 From: William Schlieper <schlieper@unc.edu> Date: Sun, 3 Aug 2008 13:21:32 -0400 Subject: [PATCH 5/8] irc.ui: Userlists are now sorted --- extra/irc/ui/ui.factor | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/extra/irc/ui/ui.factor b/extra/irc/ui/ui.factor index d899b75d8d..0c9fdee6e0 100755 --- a/extra/irc/ui/ui.factor +++ b/extra/irc/ui/ui.factor @@ -3,12 +3,13 @@ USING: accessors kernel threads combinators concurrency.mailboxes sequences strings hashtables splitting fry assocs hashtables colors + sorting qualified unicode.case math.order ui ui.gadgets ui.gadgets.panes ui.gadgets.editors ui.gadgets.scrollers ui.commands ui.gadgets.frames ui.gestures ui.gadgets.tabs ui.gadgets.grids ui.gadgets.packs ui.gadgets.labels io io.styles namespaces calendar calendar.format models continuations irc.client irc.client.private irc.messages irc.messages.private - irc.ui.commandparser irc.ui.load qualified ; + irc.ui.commandparser irc.ui.load ; RENAME: join sequences => sjoin @@ -86,6 +87,12 @@ M: mode write-irc " to " blue write-color channel>> write ; +M: nick write-irc + "* " blue write-color + [ prefix>> parse-name write ] keep + " is now known as " blue write-color + trailing>> write ; + M: unhandled write-irc "UNHANDLED: " write line>> blue write-color ; @@ -118,15 +125,18 @@ M: irc-message write-irc GENERIC: handle-inbox ( tab message -- ) -: filter-participants ( pack alist val color -- pack ) - '[ , = [ <label> , >>color add-gadget ] [ drop ] if ] assoc-each ; +: value-labels ( assoc val -- seq ) + '[ nip , = ] assoc-filter keys [ >lower <=> ] sort [ <label> ] map ; + +: add-gadget-color ( pack seq color -- pack ) + '[ , >>color add-gadget ] each ; : update-participants ( tab -- ) [ userlist>> [ clear-gadget ] keep ] [ listener>> participants>> ] bi - [ +operator+ dark-green filter-participants ] - [ +voice+ blue filter-participants ] - [ +normal+ black filter-participants ] tri drop ; + [ +operator+ value-labels dark-green add-gadget-color ] + [ +voice+ value-labels blue add-gadget-color ] + [ +normal+ value-labels black add-gadget-color ] tri drop ; M: participant-changed handle-inbox drop update-participants ; From 0ed0167dd6b5df5f9816cf86a7b43353f5d2fbb1 Mon Sep 17 00:00:00 2001 From: Slava Pestov <slava@slava-pestovs-macbook-pro.local> Date: Sun, 3 Aug 2008 21:32:12 -0500 Subject: [PATCH 6/8] More accurate escape analysis --- .../allocations/allocations.factor | 62 ++++++++++++------- .../escape-analysis/branches/branches.factor | 17 +++-- .../escape-analysis-tests.factor | 47 +++++++++++--- .../escape-analysis/escape-analysis.factor | 7 ++- .../escape-analysis/graph/graph-tests.factor | 19 ------ .../tree/escape-analysis/graph/graph.factor | 38 ------------ .../tree/escape-analysis/simple/simple.factor | 15 +++-- 7 files changed, 100 insertions(+), 105 deletions(-) delete mode 100644 unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor delete mode 100644 unfinished/compiler/tree/escape-analysis/graph/graph.factor diff --git a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor index 09c20a93dc..19a5e5b12a 100644 --- a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor +++ b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor @@ -1,13 +1,10 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. USING: assocs namespaces sequences kernel math combinators sets -fry stack-checker.state compiler.tree.copy-equiv -compiler.tree.escape-analysis.graph ; +disjoint-sets fry stack-checker.state compiler.tree.copy-equiv ; IN: compiler.tree.escape-analysis.allocations -SYMBOL: escaping - -! A map from values to sequences of values or 'escaping' +! A map from values to sequences of values SYMBOL: allocations : allocation ( value -- allocation ) @@ -23,35 +20,56 @@ SYMBOL: allocations : record-allocations ( allocations values -- ) [ record-allocation ] 2each ; -: record-slot-access ( out slot# in -- ) - over zero? [ 3drop ] [ allocation ?nth swap is-copy-of ] if ; +! We track escaping values with a disjoint set. +SYMBOL: escaping-values -! We track available values -SYMBOL: slot-graph +SYMBOL: +escaping+ + +: <escaping-values> ( -- disjoint-set ) + <disjoint-set> +escaping+ over add-atom ; + +: init-escaping-values ( -- ) + copies get <escaping-values> + [ '[ drop , add-atom ] assoc-each ] + [ '[ , equate ] assoc-each ] + [ nip escaping-values set ] + 2tri ; + +: <slot-value> ( -- value ) + <value> + [ introduce-value ] + [ escaping-values get add-atom ] + [ ] + tri ; + +: same-value ( in-value out-value -- ) + over [ + [ is-copy-of ] [ escaping-values get equate ] 2bi + ] [ 2drop ] if ; + +: record-slot-access ( out slot# in -- ) + over zero? [ 3drop ] [ allocation ?nth swap same-value ] if ; + +: merge-values ( in-values out-value -- ) + escaping-values get '[ , , equate ] each ; : merge-slots ( values -- value ) dup [ ] contains? [ - <value> - [ introduce-value ] - [ slot-graph get add-edges ] - [ ] tri + <slot-value> [ merge-values ] keep ] [ drop f ] if ; -! A disqualified slot value is not available for unboxing. A -! tuple may be unboxed if none of its slots have been -! disqualified. +: add-escaping-values ( values -- ) + escaping-values get + '[ +escaping+ , equate ] each ; -: disqualify ( slot-value -- ) - slot-graph get mark-vertex ; +: escaping-value? ( value -- ? ) + +escaping+ escaping-values get equiv? ; SYMBOL: escaping-allocations : compute-escaping-allocations ( -- ) - #! Any allocations involving unavailable slots are - #! potentially escaping, and cannot be unboxed. allocations get - slot-graph get marked-components - '[ [ , key? ] contains? nip ] assoc-filter + [ drop escaping-value? ] assoc-filter escaping-allocations set ; : escaping-allocation? ( value -- ? ) diff --git a/unfinished/compiler/tree/escape-analysis/branches/branches.factor b/unfinished/compiler/tree/escape-analysis/branches/branches.factor index 1bd6973369..950e0341f9 100644 --- a/unfinished/compiler/tree/escape-analysis/branches/branches.factor +++ b/unfinished/compiler/tree/escape-analysis/branches/branches.factor @@ -1,6 +1,6 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors kernel namespaces sequences sets +USING: accessors kernel namespaces sequences sets fry stack-checker.branches compiler.tree compiler.tree.propagation.branches @@ -13,22 +13,21 @@ SYMBOL: children-escape-data M: #branch escape-analysis* live-children sift [ (escape-analysis) ] each ; -: disqualify-allocations ( allocations -- ) - [ [ disqualify ] each ] each ; - : (merge-allocations) ( values -- allocation ) [ - [ allocation ] map dup [ ] all? [ + dup [ allocation ] map dup [ ] all? [ dup [ length ] map all-equal? [ - flip + nip flip [ (merge-allocations) ] [ [ merge-slots ] map ] bi [ record-allocations ] keep - ] [ disqualify-allocations f ] if - ] [ disqualify-allocations f ] if + ] [ drop add-escaping-values f ] if + ] [ drop add-escaping-values f ] if ] map ; : merge-allocations ( in-values out-values -- ) - [ (merge-allocations) ] dip record-allocations ; + [ [ merge-values ] 2each ] + [ [ (merge-allocations) ] dip record-allocations ] + 2bi ; M: #phi escape-analysis* [ [ phi-in-d>> ] [ out-d>> ] bi merge-allocations ] diff --git a/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor index 83cdfd980b..6f99868c23 100644 --- a/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor +++ b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor @@ -5,10 +5,25 @@ compiler.tree.normalization compiler.tree.copy-equiv compiler.tree.propagation compiler.tree.cleanup compiler.tree.combinators compiler.tree sequences math kernel tools.test accessors slots.private quotations.private -prettyprint classes.tuple.private ; +prettyprint classes.tuple.private classes classes.tuple ; \ escape-analysis must-infer +GENERIC: count-unboxed-allocations* ( m node -- n ) + +: (count-unboxed-allocations) ( m node -- n ) + out-d>> first escaping-allocation? [ 1+ ] unless ; + +M: #call count-unboxed-allocations* + dup word>> \ <tuple-boa> = + [ (count-unboxed-allocations) ] [ drop ] if ; + +M: #push count-unboxed-allocations* + dup literal>> class immutable-tuple-class? + [ (count-unboxed-allocations) ] [ drop ] if ; + +M: node count-unboxed-allocations* drop ; + : count-unboxed-allocations ( quot -- sizes ) build-tree normalize @@ -16,14 +31,7 @@ prettyprint classes.tuple.private ; propagate cleanup escape-analysis - 0 swap [ - dup #call? - [ - dup word>> \ <tuple-boa> = [ - out-d>> first escaping-allocation? [ 1+ ] unless - ] [ drop ] if - ] [ drop ] if - ] each-node ; + 0 swap [ count-unboxed-allocations* ] each-node ; [ 0 ] [ [ [ + ] curry ] count-unboxed-allocations ] unit-test @@ -128,3 +136,24 @@ TUPLE: cons { car read-only } { cdr read-only } ; ] if drop ] count-unboxed-allocations ] unit-test + +[ 2 ] [ + [ + [ dup cons boa ] [ drop 1 2 cons boa ] if car>> + ] count-unboxed-allocations +] unit-test + +[ 2 ] [ + [ + 3dup + [ cons boa ] [ cons boa 3 cons boa ] if + [ car>> ] [ cdr>> ] bi + ] count-unboxed-allocations +] unit-test + +[ 2 ] [ + [ + 3dup [ cons boa ] [ cons boa . 1 2 cons boa ] if + [ car>> ] [ cdr>> ] bi + ] count-unboxed-allocations +] unit-test diff --git a/unfinished/compiler/tree/escape-analysis/escape-analysis.factor b/unfinished/compiler/tree/escape-analysis/escape-analysis.factor index c41627005b..0ba44a1dc5 100644 --- a/unfinished/compiler/tree/escape-analysis/escape-analysis.factor +++ b/unfinished/compiler/tree/escape-analysis/escape-analysis.factor @@ -1,9 +1,10 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: kernel namespaces search-dequeues +USING: kernel namespaces search-dequeues assocs fry sequences +disjoint-sets compiler.tree compiler.tree.def-use -compiler.tree.escape-analysis.graph +compiler.tree.copy-equiv compiler.tree.escape-analysis.allocations compiler.tree.escape-analysis.recursive compiler.tree.escape-analysis.branches @@ -12,7 +13,7 @@ compiler.tree.escape-analysis.simple ; IN: compiler.tree.escape-analysis : escape-analysis ( node -- node ) + init-escaping-values H{ } clone allocations set - <graph> slot-graph set dup (escape-analysis) compute-escaping-allocations ; diff --git a/unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor b/unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor deleted file mode 100644 index 3a7dee58a9..0000000000 --- a/unfinished/compiler/tree/escape-analysis/graph/graph-tests.factor +++ /dev/null @@ -1,19 +0,0 @@ -IN: compiler.tree.escape-analysis.graph.tests -USING: compiler.tree.escape-analysis.graph tools.test namespaces -accessors ; - -<graph> "graph" set - -[ ] [ { 2 3 4 } 1 "graph" get add-edges ] unit-test -[ ] [ { 5 6 } 2 "graph" get add-edges ] unit-test -[ ] [ { 7 8 } 9 "graph" get add-edges ] unit-test -[ ] [ { 6 10 } 4 "graph" get add-edges ] unit-test - -[ ] [ 3 "graph" get mark-vertex ] unit-test - -[ H{ { 1 1 } { 2 2 } { 3 3 } { 4 4 } { 5 5 } { 6 6 } { 10 10 } } ] -[ "graph" get marked>> ] unit-test - -[ ] [ { 1 11 } 12 "graph" get add-edges ] unit-test - -[ t ] [ 11 "graph" get marked-vertex? ] unit-test diff --git a/unfinished/compiler/tree/escape-analysis/graph/graph.factor b/unfinished/compiler/tree/escape-analysis/graph/graph.factor deleted file mode 100644 index 59ba51d99e..0000000000 --- a/unfinished/compiler/tree/escape-analysis/graph/graph.factor +++ /dev/null @@ -1,38 +0,0 @@ -! Copyright (C) 2008 Slava Pestov. -! See http://factorcode.org/license.txt for BSD license. -USING: kernel accessors assocs fry sequences sets -dequeues search-dequeues namespaces ; -IN: compiler.tree.escape-analysis.graph - -TUPLE: graph edges work-list ; - -: <graph> ( -- graph ) - H{ } clone <hashed-dlist> graph boa ; - -: mark-vertex ( vertex graph -- ) work-list>> push-front ; - -: add-edge ( out in graph -- ) - [ edges>> push-at ] [ swapd edges>> push-at ] 3bi ; - -: add-edges ( out-seq in graph -- ) - '[ , , add-edge ] each ; - -<PRIVATE - -SYMBOL: marked - -: (mark-vertex) ( vertex graph -- ) - over marked get key? [ 2drop ] [ - [ drop marked get conjoin ] - [ [ edges>> at ] [ work-list>> ] bi push-all-front ] - 2bi - ] if ; - -PRIVATE> - -: marked-components ( graph -- vertices ) - #! All vertices in connected components of marked vertices. - H{ } clone marked [ - [ work-list>> ] keep - '[ , (mark-vertex) ] slurp-dequeue - ] with-variable ; diff --git a/unfinished/compiler/tree/escape-analysis/simple/simple.factor b/unfinished/compiler/tree/escape-analysis/simple/simple.factor index 8329a04a61..8828b4c410 100644 --- a/unfinished/compiler/tree/escape-analysis/simple/simple.factor +++ b/unfinished/compiler/tree/escape-analysis/simple/simple.factor @@ -2,17 +2,25 @@ ! See http://factorcode.org/license.txt for BSD license. USING: kernel accessors sequences classes.tuple classes.tuple.private math math.private slots.private -combinators dequeues search-dequeues namespaces fry +combinators dequeues search-dequeues namespaces fry classes +stack-checker.state compiler.tree compiler.tree.propagation.info compiler.tree.escape-analysis.nodes compiler.tree.escape-analysis.allocations ; IN: compiler.tree.escape-analysis.simple +M: #push escape-analysis* + #! Delegation. + dup literal>> dup class immutable-tuple-class? [ + tuple-slots length 1- [ <slot-value> ] replicate + swap out-d>> first record-allocation + ] [ 2drop ] if ; + : record-tuple-allocation ( #call -- ) #! Delegation. dup dup in-d>> peek node-value-info literal>> - class>> all-slots rest-slice [ read-only>> ] all? [ + class>> immutable-tuple-class? [ [ in-d>> but-last ] [ out-d>> first ] bi record-allocation ] [ drop ] if ; @@ -23,9 +31,6 @@ IN: compiler.tree.escape-analysis.simple [ in-d>> first ] tri over fixnum? [ [ 3 - ] dip record-slot-access ] [ 3drop ] if ; -: add-escaping-values ( values -- ) - [ allocation [ disqualify ] each ] each ; - M: #call escape-analysis* dup word>> { { \ <tuple-boa> [ record-tuple-allocation ] } From 04a72f2472c37c892dd80cf9f2231416cefd3908 Mon Sep 17 00:00:00 2001 From: Slava Pestov <slava@slava-pestovs-macbook-pro.local> Date: Sun, 3 Aug 2008 21:55:19 -0500 Subject: [PATCH 7/8] Document disjoint-sets --- basis/disjoint-sets/disjoint-sets-docs.factor | 58 +++++++++++++++++++ basis/disjoint-sets/disjoint-sets.factor | 13 +++-- .../allocations/allocations.factor | 26 ++++----- .../escape-analysis/branches/branches.factor | 2 - 4 files changed, 78 insertions(+), 21 deletions(-) create mode 100644 basis/disjoint-sets/disjoint-sets-docs.factor diff --git a/basis/disjoint-sets/disjoint-sets-docs.factor b/basis/disjoint-sets/disjoint-sets-docs.factor new file mode 100644 index 0000000000..b1d7cf685a --- /dev/null +++ b/basis/disjoint-sets/disjoint-sets-docs.factor @@ -0,0 +1,58 @@ +IN: disjoint-sets +USING: help.markup help.syntax kernel assocs math ; + +HELP: <disjoint-set> +{ $values { "disjoint-set" disjoint-set } } +{ $description "Creates a new disjoint set data structure with no elements." } ; + +HELP: add-atom +{ $values { "a" object } { "disjoint-set" disjoint-set } } +{ $description "Adds a new element to the disjoint set, initially only equivalent to itself." } ; + +HELP: equiv-set-size +{ $values { "a" object } { "disjoint-set" disjoint-set } { "n" integer } } +{ $description "Outputs the number of elements in the equivalence class of " { $snippet "a" } "." } ; + +HELP: equiv? +{ $values { "a" object } { "b" object } { "disjoint-set" disjoint-set } { "?" "a boolean" } } +{ $description "Tests if two elements belong to the same equivalence class." } ; + +HELP: equate +{ $values { "a" object } { "b" object } { "disjoint-set" disjoint-set } } +{ $description "Merges the equivalence classes of two elements, which must previously have been added with " { $link add-atom } "." } ; + +HELP: assoc>disjoint-set +{ $values { "assoc" assoc } { "disjoint-set" disjoint-set } } +{ $description "Given an assoc representation of a graph where the keys are vertices and key/value pairs are edges, creates a disjoint set whose elements are the keys of assoc, and two keys are equvalent if they belong to the same connected component of the graph." } +{ $examples + { $example + "USING: disjoint-sets kernel prettyprint ;" + "H{ { 1 1 } { 2 1 } { 3 4 } { 4 4 } { 5 3 } } assoc>disjoint-set" + "1 2 pick equiv? ." + "4 5 pick equiv? ." + "1 5 pick equiv? ." + "drop" + "t\nt\nf\n" + } +} ; + +ARTICLE: "disjoint-sets" "Disjoint sets" +"The " { $emphasis "disjoint set" } " data structure, also known as " { $emphasis "union-find" } " (after the two main operations which it supports) represents a set of elements partitioned into disjoint equivalence classes, or alternatively, an equivalence relation on a set." +$nl +"The two main supported operations are equating two elements, which joins their equivalence classes, and checking if two elements belong to the same equivalence class. Both operations have the time complexity of the inverse Ackermann function, which for all intents and purposes is constant time." +$nl +"The class of disjoint sets:" +{ $subsection disjoint-set } +"Creating new disjoint sets:" +{ $subsection <disjoint-set> } +{ $subsection assoc>disjoint-set } +"Queries:" +{ $subsection equiv? } +{ $subsection equiv-set-size } +"Adding elements:" +{ $subsection add-atom } +"Equating elements:" +{ $subsection equate } +"Additionally, disjoint sets implement the " { $link clone } " generic word." ; + +ABOUT: "disjoint-sets" diff --git a/basis/disjoint-sets/disjoint-sets.factor b/basis/disjoint-sets/disjoint-sets.factor index 284d206da4..a885e333c5 100644 --- a/basis/disjoint-sets/disjoint-sets.factor +++ b/basis/disjoint-sets/disjoint-sets.factor @@ -1,7 +1,7 @@ ! Copyright (C) 2008 Eric Mertens. ! See http://factorcode.org/license.txt for BSD license. USING: accessors arrays hints kernel locals math hashtables -assocs ; +assocs fry ; IN: disjoint-sets @@ -36,8 +36,6 @@ TUPLE: disjoint-set : representative? ( a disjoint-set -- ? ) dupd parent = ; inline -PRIVATE> - GENERIC: representative ( a disjoint-set -- p ) M: disjoint-set representative @@ -45,8 +43,6 @@ M: disjoint-set representative [ [ parent ] keep representative dup ] 2keep set-parent ] if ; -<PRIVATE - : representatives ( a b disjoint-set -- r r ) [ representative ] curry bi@ ; inline @@ -90,3 +86,10 @@ M:: disjoint-set equate ( a b disjoint-set -- ) M: disjoint-set clone [ parents>> ] [ ranks>> ] [ counts>> ] tri [ clone ] tri@ disjoint-set boa ; + +: assoc>disjoint-set ( assoc -- disjoint-set ) + <disjoint-set> + [ '[ drop , add-atom ] assoc-each ] + [ '[ , equate ] assoc-each ] + [ nip ] + 2tri ; diff --git a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor index 19a5e5b12a..4bd23aa8a7 100644 --- a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor +++ b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor @@ -4,18 +4,19 @@ USING: assocs namespaces sequences kernel math combinators sets disjoint-sets fry stack-checker.state compiler.tree.copy-equiv ; IN: compiler.tree.escape-analysis.allocations -! A map from values to sequences of values +! A map from values to one of the following: +! - f -- initial status, assigned to values we have not seen yet; +! may potentially become an allocation later +! - a sequence of values -- potentially unboxed tuple allocations +! - t -- not allocated locally, can never be unboxed + SYMBOL: allocations -: allocation ( value -- allocation ) - resolve-copy allocations get at ; +: (allocation) resolve-copy allocations get ; inline -: record-allocation ( allocation value -- ) - { - { [ dup not ] [ 2drop ] } - { [ over not ] [ allocations get delete-at drop ] } - [ allocations get set-at ] - } cond ; +: allocation ( value -- allocation ) (allocation) at ; + +: record-allocation ( allocation value -- ) (allocation) set-at ; : record-allocations ( allocations values -- ) [ record-allocation ] 2each ; @@ -29,11 +30,8 @@ SYMBOL: +escaping+ <disjoint-set> +escaping+ over add-atom ; : init-escaping-values ( -- ) - copies get <escaping-values> - [ '[ drop , add-atom ] assoc-each ] - [ '[ , equate ] assoc-each ] - [ nip escaping-values set ] - 2tri ; + copies get assoc>disjoint-set +escaping+ over add-atom + escaping-values set ; : <slot-value> ( -- value ) <value> diff --git a/unfinished/compiler/tree/escape-analysis/branches/branches.factor b/unfinished/compiler/tree/escape-analysis/branches/branches.factor index 950e0341f9..36d4b1f6a2 100644 --- a/unfinished/compiler/tree/escape-analysis/branches/branches.factor +++ b/unfinished/compiler/tree/escape-analysis/branches/branches.factor @@ -8,8 +8,6 @@ compiler.tree.escape-analysis.nodes compiler.tree.escape-analysis.allocations ; IN: compiler.tree.escape-analysis.branches -SYMBOL: children-escape-data - M: #branch escape-analysis* live-children sift [ (escape-analysis) ] each ; From 175b6deee58381e802ccfd7fc2caca1a91d31486 Mon Sep 17 00:00:00 2001 From: Slava Pestov <slava@slava-pestovs-macbook-pro.local> Date: Mon, 4 Aug 2008 04:35:31 -0500 Subject: [PATCH 8/8] Working on recursive escape analysis --- .../tree/copy-equiv/copy-equiv.factor | 8 ++-- .../allocations/allocations.factor | 38 ++++++++++++------- .../escape-analysis/branches/branches.factor | 17 +++++---- .../escape-analysis-tests.factor | 30 +++++++++++++++ .../recursive/recursive.factor | 25 ++++++++---- .../tree/escape-analysis/simple/simple.factor | 31 +++++++++++---- .../tree/propagation/branches/branches.factor | 2 +- 7 files changed, 111 insertions(+), 40 deletions(-) diff --git a/unfinished/compiler/tree/copy-equiv/copy-equiv.factor b/unfinished/compiler/tree/copy-equiv/copy-equiv.factor index bf5b47c9b1..a96fe8eb22 100644 --- a/unfinished/compiler/tree/copy-equiv/copy-equiv.factor +++ b/unfinished/compiler/tree/copy-equiv/copy-equiv.factor @@ -8,7 +8,8 @@ compiler.tree.combinators ; IN: compiler.tree.copy-equiv ! Two values are copy-equivalent if they are always identical -! at run-time ("DS" relation). +! at run-time ("DS" relation). This is just a weak form of +! value numbering. ! Mapping from values to their canonical leader SYMBOL: copies @@ -25,7 +26,8 @@ SYMBOL: copies ] if ] ; -: resolve-copy ( copy -- val ) copies get compress-path ; +: resolve-copy ( copy -- val ) + copies get compress-path [ "Unknown value" throw ] unless* ; : is-copy-of ( val copy -- ) copies get set-at ; @@ -55,7 +57,7 @@ M: #return-recursive compute-copy-equiv* #! An output is a copy of every input if all inputs are #! copies of the same original value. [ - swap [ resolve-copy ] map sift + swap sift [ resolve-copy ] map dup [ all-equal? ] [ empty? not ] bi and [ first swap is-copy-of ] [ 2drop ] if ] 2each ; diff --git a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor index 4bd23aa8a7..b4f4a2a5dd 100644 --- a/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor +++ b/unfinished/compiler/tree/escape-analysis/allocations/allocations.factor @@ -1,26 +1,41 @@ ! Copyright (C) 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: assocs namespaces sequences kernel math combinators sets -disjoint-sets fry stack-checker.state compiler.tree.copy-equiv ; +USING: accessors assocs namespaces sequences kernel math +combinators sets disjoint-sets fry stack-checker.state +compiler.tree.copy-equiv ; IN: compiler.tree.escape-analysis.allocations ! A map from values to one of the following: ! - f -- initial status, assigned to values we have not seen yet; ! may potentially become an allocation later ! - a sequence of values -- potentially unboxed tuple allocations -! - t -- not allocated locally, can never be unboxed +! - t -- not allocated in this procedure, can never be unboxed SYMBOL: allocations -: (allocation) resolve-copy allocations get ; inline +TUPLE: slot-access slot# value ; -: allocation ( value -- allocation ) (allocation) at ; +C: <slot-access> slot-access + +: (allocation) ( value -- value' allocations ) + resolve-copy allocations get ; inline + +: allocation ( value -- allocation ) + (allocation) at dup slot-access? [ + [ slot#>> ] [ value>> allocation ] bi nth + allocation + ] when ; : record-allocation ( allocation value -- ) (allocation) set-at ; +: unknown-allocation ( value -- ) t swap record-allocation ; + : record-allocations ( allocations values -- ) [ record-allocation ] 2each ; +: unknown-allocations ( values -- ) + [ unknown-allocation ] each ; + ! We track escaping values with a disjoint set. SYMBOL: escaping-values @@ -40,21 +55,16 @@ SYMBOL: +escaping+ [ ] tri ; -: same-value ( in-value out-value -- ) - over [ - [ is-copy-of ] [ escaping-values get equate ] 2bi - ] [ 2drop ] if ; - : record-slot-access ( out slot# in -- ) - over zero? [ 3drop ] [ allocation ?nth swap same-value ] if ; + over zero? [ 3drop ] [ + <slot-access> swap record-allocation + ] if ; : merge-values ( in-values out-value -- ) escaping-values get '[ , , equate ] each ; : merge-slots ( values -- value ) - dup [ ] contains? [ - <slot-value> [ merge-values ] keep - ] [ drop f ] if ; + <slot-value> [ merge-values ] keep ; : add-escaping-values ( values -- ) escaping-values get diff --git a/unfinished/compiler/tree/escape-analysis/branches/branches.factor b/unfinished/compiler/tree/escape-analysis/branches/branches.factor index 36d4b1f6a2..391649fcb2 100644 --- a/unfinished/compiler/tree/escape-analysis/branches/branches.factor +++ b/unfinished/compiler/tree/escape-analysis/branches/branches.factor @@ -13,16 +13,19 @@ M: #branch escape-analysis* : (merge-allocations) ( values -- allocation ) [ - dup [ allocation ] map dup [ ] all? [ - dup [ length ] map all-equal? [ - nip flip - [ (merge-allocations) ] [ [ merge-slots ] map ] bi - [ record-allocations ] keep - ] [ drop add-escaping-values f ] if - ] [ drop add-escaping-values f ] if + dup [ allocation ] map sift dup empty? [ 2drop f ] [ + dup [ t eq? not ] all? [ + dup [ length ] map all-equal? [ + nip flip + [ (merge-allocations) ] [ [ merge-slots ] map ] bi + [ record-allocations ] keep + ] [ drop add-escaping-values t ] if + ] [ drop add-escaping-values t ] if + ] if ] map ; : merge-allocations ( in-values out-values -- ) + [ [ sift ] map ] dip [ [ merge-values ] 2each ] [ [ (merge-allocations) ] dip record-allocations ] 2bi ; diff --git a/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor index 6f99868c23..256152a556 100644 --- a/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor +++ b/unfinished/compiler/tree/escape-analysis/escape-analysis-tests.factor @@ -30,6 +30,7 @@ M: node count-unboxed-allocations* drop ; compute-copy-equiv propagate cleanup + compute-copy-equiv escape-analysis 0 swap [ count-unboxed-allocations* ] each-node ; @@ -157,3 +158,32 @@ TUPLE: cons { car read-only } { cdr read-only } ; [ car>> ] [ cdr>> ] bi ] count-unboxed-allocations ] unit-test + +[ 1 ] [ + [ [ 3 cons boa ] [ "A" throw ] if car>> ] + count-unboxed-allocations +] unit-test + +[ 0 ] [ + [ 10 [ drop ] each-integer ] count-unboxed-allocations +] unit-test + +[ 2 ] [ + [ + 1 2 cons boa 10 [ 2drop 1 2 cons boa ] each-integer car>> + ] count-unboxed-allocations +] unit-test + +[ 0 ] [ + [ + 1 2 cons boa 10 [ drop 2 cons boa ] each-integer car>> + ] count-unboxed-allocations +] unit-test + +: infinite-cons-loop ( a -- b ) 2 cons boa infinite-cons-loop ; inline recursive + +[ 0 ] [ + [ + 1 2 cons boa infinite-cons-loop + ] count-unboxed-allocations +] unit-test diff --git a/unfinished/compiler/tree/escape-analysis/recursive/recursive.factor b/unfinished/compiler/tree/escape-analysis/recursive/recursive.factor index f0f49ee083..5bc386690d 100644 --- a/unfinished/compiler/tree/escape-analysis/recursive/recursive.factor +++ b/unfinished/compiler/tree/escape-analysis/recursive/recursive.factor @@ -10,12 +10,16 @@ compiler.tree.escape-analysis.allocations ; IN: compiler.tree.escape-analysis.recursive : congruent? ( alloc1 alloc2 -- ? ) - 2dup [ length ] bi@ = [ - [ [ allocation ] bi@ congruent? ] 2all? - ] [ 2drop f ] if ; + { + { [ 2dup [ f eq? ] either? ] [ eq? ] } + { [ 2dup [ t eq? ] either? ] [ eq? ] } + { [ 2dup [ length ] bi@ = not ] [ 2drop f ] } + [ [ [ allocation ] bi@ congruent? ] 2all? ] + } cond ; : check-fixed-point ( node alloc1 alloc2 -- node ) - congruent? [ dup label>> f >>fixed-point drop ] unless ; inline + [ congruent? ] 2all? + [ dup label>> f >>fixed-point drop ] unless ; inline : node-input-allocations ( node -- allocations ) in-d>> [ allocation ] map ; @@ -27,13 +31,18 @@ IN: compiler.tree.escape-analysis.recursive [ label>> calls>> [ in-d>> ] map ] [ in-d>> ] bi suffix ; : analyze-recursive-phi ( #enter-recursive -- ) - [ ] [ recursive-stacks flip (merge-allocations) ] [ out-d>> ] tri - [ [ allocation ] map check-fixed-point drop ] 2keep - record-allocations ; + [ ] [ recursive-stacks flip ] [ out-d>> ] tri + [ [ merge-values ] 2each ] + [ + [ (merge-allocations) ] dip + [ [ allocation ] map check-fixed-point drop ] + [ record-allocations ] + 2bi + ] 2bi ; M: #recursive escape-analysis* ( #recursive -- ) [ - copies [ clone ] change + ! copies [ clone ] change child>> [ first analyze-recursive-phi ] diff --git a/unfinished/compiler/tree/escape-analysis/simple/simple.factor b/unfinished/compiler/tree/escape-analysis/simple/simple.factor index 8828b4c410..51d3b6913a 100644 --- a/unfinished/compiler/tree/escape-analysis/simple/simple.factor +++ b/unfinished/compiler/tree/escape-analysis/simple/simple.factor @@ -10,12 +10,21 @@ compiler.tree.escape-analysis.nodes compiler.tree.escape-analysis.allocations ; IN: compiler.tree.escape-analysis.simple +M: #introduce escape-analysis* + value>> unknown-allocation ; + +: record-literal-allocation ( value object -- ) + dup class immutable-tuple-class? [ + tuple-slots rest-slice + [ <slot-value> [ swap record-literal-allocation ] keep ] map + swap record-allocation + ] [ + drop unknown-allocation + ] if ; + M: #push escape-analysis* #! Delegation. - dup literal>> dup class immutable-tuple-class? [ - tuple-slots length 1- [ <slot-value> ] replicate - swap out-d>> first record-allocation - ] [ 2drop ] if ; + [ out-d>> first ] [ literal>> ] bi record-literal-allocation ; : record-tuple-allocation ( #call -- ) #! Delegation. @@ -23,19 +32,27 @@ M: #push escape-analysis* class>> immutable-tuple-class? [ [ in-d>> but-last ] [ out-d>> first ] bi record-allocation - ] [ drop ] if ; + ] [ out-d>> unknown-allocations ] if ; : record-slot-call ( #call -- ) [ out-d>> first ] [ dup in-d>> second node-value-info literal>> ] [ in-d>> first ] tri - over fixnum? [ [ 3 - ] dip record-slot-access ] [ 3drop ] if ; + over fixnum? [ + [ 3 - ] dip record-slot-access + ] [ + 2drop unknown-allocation + ] if ; M: #call escape-analysis* dup word>> { { \ <tuple-boa> [ record-tuple-allocation ] } { \ slot [ record-slot-call ] } - [ drop in-d>> add-escaping-values ] + [ + drop + [ in-d>> add-escaping-values ] + [ out-d>> unknown-allocations ] bi + ] } case ; M: #return escape-analysis* diff --git a/unfinished/compiler/tree/propagation/branches/branches.factor b/unfinished/compiler/tree/propagation/branches/branches.factor index 535fddb93b..eb6ba3697f 100644 --- a/unfinished/compiler/tree/propagation/branches/branches.factor +++ b/unfinished/compiler/tree/propagation/branches/branches.factor @@ -59,7 +59,7 @@ SYMBOL: infer-children-data : compute-phi-input-infos ( phi-in -- phi-info ) infer-children-data get - '[ , [ [ value-info ] bind ] 2map ] map ; + '[ , [ [ [ value-info ] [ null-info ] if* ] bind ] 2map ] map ; : annotate-phi-inputs ( #phi -- ) dup phi-in-d>> compute-phi-input-infos >>phi-info-d