]> gitweb.factorcode.org Git - factor.git/commitdiff
Debugging new optimizer
authorSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 15 Aug 2008 04:35:19 +0000 (23:35 -0500)
committerSlava Pestov <slava@slava-pestovs-macbook-pro.local>
Fri, 15 Aug 2008 04:35:19 +0000 (23:35 -0500)
27 files changed:
basis/columns/columns.factor
basis/compiler/compiler.factor
basis/compiler/generator/generator.factor
basis/compiler/tree/builder/builder-tests.factor
basis/compiler/tree/builder/builder.factor
basis/compiler/tree/cleanup/cleanup.factor
basis/compiler/tree/dead-code/branches/branches.factor
basis/compiler/tree/dead-code/dead-code-tests.factor
basis/compiler/tree/dead-code/recursive/recursive.factor
basis/compiler/tree/dead-code/simple/simple.factor
basis/compiler/tree/debugger/debugger.factor
basis/compiler/tree/def-use/def-use.factor
basis/compiler/tree/escape-analysis/simple/simple.factor
basis/compiler/tree/optimizer/optimizer.factor
basis/compiler/tree/propagation/inlining/inlining.factor
basis/compiler/tree/propagation/known-words/known-words.factor
basis/compiler/tree/propagation/propagation-tests.factor
basis/compiler/tree/propagation/recursive/recursive.factor
basis/compiler/tree/tree.factor
basis/compiler/tree/tuple-unboxing/tuple-unboxing.factor
basis/disjoint-sets/disjoint-sets.factor
basis/locals/locals.factor
basis/stack-checker/backend/backend.factor
basis/stack-checker/inlining/inlining.factor
basis/stack-checker/stack-checker-tests.factor
basis/stack-checker/visitor/dummy/dummy.factor
basis/stack-checker/visitor/visitor.factor

