1 ! Copyright (C) 2004, 2010 Slava Pestov.
2 ! See https://factorcode.org/license.txt for BSD license.
3 USING: accessors assocs classes 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
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 ;
26 : start-compilation ( word -- )
27 dup name>> compiler-message
28 H{ } clone dependencies namespaces:set
29 H{ } clone generic-dependencies namespaces:set
30 HS{ } clone conditional-dependencies namespaces:set
31 clear-compiler-error ;
33 GENERIC: no-compile? ( word -- ? )
35 M: method no-compile? "method-generic" word-prop no-compile? ;
37 M: predicate-engine-word no-compile? "owner-generic" word-prop no-compile? ;
40 { [ macro? ] [ "special" word-prop ] [ "no-compile" word-prop ] } 1|| ;
42 GENERIC: combinator? ( word -- ? )
44 M: method combinator? "method-generic" word-prop combinator? ;
46 M: predicate-engine-word combinator? "owner-generic" word-prop combinator? ;
48 M: word combinator? inline? ;
50 : ignore-error? ( word error -- ? )
51 ! Ignore some errors on inline combinators, macros, and special
52 ! words such as 'call'.
55 [ [ combinator? ] [ unknown-macro-input? ] bi* and ]
58 : finish-compilation ( word -- )
59 ! Recompile callers if the word's stack effect changed, then
60 ! save the word's dependencies so that if they change, the
61 ! word can get recompiled too.
65 [ dependencies get generic-dependencies get compiled-xref ]
66 [ conditional-dependencies get set-dependency-checks ]
71 : deoptimize-with ( word def -- * )
72 ! If the word failed to infer, compile it with the
73 ! non-optimizing compiler.
74 swap [ finish-compilation ] [ compiled get set-at ] bi return ;
76 : not-compiled-def ( word error -- def )
77 '[ _ _ not-compiled ] [ ] like ;
79 : deoptimize* ( word -- * )
80 dup def>> deoptimize-with ;
82 : ignore-error ( word error -- * )
83 drop [ clear-compiler-error ] [ deoptimize* ] bi ;
85 : remember-error ( word error -- * )
86 [ swap <compiler-error> save-compiler-error ]
87 [ [ drop ] [ not-compiled-def ] 2bi deoptimize-with ]
90 : deoptimize ( word error -- * )
91 ! If the error is ignorable, compile the word with the
92 ! non-optimizing compiler, using its definition. Otherwise,
93 ! if the compiler error is not ignorable, use a dummy
94 ! definition from 'not-compiled-def' which throws an error.
96 { [ dup inference-error? not ] [ rethrow ] }
97 { [ 2dup ignore-error? ] [ ignore-error ] }
101 : optimize? ( word -- ? )
107 : contains-breakpoints? ( -- ? )
108 dependencies get keys [ "break?" word-prop ] any? ;
110 : frontend ( word -- tree )
111 ! If the word contains breakpoints, don't optimize it, since
112 ! the walker does not support this.
114 [ [ build-tree ] [ deoptimize ] recover optimize-tree ] keep
115 contains-breakpoints? [ nip deoptimize* ] [ drop ] if
116 ] [ deoptimize* ] if ;
118 : backend ( tree word -- )
123 [ [ generate ] [ label>> ] bi compiled get set-at ]
128 : compile-word ( word -- )
129 ! We return early if the word has breakpoints or if it
133 [ start-compilation ]
136 [ finish-compilation ]
140 SINGLETON: optimizing-compiler
142 M: optimizing-compiler update-call-sites ( class generic -- words )
143 ! Words containing call sites with inferred type 'class'
144 ! which inlined a method on 'generic'
145 generic-call-sites-of keys swap '[
146 _ 2dup [ classoid? ] both?
147 [ classes-intersect? ] [ 2drop f ] if
150 M: optimizing-compiler recompile ( words -- alist )
151 H{ } clone compiled [
153 [ compile-word yield-hook get call( -- ) ] each
156 "--- compile done" compiler-message ;
158 M: optimizing-compiler to-recompile ( -- words )
160 changed-effects get new-words get diff
161 outdated-effect-usages %
163 changed-definitions get new-words get diff
164 outdated-definition-usages %
166 maybe-changed get new-words get diff
167 outdated-conditional-usages %
169 changed-definitions get filter-word-defs dup zip ,
170 ] { } make assoc-union-all keys ;
172 M: optimizing-compiler process-forgotten-words
173 [ delete-compiled-xref ] each ;
175 : enable-optimizer ( -- )
176 optimizing-compiler compiler-impl set-global ;
178 : disable-optimizer ( -- )
179 f compiler-impl set-global ;
181 { "prettyprint" "compiler" } "compiler.prettyprint" require-when
182 { "threads" "compiler" } "compiler.threads" require-when