New 'conditional dependency' mechanism for more accurate recording of recompilation information

release
Slava Pestov 2010-01-29 21:40:09 +13:00
parent 817bc02392
commit c027046857
19 changed files with 122 additions and 50 deletions

View File

@ -49,8 +49,7 @@ SYMBOL: compiled
: start ( word -- ) : start ( word -- )
dup name>> compiler-message dup name>> compiler-message
H{ } clone dependencies set init-dependencies
H{ } clone generic-dependencies set
clear-compiler-error ; clear-compiler-error ;
GENERIC: no-compile? ( word -- ? ) GENERIC: no-compile? ( word -- ? )
@ -86,15 +85,15 @@ M: word combinator? inline? ;
[ compiled-unxref ] [ compiled-unxref ]
[ [
dup crossref? [ dup crossref? [
dependencies get [ dependencies get generic-dependencies get compiled-xref ]
generic-dependencies get [ conditional-dependencies get save-conditional-dependencies ]
compiled-xref bi
] [ drop ] if ] [ drop ] if
] tri ; ] tri ;
: deoptimize-with ( word def -- * ) : deoptimize-with ( word def -- * )
#! If the word failed to infer, compile it with the #! If the word failed to infer, compile it with the
#! non-optimizing compiler. #! non-optimizing compiler.
swap [ finish ] [ compiled get set-at ] bi return ; swap [ finish ] [ compiled get set-at ] bi return ;
: not-compiled-def ( word error -- def ) : not-compiled-def ( word error -- def )
@ -203,7 +202,9 @@ M: optimizing-compiler recompile ( words -- alist )
"--- compile done" compiler-message ; "--- compile done" compiler-message ;
M: optimizing-compiler to-recompile ( -- words ) M: optimizing-compiler to-recompile ( -- words )
changed-definitions get compiled-usages assoc-combine keys ; changed-definitions get compiled-usages
changed-classes get outdated-class-usages
append assoc-combine keys ;
M: optimizing-compiler process-forgotten-words M: optimizing-compiler process-forgotten-words
[ delete-compiled-xref ] each ; [ delete-compiled-xref ] each ;

View File

@ -1,7 +1,7 @@
! Copyright (C) 2009, 2010 Slava Pestov. ! Copyright (C) 2009, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: assocs classes.algebra compiler.units definitions graphs USING: arrays assocs classes.algebra compiler.units definitions
grouping kernel namespaces sequences words fry graphs grouping kernel namespaces sequences words fry
stack-checker.dependencies ; stack-checker.dependencies ;
IN: compiler.crossref IN: compiler.crossref
@ -25,10 +25,21 @@ compiled-generic-crossref [ H{ } clone ] initialize
[ "flushable" word-prop inlined-dependency flushed-dependency ? ] bi [ "flushable" word-prop inlined-dependency flushed-dependency ? ] bi
'[ nip _ dependency>= ] assoc-filter ; '[ nip _ dependency>= ] assoc-filter ;
: compiled-usages ( seq -- assocs ) : compiled-usages ( assoc -- assocs )
[ drop word? ] assoc-filter [ drop word? ] assoc-filter
[ [ drop (compiled-usages) ] { } assoc>map ] keep suffix ; [ [ drop (compiled-usages) ] { } assoc>map ] keep suffix ;
: dependencies-satisfied? ( word -- ? )
"conditional-dependencies" word-prop [ satisfied? ] all? ;
: outdated-class-usages ( assoc -- assocs )
[
drop
compiled-usage
[ nip class-dependency dependency>= ] assoc-filter
[ drop dependencies-satisfied? not ] assoc-filter
] { } assoc>map ;
: compiled-generic-usage ( word -- assoc ) : compiled-generic-usage ( word -- assoc )
compiled-generic-crossref get at ; compiled-generic-crossref get at ;
@ -49,10 +60,14 @@ compiled-generic-crossref [ H{ } clone ] initialize
: compiled-unxref ( word -- ) : compiled-unxref ( word -- )
[ "compiled-uses" compiled-crossref (compiled-unxref) ] [ "compiled-uses" compiled-crossref (compiled-unxref) ]
[ "compiled-generic-uses" compiled-generic-crossref (compiled-unxref) ] [ "compiled-generic-uses" compiled-generic-crossref (compiled-unxref) ]
bi ; [ f "conditional-dependencies" set-word-prop ]
tri ;
: delete-compiled-xref ( word -- ) : delete-compiled-xref ( word -- )
[ compiled-unxref ] [ compiled-unxref ]
[ compiled-crossref get delete-at ] [ compiled-crossref get delete-at ]
[ compiled-generic-crossref get delete-at ] [ compiled-generic-crossref get delete-at ]
tri ; tri ;
: save-conditional-dependencies ( word deps -- )
>array f like "conditional-dependencies" set-word-prop ;