index e174cd890007481ee97fdb47707dcbd9ac8f12de..5ac8531f586c7ff05377c79b5092c85a93175d83 100644 (file)
@@ -15,4 +15,4 @@ M: column length seq>> length ;
 INSTANCE: column virtual-sequence
 
 : <flipped> ( seq -- seq' )
-    dup empty? [ first length [ <column> ] with map ] unless ;
+    dup empty? [ dup first length [ <column> ] with map ] unless ;
index 5880d05e93bae9aec68c1f122864673f1025d366..2a274ef45700885f66537d0f9752fc7956abdeb0 100755 (executable)
@@ -1,6 +1,6 @@
 ! Copyright (C) 2004, 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
-USING: kernel namespaces arrays sequences io debugger words
+USING: kernel namespaces arrays sequences io debugger words fry
 compiler.units continuations vocabs assocs dlists definitions
 math threads graphs generic combinators dequeues search-dequeues
 stack-checker stack-checker.state compiler.generator
@@ -47,10 +47,10 @@ SYMBOL: +failed+
 
 : (compile) ( word -- )
     USE: prettyprint dup .
-    [
+    '[
         H{ } clone dependencies set
 
-        {
+        {
             [ compile-begins ]
             [
                 [ build-tree-from-word ] [ compile-failed return ] recover
@@ -59,7 +59,7 @@ SYMBOL: +failed+
             [ dup generate ]
             [ compile-succeeded ]
         } cleave
-    ] curry with-return ;
+    ] with-return ;
 
 : compile-loop ( dequeue -- )
     [ (compile) yield ] slurp-dequeue ;
index ddfbae35a98ae171d6550b117798aa27bf1c229b..637ff8146cc1660801f325d7871607cba008f87f 100755 (executable)
@@ -92,7 +92,7 @@ M: node generate-node drop iterate-next ;
     %jump-label ;
 
 : generate-call ( label -- next )
-    dup maybe-compile
+    dup maybe-compile
     end-basic-block
     dup compiling-loops get at [
         %jump-label f
@@ -107,7 +107,7 @@ M: node generate-node drop iterate-next ;
     ] ?if ;
 
 ! #recursive
-: compile-recursive ( node -- )
+: compile-recursive ( node -- next )
     dup label>> id>> generate-call >r
     [ child>> ] [ label>> word>> ] [ label>> id>> ] tri generate
     r> ;
@@ -115,7 +115,7 @@ M: node generate-node drop iterate-next ;
 : compiling-loop ( word -- )
     <label> dup resolve-label swap compiling-loops get set-at ;
 
-: compile-loop ( node -- )
+: compile-loop ( node -- next )
     end-basic-block
     [ label>> id>> compiling-loop ] [ child>> generate-nodes ] bi
     iterate-next ;
@@ -232,7 +232,7 @@ M: #dispatch generate-node
     ] if ;
 
 M: #call generate-node
-    dup node-input-infos [ class>> ] map set-operand-classes
+    dup node-input-infos [ class>> ] map set-operand-classes
     dup find-if-intrinsic [
         do-if-intrinsic
     ] [
index 1d859ac531aa07eedd64ba5cbd61cdf2fbee496e..30244725b2f0a451d1e4c8e2e3d66754e5cfb562 100644 (file)
@@ -1,6 +1,11 @@
 IN: compiler.tree.builder.tests
-USING: compiler.tree.builder tools.test ;
+USING: compiler.tree.builder tools.test sequences kernel
+compiler.tree ;
 
 \ build-tree must-infer
 \ build-tree-with must-infer
 \ build-tree-from-word must-infer
+
+: inline-recursive ( -- ) inline-recursive ; inline recursive
+
+[ t ] [ \ inline-recursive build-tree-from-word [ #recursive? ] contains? nip ] unit-test
index e2315dbdf7253674168c6544170c42551e8115e7..8a59f82bcfa23af579f2a73bff3c52bd89861852 100644 (file)
@@ -22,10 +22,15 @@ IN: compiler.tree.builder
     ] with-tree-builder nip
     unclip-last in-d>> ;
 
+: ends-with-terminate? ( nodes -- ? )
+    dup empty? [ drop f ] [ peek #terminate? ] if ;
+
 : build-sub-tree ( #call quot -- nodes )
-    [ [ out-d>> ] [ in-d>> ] bi ] dip
-    build-tree-with
-    rot #copy suffix ;
+    [ [ out-d>> ] [ in-d>> ] bi ] dip build-tree-with
+    over ends-with-terminate?
+    [ drop swap [ f swap #push ] map append ]
+    [ rot #copy suffix ]
+    if ;
 
 : (make-specializer) ( class picker -- quot )
     swap "predicate" word-prop append ;
@@ -70,13 +75,31 @@ IN: compiler.tree.builder
         [ drop ]
     } cond ;
 
+: (build-tree-from-word) ( word -- )
+    dup
+    [ "inline" word-prop ]
+    [ "recursive" word-prop ] bi and [
+        1quotation f infer-quot
+    ] [
+        [ specialized-def ]
+        [ dup 2array 1array ] bi infer-quot
+    ] if ;
+
+: check-cannot-infer ( word -- )
+    dup +cannot-infer+ word-prop [ cannot-infer-effect ] [ drop ] if ;
+
+: check-no-compile ( word -- )
+    dup "no-compile" word-prop [ cannot-infer-effect ] [ drop ] if ;
+
 : build-tree-from-word ( word -- effect nodes )
     [
         [
-            dup +cannot-infer+ word-prop [ cannot-infer-effect ] when
-            dup "no-compile" word-prop [ cannot-infer-effect ] when
-            dup specialized-def over dup 2array 1array infer-quot
-            finish-word
+            {
+                [ check-cannot-infer ]
+                [ check-no-compile ]
+                [ (build-tree-from-word) ]
+                [ finish-word ]
+            } cleave
         ] maybe-cannot-infer
     ] with-tree-builder ;
 
index 31c01c806d6a4eb62c89e49e56afb7555c7d1fca..7aebdcf3fe6419b75c86216512d2b609368e49dc 100644 (file)
@@ -13,14 +13,30 @@ IN: compiler.tree.cleanup
 ! A phase run after propagation to finish the job, so to speak.
 ! Codifies speculative inlining decisions, deletes branches
 ! marked as never taken, and flattens local recursive blocks
-! that do not call themselves.
+! that do not call themselves. Finally, if inlining inserts a
+! #terminate, we delete all nodes after that.
+
+GENERIC: delete-node ( node -- )
+
+M: #call-recursive delete-node
+    dup label>> [ [ eq? not ] with filter ] change-calls drop ;
+
+M: #return-recursive delete-node
+    label>> f >>return drop ;
+
+M: node delete-node drop ;
+
+: delete-nodes ( nodes -- ) [ delete-node ] each-node ;
 
 GENERIC: cleanup* ( node -- node/nodes )
 
+: termination-cleanup ( nodes -- nodes' )
+    dup [ #terminate? ] find drop [ 1+ cut delete-nodes ] when* ;
+
 : cleanup ( nodes -- nodes' )
     #! We don't recurse into children here, instead the methods
     #! do it since the logic is a bit more involved
-    [ cleanup* ] map flatten ;
+    [ cleanup* ] map flatten ; ! termination-cleanup ;
 
 : cleanup-folding? ( #call -- ? )
     node-output-infos dup empty?
@@ -74,18 +90,6 @@ M: #call cleanup*
 
 M: #declare cleanup* drop f ;
 
-GENERIC: delete-node ( node -- )
-
-M: #call-recursive delete-node
-    dup label>> [ [ eq? not ] with filter ] change-calls drop ;
-
-M: #return-recursive delete-node
-    label>> f >>return drop ;
-
-M: node delete-node drop ;
-
-: delete-nodes ( nodes -- ) [ delete-node ] each-node ;
-
 : delete-unreachable-branches ( #branch -- )
     dup live-branches>> '[
         ,
index f9ed205fb5760a0c53d290912b7c2649af85461c..b36eddfece7d98bb34a936381aefa40eb0fbd6d4 100644 (file)
@@ -20,48 +20,47 @@ M: #phi compute-live-values*
     [ [ out-r>> ] [ phi-in-r>> ] bi look-at-phi ]
     2bi ;
 
-SYMBOL: if-node
-
-M: #if remove-dead-code*
-    [ [ (remove-dead-code) ] map ] change-children
-    dup if-node set ;
+M: #branch remove-dead-code*
+    [ [ (remove-dead-code) ] map ] change-children ;
 
 : remove-phi-inputs ( #phi -- )
-    dup [ out-d>> ] [ phi-in-d>> ] bi filter-corresponding >>phi-in-d
-    dup [ out-r>> ] [ phi-in-r>> ] bi filter-corresponding >>phi-in-r
+    dup [ out-d>> ] [ phi-in-d>> flip ] bi filter-corresponding flip >>phi-in-d
+    dup [ out-r>> ] [ phi-in-r>> flip ] bi filter-corresponding flip >>phi-in-r
     drop ;
 
-: dead-value-indices ( values -- indices )
-    [ length ] keep live-values get
-    '[ , nth , key? not ] filter ; inline
-
-: drop-d-values ( values indices -- node )
-    [ drop filter-live ] [ nths filter-live ] 2bi
-    [ make-values ] keep
-    [ drop ] [ zip ] 2bi
-    #shuffle ;
-
-: drop-r-values ( values indices -- nodes )
-    [ dup make-values [ #r> ] keep ] dip
-    drop-d-values dup out-d>> dup make-values #>r
-    3array ;
-
-: insert-drops ( nodes d-values r-values d-indices r-indices -- nodes' )
-    '[
-        [ , drop-d-values 1array ]
-        [ , drop-r-values ]
-        bi* 3append
-    ] 3map ;
-
-: hoist-drops ( #phi -- )
-    if-node get swap
-    {
-        [ phi-in-d>> ]
-        [ phi-in-r>> ]
-        [ out-d>> dead-value-indices ]
-        [ out-r>> dead-value-indices ]
-    } cleave
-    '[ , , , , insert-drops ] change-children drop ;
+! SYMBOL: if-node
+! 
+! : dead-value-indices ( values -- indices )
+!     [ length ] keep live-values get
+!     '[ , nth , key? not ] filter ; inline
+! 
+! : drop-d-values ( values indices -- node )
+!     [ drop filter-live ] [ nths filter-live ] 2bi
+!     [ make-values ] keep
+!     [ drop ] [ zip ] 2bi
+!     #shuffle ;
+! 
+! : drop-r-values ( values indices -- nodes )
+!     [ dup make-values [ #r> ] keep ] dip
+!     drop-d-values dup out-d>> dup make-values #>r
+!     3array ;
+! 
+! : insert-drops ( nodes d-values r-values d-indices r-indices -- nodes' )
+!     '[
+!         [ , drop-d-values 1array ]
+!         [ , drop-r-values ]
+!         bi* 3append
+!     ] 3map ;
+! 
+! : hoist-drops ( #phi -- )
+!     if-node get swap
+!     {
+!         [ phi-in-d>> ]
+!         [ phi-in-r>> ]
+!         [ out-d>> dead-value-indices ]
+!         [ out-r>> dead-value-indices ]
+!     } cleave
+!     '[ , , , , insert-drops ] change-children drop ;
 
 : remove-phi-outputs ( #phi -- )
     [ filter-live ] change-out-d
@@ -70,7 +69,7 @@ M: #if remove-dead-code*
 
 M: #phi remove-dead-code*
     {
-        [ hoist-drops ]
+        [ hoist-drops ]
         [ remove-phi-inputs ]
         [ remove-phi-outputs ]
         [ ]
index 09fc003543fa304213e0ec6e4df429fe8fccf0e8..d587ae70f22d548b2269c98f268138fccce3b0d6 100644 (file)
@@ -1,6 +1,8 @@
 USING: namespaces assocs sequences compiler.tree.builder
 compiler.tree.dead-code compiler.tree.def-use compiler.tree
-compiler.tree.combinators compiler.tree.debugger
+compiler.tree.combinators compiler.tree.propagation
+compiler.tree.cleanup compiler.tree.escape-analysis
+compiler.tree.tuple-unboxing compiler.tree.debugger
 compiler.tree.normalization compiler.tree.checker tools.test
 kernel math stack-checker.state accessors combinators io ;
 IN: compiler.tree.dead-code.tests
@@ -10,6 +12,10 @@ IN: compiler.tree.dead-code.tests
 : count-live-values ( quot -- n )
     build-tree
     normalize
+    propagate
+    cleanup
+    escape-analysis
+    unbox-tuples
     compute-def-use
     remove-dead-code
     0 swap [
@@ -32,11 +38,11 @@ IN: compiler.tree.dead-code.tests
 
 [ 2 ] [ [ [ 1 ] [ dup ] if drop ] count-live-values ] unit-test
 
-[ 2 ] [ [ 1 + ] count-live-values ] unit-test
+[ 2 ] [ [ 1 + ] count-live-values ] unit-test
 
 [ 0 ] [ [ 1 2 + drop ] count-live-values ] unit-test
 
-[ 3 ] [ [ 1 + 3 + ] count-live-values ] unit-test
+[ 3 ] [ [ 1 + 3 + ] count-live-values ] unit-test
 
 [ 0 ] [ [ 1 2 + 3 + drop ] count-live-values ] unit-test
 
@@ -52,9 +58,18 @@ IN: compiler.tree.dead-code.tests
 
 [ 0 ] [ [ [ 1 ] [ 2 ] compose call + drop ] count-live-values ] unit-test
 
+[ 3 ] [ [ 10 [ ] times ] count-live-values ] unit-test
+
 : optimize-quot ( quot -- quot' )
-    build-tree normalize compute-def-use remove-dead-code
-    dup check-nodes nodes>quot ;
+    build-tree
+    normalize
+    propagate
+    cleanup
+    escape-analysis
+    unbox-tuples
+    compute-def-use
+    remove-dead-code
+    "no-check" get [ dup check-nodes ] unless nodes>quot ;
 
 [ [ drop 1 ] ] [ [ >r 1 r> drop ] optimize-quot ] unit-test
 
@@ -76,3 +91,14 @@ IN: compiler.tree.dead-code.tests
 [ [ [ drop drop ] [ non-flushable-3 drop ] if ] ] [
     [ [ flushable-1 ] [ non-flushable-3 ] if drop ] optimize-quot
 ] unit-test
+
+[ [ [ f ] [ f ] if ] ] [ [ [ f ] [ f ] if ] optimize-quot ] unit-test
+
+[ ] [ [ dup [ 3 throw ] [ ] if ] optimize-quot drop ] unit-test
+
+: non-flushable-4 ( a -- b ) drop f ;
+
+: recursive-test-1 ( a b -- )
+    dup 10 < [
+        >r drop 5 non-flushable-4 r> 1 + recursive-test-1
+    ] [ 2drop ] if ; inline recursive
index 0fbfa886e1079da05d989cb7c8efc6be5ee2604f..28c65969e3d0bb9cc92b0635daaf721db232fff1 100644 (file)
@@ -15,8 +15,14 @@ M: #enter-recursive compute-live-values*
 M: #return-recursive compute-live-values*
     [ out-d>> ] [ return-recursive-phi-in ] bi look-at-phi ;
 
+M: #call-recursive compute-live-values*
+    #! If the output of a copy is live, then the corresponding
+    #! inputs to #return nodes are live also.
+    [ out-d>> ] [ label>> return>> in-d>> ] bi look-at-mapping ;
+
 M: #recursive remove-dead-code*
-    [ filter-live ] change-in-d ;
+    [ filter-live ] change-in-d
+    [ (remove-dead-code) ] change-child ;
 
 M: #call-recursive remove-dead-code*
     [ filter-live ] change-in-d
index 4e3ce65686c2ae65377f955e9f6908875f6fab9c..a3695dc81585b114865b80687312ecd245cf0369 100644 (file)
@@ -25,11 +25,6 @@ M: #copy compute-live-values*
 
 M: #call compute-live-values* nip look-at-inputs ;
 
-M: #call-recursive compute-live-values*
-    #! If the output of a copy is live, then the corresponding
-    #! inputs to #return nodes are live also.
-    [ out-d>> ] [ label>> return>> ] bi look-at-mapping ;
-
 M: #>r compute-live-values*
     [ out-r>> ] [ in-d>> ] bi look-at-mapping ;
 
@@ -108,3 +103,7 @@ M: #copy remove-dead-code*
     [ in-d>> ] [ out-d>> ] bi
     2dup swap zip #shuffle
     remove-dead-code* ;
+
+M: #terminate remove-dead-code*
+    [ filter-live ] change-in-d
+    [ filter-live ] change-in-r ;
index 87f23ac5437172960bad2c6b5d4a25d49f41307e..7660ec3222fd8fb69194c930b6303d18e432baae 100644 (file)
@@ -21,7 +21,7 @@ MACRO: match-choose ( alist -- )
 MATCH-VARS: ?a ?b ?c ;
 
 : pretty-shuffle ( effect -- word/f )
-    [ in>> ] [ out>> ] bi drop-prefix [ >array ] bi@ 2array {
+    [ in>> ] [ out>> ] bi 2array {
         { { { } { } } [ ] }
         { { { ?a } { ?a } } [ ] }
         { { { ?a ?b } { ?a ?b } } [ ] }
@@ -84,6 +84,12 @@ M: #r> node>quot
     [ in-r>> length ] [ out-d>> empty? \ rdrop \ r> ? ] bi
     <repetition> % ;
 
+M: #alien-invoke node>quot params>> , \ #alien-invoke , ;
+
+M: #alien-indirect node>quot params>> , \ #alien-indirect , ;
+
+M: #alien-callback node>quot params>> , \ #alien-callback , ;
+
 M: node node>quot drop ;
 
 : nodes>quot ( node -- quot )
index edb35c1f2bfd6f6527292168a55d2de4d0c1b6d4..2b31ac9929ac22d630b47ab809a5d3cadbdc36db 100755 (executable)
@@ -43,6 +43,8 @@ M: #phi node-uses-values
     [ phi-in-d>> ] [ phi-in-r>> ] bi
     append concat remove-bottom prune ;
 M: #declare node-uses-values declaration>> keys ;
+M: #terminate node-uses-values [ in-d>> ] [ in-r>> ] bi append ;
+M: #alien-callback node-uses-values drop f ;
 M: node node-uses-values in-d>> ;
 
 GENERIC: node-defs-values ( node -- values )
@@ -54,6 +56,7 @@ M: #declare node-defs-values drop f ;
 M: #return node-defs-values drop f ;
 M: #recursive node-defs-values drop f ;
 M: #terminate node-defs-values drop f ;
+M: #alien-callback node-defs-values drop f ;
 M: node node-defs-values out-d>> ;
 
 : node-def-use ( node -- )
index 40ca4372fa12533371ecb54168e46f95b4ec30fc..0edcd6c46c720877a8e5da663d8979d61b1da49d 100644 (file)
@@ -81,10 +81,10 @@ M: #return escape-analysis*
 
 M: #alien-invoke escape-analysis*
     [ in-d>> add-escaping-values ]
-    [ out-d>> unknown-allocation ]
+    [ out-d>> unknown-allocations ]
     bi ;
 
 M: #alien-indirect escape-analysis*
     [ in-d>> add-escaping-values ]
-    [ out-d>> unknown-allocation ]
+    [ out-d>> unknown-allocations ]
     bi ;
index 2d2a376bc0ed6091da22117b04a74ff8be9a3a18..691795efdbb1baeb7634e87065cc7684f088725c 100644 (file)
@@ -10,7 +10,8 @@ compiler.tree.dead-code
 compiler.tree.strength-reduction
 compiler.tree.loop.detection
 compiler.tree.loop.inversion
-compiler.tree.branch-fusion ;
+compiler.tree.branch-fusion
+compiler.tree.checker ;
 IN: compiler.tree.optimizer
 
 : optimize-tree ( nodes -- nodes' )
@@ -18,10 +19,12 @@ IN: compiler.tree.optimizer
     propagate
     cleanup
     detect-loops
-    invert-loops
-    fuse-branches
-    escape-analysis
-    unbox-tuples
-    compute-def-use
-    remove-dead-code
-    strength-reduce ;
+    ! invert-loops
+    ! fuse-branches
+    ! escape-analysis
+    ! unbox-tuples
+    ! compute-def-use
+    ! remove-dead-code
+    ! strength-reduce
+    compute-def-use USE: kernel
+    dup check-nodes ;
index d333842657154c8d763e54843dbe154fa151c0a3..b30800b4457348cc912ab1ec8247eaaa86673905 100644 (file)
@@ -123,7 +123,7 @@ DEFER: (flat-length)
 SYMBOL: history
 
 : remember-inlining ( word -- )
-    history get [ swap suffix ] change ;
+    history [ swap suffix ] change ;
 
 : inline-word ( #call word -- )
     dup history get memq? [
index 89d4cd690d5314203c613a1fbd9ce934bcba97c3..4ab7fcea4e6eea356683cce50099bccc6b182d20 100644 (file)
@@ -253,7 +253,7 @@ generic-comparison-ops [
 
 { <tuple> <tuple-boa> } [
     [
-        literal>> dup tuple-layout? [ class>> ] [ drop tuple ] if
+        literal>> dup tuple-layout? [ class>> ] [ drop tuple ] if <class-info>
         [ clear ] dip
     ] +outputs+ set-word-prop
 ] each
@@ -273,10 +273,10 @@ generic-comparison-ops [
 \ instance? [
     [ value-info ] dip over literal>> class? [
         [ literal>> ] dip predicate-constraints
-    ] [ 2drop f ] if
+    ] [ 3drop f ] if
 ] +constraints+ set-word-prop
 
 \ instance? [
     dup literal>> class?
-    [ literal>> predicate-output-infos ] [ 2drop f ] if
+    [ literal>> predicate-output-infos ] [ 2drop object-info ] if
 ] +outputs+ set-word-prop
index 1256be8f795fe03314964dd671ae66c894301512..7d7959164d0990532f6534e4016057d4b5bb256a 100644 (file)
@@ -557,3 +557,12 @@ M: fixnum bad-generic 1 fixnum+fast ;
         0 10 [ bad-generic dup 123 bitand drop bad-generic 1 + ] times
     ] final-classes
 ] unit-test
+
+GENERIC: infinite-loop ( a -- b )
+M: integer infinite-loop infinite-loop ;
+
+[ ] [ [ { integer } declare infinite-loop ] final-classes drop ] unit-test
+
+[ V{ tuple } ] [ [ tuple-layout <tuple> ] final-classes ] unit-test
+
+[ ] [ [ instance? ] final-classes drop ] unit-test
index 6b266c4ea8c7afdedc98aaefcb0971872abe3e51..14a9427dd1bfe35b9be6b84a46d5b1b71335f750 100644 (file)
@@ -52,6 +52,7 @@ IN: compiler.tree.propagation.recursive
     3bi ;
 
 M: #recursive propagate-around ( #recursive -- )
+    "blah" USE: io print
     { 0 } clone [ USE: math
         dup first 10 = [ "OOPS" throw ] [ dup first 1+ swap set-first ] if
         constraints [ clone ] change
index 01eb73c71f47f0f76c37329bbc33d9d50f7e21ac..a4b1fabd453bfaed626ea8a4fba0f44921b739c7 100755 (executable)
@@ -66,10 +66,11 @@ TUPLE: #r> < #renaming in-r out-d ;
         swap >>out-d
         swap >>in-r ;
 
-TUPLE: #terminate < node in-d ;
+TUPLE: #terminate < node in-d in-r ;
 
-: #terminate ( stack -- node )
+: #terminate ( in-d in-r -- node )
     \ #terminate new
+        swap >>in-r
         swap >>in-d ;
 
 TUPLE: #branch < node in-d children live-branches ;
index 2f8f65f0243c743b99c7e56faf627a4489756b67..bc5e74b6d736b16413d22e9547734ea75225f018 100644 (file)
@@ -93,7 +93,8 @@ M: #shuffle unbox-tuples*
     [ unzip [ flatten-values ] bi@ zip ] change-mapping ;
 
 M: #terminate unbox-tuples*
-    [ flatten-values ] change-in-d ;
+    [ flatten-values ] change-in-d
+    [ flatten-values ] change-in-r ;
 
 M: #phi unbox-tuples*
     [ [ flatten-values ] map pad-with-bottom ] change-phi-in-d
index 77e4a53f7b1b33357f13e28b0b3acf93926214a0..4ef787d33b7a98f3fa1808561404976f4959a249 100644 (file)
@@ -92,7 +92,7 @@ M:: disjoint-set equate ( a b disjoint-set -- )
     '[ , , equate ] each ;
 
 : equate-all ( seq disjoint-set -- )
-    over dup empty? [ 2drop ] [
+    over empty? [ 2drop ] [
         [ unclip-slice ] dip equate-all-with
     ] if ;
 
index 1858be11a862aafea8f9919e13b9f9d2c62a3a88..5b4da8927a2c748471763d6e3a901ebb299e5acf 100755 (executable)
@@ -288,7 +288,7 @@ M: wlet local-rewrite*
     CREATE-METHOD
     [ parse-locals-definition ] with-method-definition ;
 
-: parsed-lambda ( form -- )
+: parsed-lambda ( accum form -- accum )
     in-lambda? get [ parsed ] [ lambda-rewrite over push-all ] if ;
 
 PRIVATE>
index adb68194477fdf99438e3a2ab6b813881d288bda..a65eb3c3966cd7e2b5c39183ee296b231516022a 100755 (executable)
@@ -85,7 +85,7 @@ M: wrapper apply-object
 M: object apply-object push-literal ;
 
 : terminate ( -- )
-    terminated? on meta-d get clone #terminate, ;
+    terminated? on meta-d get clone meta-r get clone #terminate, ;
 
 : infer-quot ( quot rstate -- )
     recursive-state get [
index 3be2e21b7ecbc023da52297d484b1d3ef26c2488..1c94b2152bf11a5e9cd172e9362607ba2290d60e 100644 (file)
@@ -1,8 +1,8 @@
 ! Copyright (C) 2008 Slava Pestov.
 ! See http://factorcode.org/license.txt for BSD license.
 USING: fry namespaces assocs kernel sequences words accessors
-definitions math effects classes arrays combinators vectors
-arrays
+definitions math math.order effects classes arrays combinators
+vectors arrays
 stack-checker.state
 stack-checker.visitor
 stack-checker.backend
@@ -115,8 +115,8 @@ SYMBOL: enter-out
 
 : adjust-stack-effect ( effect -- effect' )
     [ in>> ] [ out>> ] bi
-    meta-d get length pick length - object <repetition>
-    '[ , prepend ] bi@
+    meta-d get length pick length - 0 max
+    object <repetition> '[ , prepend ] bi@
     <effect> ;
 
 : call-recursive-inline-word ( word -- )
index 5d0ac42919243d1b9877d6c8f839dcf3f7e02729..0d34a19a64bfb2d57363ce7da4b6e895c09bbc9a 100755 (executable)
@@ -563,3 +563,9 @@ M: object inference-invalidation-d inference-invalidation-c 2drop ;
 
 { 3 0 } [ [ 2drop "A" throw ] [ ] if 2drop ] must-infer-as
 { 2 0 } [ drop f f [ 2drop "A" throw ] [ ] if 2drop ] must-infer-as
+
+: unbalanced-retain-usage ( a b -- )
+    dup 10 < [ 2drop 5 1 + unbalanced-retain-usage ] [ 2drop ] if ;
+    inline recursive
+
+[ unbalanced-retain-usage ] [ inference-error? ] must-fail-with
index 381405bd3174ac181d80efd0bb20bffa8d8dc13e..d2592c889a29a52fd8baaf96aa377c4f1b9a0418 100644 (file)
@@ -14,7 +14,7 @@ M: f #r>, 2drop ;
 M: f #return, drop ;
 M: f #enter-recursive, 3drop ;
 M: f #return-recursive, 3drop ;
-M: f #terminate, drop ;
+M: f #terminate, 2drop ;
 M: f #if, 3drop ;
 M: f #dispatch, 2drop ;
 M: f #phi, drop drop drop drop drop ;
index 813117f8ff5c18a638a927811775e15196d5549b..3d434dbd0e507c9e39313bd260c0408f3047b390 100644 (file)
@@ -17,7 +17,7 @@ HOOK: #shuffle, stack-visitor ( inputs outputs mapping -- )
 HOOK: #drop, stack-visitor ( values -- )
 HOOK: #>r, stack-visitor ( inputs outputs -- )
 HOOK: #r>, stack-visitor ( inputs outputs -- )
-HOOK: #terminate, stack-visitor ( stack -- )
+HOOK: #terminate, stack-visitor ( in-d in-r -- )
 HOOK: #if, stack-visitor ( ? true false -- )
 HOOK: #dispatch, stack-visitor ( n branches -- )
 HOOK: #phi, stack-visitor ( d-phi-in d-phi-out r-phi-in r-phi-out terminated -- )