diff --git a/basis/compiler/compiler.factor b/basis/compiler/compiler.factor index e58cf0c834..161b6a4896 100755 --- a/basis/compiler/compiler.factor +++ b/basis/compiler/compiler.factor @@ -12,6 +12,8 @@ compiler.errors compiler.units compiler.utilities compiler.tree.builder compiler.tree.optimizer +compiler.crossref + compiler.cfg compiler.cfg.builder compiler.cfg.optimizer @@ -193,6 +195,14 @@ M: optimizing-compiler recompile ( words -- alist ) ] with-scope "--- compile done" compiler-message ; +M: optimizing-compiler to-recompile ( -- words ) + changed-definitions get compiled-usages + changed-generics get compiled-generic-usages + append assoc-combine keys ; + +M: optimizing-compiler process-forgotten-words + [ delete-compiled-xref ] each ; + : with-optimizer ( quot -- ) [ optimizing-compiler compiler-impl ] dip with-variable ; inline diff --git a/basis/compiler/crossref/authors.txt b/basis/compiler/crossref/authors.txt new file mode 100644 index 0000000000..1901f27a24 --- /dev/null +++ b/basis/compiler/crossref/authors.txt @@ -0,0 +1 @@ +Slava Pestov diff --git a/basis/compiler/crossref/crossref.factor b/basis/compiler/crossref/crossref.factor new file mode 100644 index 0000000000..7941d5ee50 --- /dev/null +++ b/basis/compiler/crossref/crossref.factor @@ -0,0 +1,68 @@ +! Copyright (C) 2009 Slava Pestov. +! See http://factorcode.org/license.txt for BSD license. +USING: assocs classes.algebra compiler.units definitions graphs +grouping kernel namespaces sequences words stack-checker.state ; +IN: compiler.crossref + +SYMBOL: compiled-crossref + +compiled-crossref [ H{ } clone ] initialize + +SYMBOL: compiled-generic-crossref + +compiled-generic-crossref [ H{ } clone ] initialize + +: compiled-usage ( word -- assoc ) + compiled-crossref get at ; + +: (compiled-usages) ( word -- assoc ) + #! If the word is not flushable anymore, we have to recompile + #! all words which flushable away a call (presumably when the + #! word was still flushable). If the word is flushable, we + #! don't have to recompile words that folded this away. + [ compiled-usage ] + [ "flushable" word-prop inlined-dependency flushed-dependency ? ] bi + [ dependency>= nip ] curry assoc-filter ; + +: compiled-usages ( seq -- assocs ) + [ drop word? ] assoc-filter + [ [ drop (compiled-usages) ] { } assoc>map ] keep suffix ; + +: compiled-generic-usage ( word -- assoc ) + compiled-generic-crossref get at ; + +: (compiled-generic-usages) ( generic class -- assoc ) + [ compiled-generic-usage ] dip + [ + 2dup [ valid-class? ] both? + [ classes-intersect? ] [ 2drop f ] if nip + ] curry assoc-filter ; + +: compiled-generic-usages ( assoc -- assocs ) + [ (compiled-generic-usages) ] { } assoc>map ; + +: (compiled-xref) ( word dependencies word-prop variable -- ) + [ concat set-word-prop ] [ get add-vertex* ] bi-curry* 2bi ; + +: compiled-xref ( word dependencies generic-dependencies -- ) + [ [ drop crossref? ] { } assoc-filter-as f like ] bi@ + [ "compiled-uses" compiled-crossref (compiled-xref) ] + [ "compiled-generic-uses" compiled-generic-crossref (compiled-xref) ] + bi-curry* bi ; + +: (compiled-unxref) ( word word-prop variable -- ) + [ [ [ dupd word-prop 2 ] dip get remove-vertex* ] 2curry ] + [ drop [ remove-word-prop ] curry ] + 2bi bi ; + +: compiled-unxref ( word -- ) + [ "compiled-uses" compiled-crossref (compiled-unxref) ] + [ "compiled-generic-uses" compiled-generic-crossref (compiled-unxref) ] + bi ; + +: delete-compiled-xref ( word -- ) + [ compiled-unxref ] + [ compiled-crossref get delete-at ] + [ compiled-generic-crossref get delete-at ] + tri ; + diff --git a/basis/compiler/tests/redefine3.factor b/basis/compiler/tests/redefine3.factor index 67added49d..913111b8ea 100644 --- a/basis/compiler/tests/redefine3.factor +++ b/basis/compiler/tests/redefine3.factor @@ -1,6 +1,6 @@ USING: accessors compiler compiler.units tools.test math parser kernel sequences sequences.private classes.mixin generic -definitions arrays words assocs eval ; +definitions arrays words assocs eval grouping ; IN: compiler.tests.redefine3 GENERIC: sheeple ( obj -- x ) @@ -13,20 +13,23 @@ M: empty-mixin sheeple drop "wake up" ; inline : sheeple-test ( -- string ) { } sheeple ; +: compiled-use? ( key word -- ? ) + "compiled-uses" word-prop 2 key? ; + [ "sheeple" ] [ sheeple-test ] unit-test [ t ] [ \ sheeple-test optimized? ] unit-test -[ t ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test -[ f ] [ empty-mixin \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test +[ t ] [ object \ sheeple method \ sheeple-test compiled-use? ] unit-test +[ f ] [ empty-mixin \ sheeple method \ sheeple-test compiled-use? ] unit-test [ ] [ "IN: compiler.tests.redefine3 USE: arrays INSTANCE: array empty-mixin" eval( -- ) ] unit-test [ "wake up" ] [ sheeple-test ] unit-test -[ f ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test -[ t ] [ empty-mixin \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test +[ f ] [ object \ sheeple method \ sheeple-test compiled-use? ] unit-test +[ t ] [ empty-mixin \ sheeple method \ sheeple-test compiled-use? ] unit-test [ ] [ [ array empty-mixin remove-mixin-instance ] with-compilation-unit ] unit-test [ "sheeple" ] [ sheeple-test ] unit-test [ t ] [ \ sheeple-test optimized? ] unit-test -[ t ] [ object \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test -[ f ] [ empty-mixin \ sheeple method \ sheeple-test "compiled-uses" word-prop key? ] unit-test +[ t ] [ object \ sheeple method \ sheeple-test compiled-use? ] unit-test +[ f ] [ empty-mixin \ sheeple method \ sheeple-test compiled-use? ] unit-test diff --git a/basis/stack-checker/state/state-tests.factor b/basis/stack-checker/state/state-tests.factor index a4dea993c0..4ecb39e592 100644 --- a/basis/stack-checker/state/state-tests.factor +++ b/basis/stack-checker/state/state-tests.factor @@ -28,3 +28,11 @@ SYMBOL: b b inlined-dependency depends-on ] computing-dependencies ] unit-test + +[ flushed-dependency ] [ f flushed-dependency strongest-dependency ] unit-test +[ flushed-dependency ] [ flushed-dependency f strongest-dependency ] unit-test +[ inlined-dependency ] [ flushed-dependency inlined-dependency strongest-dependency ] unit-test +[ inlined-dependency ] [ called-dependency inlined-dependency strongest-dependency ] unit-test +[ flushed-dependency ] [ called-dependency flushed-dependency strongest-dependency ] unit-test +[ called-dependency ] [ called-dependency f strongest-dependency ] unit-test + diff --git a/basis/stack-checker/state/state.factor b/basis/stack-checker/state/state.factor index a76d302a7e..bd9c57efbc 100644 --- a/basis/stack-checker/state/state.factor +++ b/basis/stack-checker/state/state.factor @@ -48,6 +48,18 @@ SYMBOL: literals ! Words that the current quotation depends on SYMBOL: dependencies +SYMBOLS: inlined-dependency flushed-dependency called-dependency ; + +: index>= ( obj1 obj2 seq -- ? ) + [ index ] curry bi@ >= ; + +: dependency>= ( how1 how2 -- ? ) + { called-dependency flushed-dependency inlined-dependency } + index>= ; + +: strongest-dependency ( how1 how2 -- how ) + [ called-dependency or ] bi@ [ dependency>= ] most ; + : depends-on ( word how -- ) over primitive? [ 2drop ] [ dependencies get dup [ diff --git a/basis/tools/deploy/shaker/shaker.factor b/basis/tools/deploy/shaker/shaker.factor index e42f478de6..856b99fd98 100755 --- a/basis/tools/deploy/shaker/shaker.factor +++ b/basis/tools/deploy/shaker/shaker.factor @@ -9,6 +9,7 @@ compiler.units definitions generic generic.standard generic.single tools.deploy.config combinators classes classes.builtin slots.private grouping command-line ; QUALIFIED: bootstrap.stage2 +QUALIFIED: compiler.crossref QUALIFIED: compiler.errors QUALIFIED: continuations QUALIFIED: definitions @@ -340,8 +341,8 @@ IN: tools.deploy.shaker implementors-map update-map main-vocab-hook - compiled-crossref - compiled-generic-crossref + compiler.crossref:compiled-crossref + compiler.crossref:compiled-generic-crossref compiler-impl compiler.errors:compiler-errors lexer-factory diff --git a/basis/tools/profiler/profiler.factor b/basis/tools/profiler/profiler.factor index 626fdab826..8279a90514 100644 --- a/basis/tools/profiler/profiler.factor +++ b/basis/tools/profiler/profiler.factor @@ -1,9 +1,10 @@ ! Copyright (C) 2007, 2008 Slava Pestov. ! See http://factorcode.org/license.txt for BSD license. -USING: accessors words sequences math prettyprint kernel arrays io -io.styles namespaces assocs kernel.private strings combinators -sorting math.parser vocabs definitions tools.profiler.private -tools.crossref continuations generic compiler.units sets classes fry ; +USING: accessors words sequences math prettyprint kernel arrays +io io.styles namespaces assocs kernel.private strings +combinators sorting math.parser vocabs definitions +tools.profiler.private tools.crossref continuations generic +compiler.units compiler.crossref sets classes fry ; IN: tools.profiler : profile ( quot -- ) diff --git a/core/compiler/units/units-tests.factor b/core/compiler/units/units-tests.factor index 8dce12f411..c827d370d5 100644 --- a/core/compiler/units/units-tests.factor +++ b/core/compiler/units/units-tests.factor @@ -5,13 +5,6 @@ IN: compiler.units.tests [ [ [ ] define-temp ] with-compilation-unit ] must-infer [ [ [ ] define-temp ] with-nested-compilation-unit ] must-infer -[ flushed-dependency ] [ f flushed-dependency strongest-dependency ] unit-test -[ flushed-dependency ] [ flushed-dependency f strongest-dependency ] unit-test -[ inlined-dependency ] [ flushed-dependency inlined-dependency strongest-dependency ] unit-test -[ inlined-dependency ] [ called-dependency inlined-dependency strongest-dependency ] unit-test -[ flushed-dependency ] [ called-dependency flushed-dependency strongest-dependency ] unit-test -[ called-dependency ] [ called-dependency f strongest-dependency ] unit-test - ! Non-optimizing compiler bugs [ 1 1 ] [ "A" "B" [ [ [ 1 ] dip ] 2array 1array modify-code-heap ] keep diff --git a/core/compiler/units/units.factor b/core/compiler/units/units.factor index 8b6625d014..eb7cc7b5d2 100644 --- a/core/compiler/units/units.factor +++ b/core/compiler/units/units.factor @@ -40,8 +40,19 @@ SYMBOL: compiler-impl HOOK: recompile compiler-impl ( words -- alist ) +HOOK: to-recompile compiler-impl ( -- words ) + +HOOK: process-forgotten-words compiler-impl ( words -- ) + ! Non-optimizing compiler -M: f recompile [ dup def>> ] { } map>assoc ; +M: f recompile + [ dup def>> ] { } map>assoc ; + +M: f to-recompile + changed-definitions get [ drop word? ] assoc-filter + changed-generics get assoc-union keys ; + +M: f process-forgotten-words drop ; : without-optimizer ( quot -- ) [ f compiler-impl ] dip with-variable ; inline @@ -50,8 +61,12 @@ M: f recompile [ dup def>> ] { } map>assoc ; ! during stage1 bootstrap, it would just waste time. SINGLETON: dummy-compiler +M: dummy-compiler to-recompile f ; + M: dummy-compiler recompile drop { } ; +M: dummy-compiler process-forgotten-words drop ; + : ( -- pair ) { H{ } H{ } } [ clone ] map ; SYMBOL: definition-observers @@ -89,59 +104,9 @@ GENERIC: definitions-changed ( assoc obj -- ) : compile ( words -- ) recompile modify-code-heap ; -: index>= ( obj1 obj2 seq -- ? ) - [ index ] curry bi@ >= ; - -: dependency>= ( how1 how2 -- ? ) - { called-dependency flushed-dependency inlined-dependency } - index>= ; - -: strongest-dependency ( how1 how2 -- how ) - [ called-dependency or ] bi@ [ dependency>= ] most ; - -: weakest-dependency ( how1 how2 -- how ) - [ inlined-dependency or ] bi@ [ dependency>= not ] most ; - -: compiled-usage ( word -- assoc ) - compiled-crossref get at ; - -: (compiled-usages) ( word -- assoc ) - #! If the word is not flushable anymore, we have to recompile - #! all words which flushable away a call (presumably when the - #! word was still flushable). If the word is flushable, we - #! don't have to recompile words that folded this away. - [ compiled-usage ] - [ "flushable" word-prop inlined-dependency flushed-dependency ? ] bi - [ dependency>= nip ] curry assoc-filter ; - -: compiled-usages ( assoc -- assocs ) - [ drop word? ] assoc-filter - [ [ drop (compiled-usages) ] { } assoc>map ] keep suffix ; - -: compiled-generic-usage ( word -- assoc ) - compiled-generic-crossref get at ; - -: (compiled-generic-usages) ( generic class -- assoc ) - [ compiled-generic-usage ] dip - [ - 2dup [ valid-class? ] both? - [ classes-intersect? ] [ 2drop f ] if nip - ] curry assoc-filter ; - -: compiled-generic-usages ( assoc -- assocs ) - [ (compiled-generic-usages) ] { } assoc>map ; - -: words-only ( assoc -- assoc' ) - [ drop word? ] assoc-filter ; - -: to-recompile ( -- seq ) - changed-definitions get compiled-usages - changed-generics get compiled-generic-usages - append assoc-combine keys ; - : process-forgotten-definitions ( -- ) forgotten-definitions get keys - [ [ word? ] filter [ delete-compiled-xref ] each ] + [ [ word? ] filter process-forgotten-words ] [ [ delete-definition-errors ] each ] bi ; diff --git a/core/definitions/definitions.factor b/core/definitions/definitions.factor index e2fb4b8161..d815b9609d 100644 --- a/core/definitions/definitions.factor +++ b/core/definitions/definitions.factor @@ -7,15 +7,13 @@ MIXIN: definition ERROR: no-compilation-unit definition ; -SYMBOLS: inlined-dependency flushed-dependency called-dependency ; - : set-in-unit ( value key assoc -- ) [ set-at ] [ no-compilation-unit ] if* ; SYMBOL: changed-definitions : changed-definition ( defspec -- ) - inlined-dependency swap changed-definitions get set-in-unit ; + dup changed-definitions get set-in-unit ; SYMBOL: changed-effects diff --git a/core/words/words.factor b/core/words/words.factor index 45e014f6be..d2fe7d2625 100755 --- a/core/words/words.factor +++ b/core/words/words.factor @@ -64,41 +64,6 @@ GENERIC: crossref? ( word -- ? ) M: word crossref? dup "forgotten" word-prop [ drop f ] [ vocabulary>> >boolean ] if ; -SYMBOL: compiled-crossref - -compiled-crossref [ H{ } clone ] initialize - -SYMBOL: compiled-generic-crossref - -compiled-generic-crossref [ H{ } clone ] initialize - -: (compiled-xref) ( word dependencies word-prop variable -- ) - [ [ set-word-prop ] curry ] - [ [ get add-vertex* ] curry ] - bi* 2bi ; - -: compiled-xref ( word dependencies generic-dependencies -- ) - [ [ drop crossref? ] { } assoc-filter-as f like ] bi@ - [ "compiled-uses" compiled-crossref (compiled-xref) ] - [ "compiled-generic-uses" compiled-generic-crossref (compiled-xref) ] - bi-curry* bi ; - -: (compiled-unxref) ( word word-prop variable -- ) - [ [ [ dupd word-prop ] dip get remove-vertex* ] 2curry ] - [ drop [ remove-word-prop ] curry ] - 2bi bi ; - -: compiled-unxref ( word -- ) - [ "compiled-uses" compiled-crossref (compiled-unxref) ] - [ "compiled-generic-uses" compiled-generic-crossref (compiled-unxref) ] - bi ; - -: delete-compiled-xref ( word -- ) - [ compiled-unxref ] - [ compiled-crossref get delete-at ] - [ compiled-generic-crossref get delete-at ] - tri ; - : inline? ( word -- ? ) "inline" word-prop ; inline GENERIC: subwords ( word -- seq )