1 ! Copyright (C) 2004, 2010 Slava Pestov.
2 ! See http://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs classes.algebra combinators
4 combinators.short-circuit compiler.cfg compiler.cfg.builder
5 compiler.cfg.builder.alien compiler.cfg.finalization
6 compiler.cfg.optimizer compiler.codegen compiler.crossref
7 compiler.errors compiler.tree.builder compiler.tree.optimizer
8 compiler.units compiler.utilities continuations definitions fry
9 generic generic.single io kernel macros make namespaces
10 sequences sets stack-checker.dependencies stack-checker.errors
11 stack-checker.inlining vocabs.loader words ;
16 : compile? ( word -- ? )
17 ! Don't attempt to compile certain words.
19 [ "forgotten" word-prop ]
23 : compiler-message ( string -- )
24 "trace-compilation" get [ [ print flush ] with-global ] [ drop ] if ;
27 dup name>> compiler-message
29 clear-compiler-error ;
31 GENERIC: no-compile? ( word -- ? )
33 M: method no-compile? "method-generic" word-prop no-compile? ;
35 M: predicate-engine-word no-compile? "owner-generic" word-prop no-compile? ;
38 { [ macro? ] [ "special" word-prop ] [ "no-compile" word-prop ] } 1|| ;
40 GENERIC: combinator? ( word -- ? )
42 M: method combinator? "method-generic" word-prop combinator? ;
44 M: predicate-engine-word combinator? "owner-generic" word-prop combinator? ;
46 M: word combinator? inline? ;
48 : ignore-error? ( word error -- ? )
49 ! Ignore some errors on inline combinators, macros, and special
50 ! words such as 'call'.
53 [ [ combinator? ] [ unknown-macro-input? ] bi* and ]
57 ! Recompile callers if the word's stack effect changed, then
58 ! save the word's dependencies so that if they change, the
59 ! word can get recompiled too.
63 [ dependencies get generic-dependencies get compiled-xref ]
64 [ conditional-dependencies get set-dependency-checks ]
69 : deoptimize-with ( word def -- * )
70 ! If the word failed to infer, compile it with the
71 ! non-optimizing compiler.
72 swap [ finish ] [ compiled get set-at ] bi return ;
74 : not-compiled-def ( word error -- def )
75 '[ _ _ not-compiled ] [ ] like ;
77 : deoptimize* ( word -- * )
78 dup def>> deoptimize-with ;
80 : ignore-error ( word error -- * )
81 drop [ clear-compiler-error ] [ deoptimize* ] bi ;
83 : remember-error ( word error -- * )
84 [ swap <compiler-error> save-compiler-error ]
85 [ [ drop ] [ not-compiled-def ] 2bi deoptimize-with ]
88 : deoptimize ( word error -- * )
89 ! If the error is ignorable, compile the word with the
90 ! non-optimizing compiler, using its definition. Otherwise,
91 ! if the compiler error is not ignorable, use a dummy
92 ! definition from 'not-compiled-def' which throws an error.
94 { [ dup inference-error? not ] [ rethrow ] }
95 { [ 2dup ignore-error? ] [ ignore-error ] }
99 : optimize? ( word -- ? )
105 : contains-breakpoints? ( -- ? )
106 dependencies get keys [ "break?" word-prop ] any? ;
108 : frontend ( word -- tree )
109 ! If the word contains breakpoints, don't optimize it, since
110 ! the walker does not support this.
112 [ [ build-tree ] [ deoptimize ] recover optimize-tree ] keep
113 contains-breakpoints? [ nip deoptimize* ] [ drop ] if
114 ] [ deoptimize* ] if ;
116 : backend ( tree word -- )
121 [ [ generate ] [ label>> ] bi compiled get set-at ]
126 : compile-word ( word -- )
127 ! We return early if the word has breakpoints or if it
138 SINGLETON: optimizing-compiler
140 M: optimizing-compiler update-call-sites ( class generic -- words )
141 ! Words containing call sites with inferred type 'class'
142 ! which inlined a method on 'generic'
143 generic-call-sites-of keys swap '[
144 _ 2dup [ valid-classoid? ] both?
145 [ classes-intersect? ] [ 2drop f ] if
148 M: optimizing-compiler recompile ( words -- alist )
149 H{ } clone compiled [
151 [ compile-word yield-hook get call( -- ) ] each
154 "--- compile done" compiler-message ;
156 M: optimizing-compiler to-recompile ( -- words )
158 changed-effects get new-words get diff
159 outdated-effect-usages %
161 changed-definitions get new-words get diff
162 outdated-definition-usages %
164 maybe-changed get new-words get diff
165 outdated-conditional-usages %
167 changed-definitions get members [ word? ] filter dup zip ,
168 ] { } make assoc-combine keys ;
170 M: optimizing-compiler process-forgotten-words
171 [ delete-compiled-xref ] each ;
173 : with-optimizer ( quot -- )
174 [ optimizing-compiler compiler-impl ] dip with-variable ; inline
176 : enable-optimizer ( -- )
177 optimizing-compiler compiler-impl set-global ;
179 : disable-optimizer ( -- )
180 f compiler-impl set-global ;
182 { "threads" "compiler" } "compiler.threads" require-when