View File

@ -76,8 +76,6 @@ M: object fake-float? drop f ;
[ f ] [ 1.0 my-fake-inline-3 ] unit-test [ f ] [ 1.0 my-fake-inline-3 ] unit-test
[ f ] [ 1.0 my-baked-inline-3 ] unit-test
[ f ] [ 1.0 my-inline-4 ] unit-test [ f ] [ 1.0 my-inline-4 ] unit-test
[ f ] [ 1.0 my-inline-5 ] unit-test [ f ] [ 1.0 my-inline-5 ] unit-test

View File

@ -1,4 +1,4 @@
! Copyright (C) 2008 Slava Pestov. ! Copyright (C) 2008, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: kernel accessors sequences combinators fry USING: kernel accessors sequences combinators fry
classes.algebra namespaces assocs words math math.private classes.algebra namespaces assocs words math math.private
@ -51,9 +51,15 @@ GENERIC: cleanup* ( node -- node/nodes )
[ in-d>> #drop ] [ in-d>> #drop ]
bi prefix ; bi prefix ;
: record-predicate-folding ( #call -- )
[ node-input-infos first class>> ]
[ word>> "predicating" word-prop ]
[ node-output-infos first literal>> ] tri
[ depends-on-class<= ] [ depends-on-classes-disjoint ] if ;
: record-folding ( #call -- ) : record-folding ( #call -- )
dup word>> predicate? dup word>> predicate?
[ [ node-input-infos first class>> ] [ word>> ] bi depends-on-generic ] [ record-predicate-folding ]
[ word>> inlined-dependency depends-on ] [ word>> inlined-dependency depends-on ]
if ; if ;
@ -63,15 +69,18 @@ GENERIC: cleanup* ( node -- node/nodes )
! Method inlining ! Method inlining
: add-method-dependency ( #call -- ) : add-method-dependency ( #call -- )
dup method>> word? [ dup method>> word? [
[ class>> ] [ word>> ] bi depends-on-generic [ [ class>> ] [ word>> ] bi depends-on-generic ]
[ [ class>> ] [ word>> ] [ method>> ] tri depends-on-method ]
bi
] [ drop ] if ; ] [ drop ] if ;
: record-inlining ( #call -- )
dup method>>
[ add-method-dependency ]
[ word>> inlined-dependency depends-on ] if ;
: cleanup-inlining ( #call -- nodes ) : cleanup-inlining ( #call -- nodes )
[ [ record-inlining ] [ body>> cleanup ] bi ;
dup method>>
[ add-method-dependency ]
[ word>> inlined-dependency depends-on ] if
] [ body>> cleanup ] bi ;
! Removing overflow checks ! Removing overflow checks
: (remove-overflow-check?) ( #call -- ? ) : (remove-overflow-check?) ( #call -- ? )

View File

@ -9,14 +9,6 @@ compiler.tree.propagation.info
compiler.tree.dead-code.liveness ; compiler.tree.dead-code.liveness ;
IN: compiler.tree.dead-code.simple IN: compiler.tree.dead-code.simple
GENERIC: flushable? ( word -- ? )
M: predicate flushable? drop t ;
M: word flushable? "flushable" word-prop ;
M: method-body flushable? "method-generic" word-prop flushable? ;
: flushable-call? ( #call -- ? ) : flushable-call? ( #call -- ? )
dup word>> dup flushable? [ dup word>> dup flushable? [
"input-classes" word-prop dup [ "input-classes" word-prop dup [

View File

@ -318,7 +318,7 @@ generic-comparison-ops [
dup literal>> class? dup literal>> class?
[ [
literal>> literal>>
[ inlined-dependency depends-on ] [ class-dependency depends-on ]
[ predicate-output-infos ] [ predicate-output-infos ]
bi bi
] [ 2drop object-info ] if ] [ 2drop object-info ] if

View File

@ -36,7 +36,7 @@ M: #declare propagate-before
#! classes mentioned in the declaration are redefined, since #! classes mentioned in the declaration are redefined, since
#! now we're making assumptions but their definitions. #! now we're making assumptions but their definitions.
declaration>> [ declaration>> [
[ inlined-dependency depends-on ] [ class-dependency depends-on ]
[ <class-info> swap refine-value-info ] [ <class-info> swap refine-value-info ]
bi bi
] assoc-each ; ] assoc-each ;
@ -110,8 +110,9 @@ M: #declare propagate-before
#! is redefined, since now we're making assumptions but the #! is redefined, since now we're making assumptions but the
#! class definition itself. #! class definition itself.
[ in-d>> first value-info ] [ in-d>> first value-info ]
[ "predicating" word-prop dup inlined-dependency depends-on ] bi* [ "predicating" word-prop ] bi*
predicate-output-infos 1array ; [ nip class-dependency depends-on ]
[ predicate-output-infos 1array ] 2bi ;
: default-output-value-infos ( #call word -- infos ) : default-output-value-infos ( #call word -- infos )
"default-output-classes" word-prop "default-output-classes" word-prop

View File

@ -163,7 +163,7 @@ ERROR: bad-partial-eval quot word ;
: inline-new ( class -- quot/f ) : inline-new ( class -- quot/f )
dup tuple-class? [ dup tuple-class? [
dup inlined-dependency depends-on dup class-dependency depends-on
[ all-slots [ initial>> literalize ] map ] [ all-slots [ initial>> literalize ] map ]
[ tuple-layout '[ _ <tuple-boa> ] ] [ tuple-layout '[ _ <tuple-boa> ] ]
bi append >quotation bi append >quotation

View File

@ -1,19 +1,19 @@
! Copyright (C) 2009 Slava Pestov. ! Copyright (C) 2009, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: assocs classes.algebra fry kernel math namespaces USING: assocs accessors classes.algebra fry generic kernel math
sequences words ; namespaces sequences words ;
IN: stack-checker.dependencies IN: stack-checker.dependencies
! Words that the current quotation depends on ! Words that the current quotation depends on
SYMBOL: dependencies SYMBOL: dependencies
SYMBOLS: inlined-dependency flushed-dependency called-dependency ; SYMBOLS: inlined-dependency class-dependency flushed-dependency called-dependency ;
: index>= ( obj1 obj2 seq -- ? ) : index>= ( obj1 obj2 seq -- ? )
[ index ] curry bi@ >= ; [ index ] curry bi@ >= ;
: dependency>= ( how1 how2 -- ? ) : dependency>= ( how1 how2 -- ? )
{ called-dependency flushed-dependency inlined-dependency } { called-dependency class-dependency flushed-dependency inlined-dependency }
index>= ; index>= ;
: strongest-dependency ( how1 how2 -- how ) : strongest-dependency ( how1 how2 -- how )
@ -36,6 +36,45 @@ SYMBOL: generic-dependencies
generic-dependencies get dup generic-dependencies get dup
[ [ ?class-or ] change-at ] [ 3drop ] if ; [ [ ?class-or ] change-at ] [ 3drop ] if ;
! Conditional dependencies are re-evaluated when classes change;
! if any fail, the word is recompiled
SYMBOL: conditional-dependencies
GENERIC: satisfied? ( dependency -- ? )
: conditional-dependency ( ... class -- )
boa conditional-dependencies get
dup [ push ] [ 2drop ] if ; inline
TUPLE: depends-on-class<= class1 class2 ;
: depends-on-class<= ( class1 class2 -- )
\ depends-on-class<= conditional-dependency ;
M: depends-on-class<= satisfied?
[ class1>> ] [ class2>> ] bi class<= ;
TUPLE: depends-on-classes-disjoint class1 class2 ;
: depends-on-classes-disjoint ( class1 class2 -- )
\ depends-on-classes-disjoint conditional-dependency ;
M: depends-on-classes-disjoint satisfied?
[ class1>> ] [ class2>> ] bi classes-intersect? not ;
TUPLE: depends-on-method class generic method ;
: depends-on-method ( class generic method -- )
\ depends-on-method conditional-dependency ;
M: depends-on-method satisfied?
[ [ class>> ] [ generic>> ] bi method-for-class ] [ method>> ] bi eq? ;
: init-dependencies ( -- )
H{ } clone dependencies set
H{ } clone generic-dependencies set
V{ } clone conditional-dependencies set ;
: without-dependencies ( quot -- ) : without-dependencies ( quot -- )
[ [
dependencies off dependencies off

View File

@ -140,7 +140,7 @@ IN: stack-checker.transforms
! Constructors ! Constructors
\ boa [ \ boa [
dup tuple-class? [ dup tuple-class? [
dup inlined-dependency depends-on dup class-dependency depends-on
[ "boa-check" word-prop [ ] or ] [ "boa-check" word-prop [ ] or ]
[ tuple-layout '[ _ <tuple-boa> ] ] [ tuple-layout '[ _ <tuple-boa> ] ]
bi append bi append

View File

@ -1,4 +1,4 @@
! Copyright (C) 2007, 2009 Slava Pestov. ! Copyright (C) 2007, 2010 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license. ! See http://factorcode.org/license.txt for BSD license.
USING: arrays accessors io.backend io.streams.c init fry USING: arrays accessors io.backend io.streams.c init fry
namespaces math make assocs kernel parser parser.notes lexer namespaces math make assocs kernel parser parser.notes lexer
@ -128,6 +128,7 @@ IN: tools.deploy.shaker
"combination" "combination"
"compiled-generic-uses" "compiled-generic-uses"
"compiled-uses" "compiled-uses"
"conditional-dependencies"
"constant" "constant"
"constraints" "constraints"
"custom-inlining" "custom-inlining"

View File

@ -45,6 +45,8 @@ PREDICATE: class < word "class" word-prop ;
PREDICATE: predicate < word "predicating" word-prop >boolean ; PREDICATE: predicate < word "predicating" word-prop >boolean ;
M: predicate flushable? drop t ;
M: predicate forget* M: predicate forget*
[ call-next-method ] [ f "predicating" set-word-prop ] bi ; [ call-next-method ] [ f "predicating" set-word-prop ] bi ;

View File

@ -28,8 +28,9 @@ TUPLE: check-mixin-class class ;
: redefine-mixin-class ( class members -- ) : redefine-mixin-class ( class members -- )
[ (define-union-class) ] [ (define-union-class) ]
[ drop changed-class ]
[ drop t "mixin" set-word-prop ] [ drop t "mixin" set-word-prop ]
2bi ; 2tri ;
: if-mixin-member? ( class mixin true false -- ) : if-mixin-member? ( class mixin true false -- )
[ check-mixin-class 2dup members member-eq? ] 2dip if ; inline [ check-mixin-class 2dup members member-eq? ] 2dip if ; inline
@ -80,12 +81,10 @@ M: mixin-class class-forgotten remove-mixin-instance ;
dup mixin-class? [ dup mixin-class? [
drop drop
] [ ] [
{ [ { } redefine-mixin-class ]
[ { } redefine-mixin-class ] [ H{ } clone "instances" set-word-prop ]
[ H{ } clone "instances" set-word-prop ] [ update-classes ]
[ changed-definition ] tri
[ update-classes ]
} cleave
] if ; ] if ;
! Definition protocol implementation ensures that removing an ! Definition protocol implementation ensures that removing an

View File

@ -223,7 +223,7 @@ M: tuple-class update-class
2drop 2drop
[ [
[ update-tuples-after ] [ update-tuples-after ]
[ changed-definition ] [ changed-class ]
bi bi
] each-subclass ] each-subclass
] ]

View File

@ -32,7 +32,7 @@ PRIVATE>
: define-union-class ( class members -- ) : define-union-class ( class members -- )
[ (define-union-class) ] [ (define-union-class) ]
[ drop changed-definition ] [ drop changed-class ]
[ drop update-classes ] [ drop update-classes ]
2tri ; 2tri ;

View File

@ -124,6 +124,7 @@ M: object bump-effect-counter* drop f ;
dup new-definitions get first update dup new-definitions get first update
dup new-definitions get second update dup new-definitions get second update
dup changed-definitions get update dup changed-definitions get update
dup changed-classes get update
dup dup changed-vocabs update ; dup dup changed-vocabs update ;
: process-forgotten-definitions ( -- ) : process-forgotten-definitions ( -- )
@ -164,6 +165,7 @@ PRIVATE>
: with-nested-compilation-unit ( quot -- ) : with-nested-compilation-unit ( quot -- )
[ [
H{ } clone changed-definitions set H{ } clone changed-definitions set
H{ } clone changed-classes set
H{ } clone changed-effects set H{ } clone changed-effects set
H{ } clone outdated-generics set H{ } clone outdated-generics set
H{ } clone outdated-tuples set H{ } clone outdated-tuples set
@ -174,6 +176,7 @@ PRIVATE>
: with-compilation-unit ( quot -- ) : with-compilation-unit ( quot -- )
[ [
H{ } clone changed-definitions set H{ } clone changed-definitions set
H{ } clone changed-classes set
H{ } clone changed-effects set H{ } clone changed-effects set
H{ } clone outdated-generics set H{ } clone outdated-generics set
H{ } clone forgotten-definitions set H{ } clone forgotten-definitions set

View File

@ -15,6 +15,11 @@ SYMBOL: changed-definitions
: changed-definition ( defspec -- ) : changed-definition ( defspec -- )
dup changed-definitions get set-in-unit ; dup changed-definitions get set-in-unit ;
SYMBOL: changed-classes
: changed-class ( class -- )
dup changed-classes get set-in-unit ;
SYMBOL: changed-effects SYMBOL: changed-effects
SYMBOL: outdated-generics SYMBOL: outdated-generics

View File

@ -104,6 +104,9 @@ GENERIC: update-generic ( class generic -- )
PREDICATE: method-body < word PREDICATE: method-body < word
"method-generic" word-prop >boolean ; "method-generic" word-prop >boolean ;
M: method-body flushable?
"method-generic" word-prop flushable? ;
M: method-body stack-effect M: method-body stack-effect
"method-generic" word-prop stack-effect ; "method-generic" word-prop stack-effect ;

View File

@ -182,6 +182,10 @@ M: parsing-word definer drop \ SYNTAX: \ ; ;
: deprecated? ( obj -- ? ) : deprecated? ( obj -- ? )
dup word? [ "deprecated" word-prop ] [ drop f ] if ; dup word? [ "deprecated" word-prop ] [ drop f ] if ;
GENERIC: flushable? ( word -- ? )
M: word flushable? "flushable" word-prop ;
! Definition protocol ! Definition protocol
M: word where "loc" word-prop ; M: word where "loc" word-prop ;