2009-01-13 18:12:43 -05:00
|
|
|
! Copyright (C) 2004, 2009 Slava Pestov.
|
2007-09-20 18:09:08 -04:00
|
|
|
! See http://factorcode.org/license.txt for BSD license.
|
2009-02-24 00:55:16 -05:00
|
|
|
USING: accessors kernel namespaces arrays sequences io words fry
|
2009-03-12 18:30:41 -04:00
|
|
|
continuations vocabs assocs dlists definitions math graphs generic
|
2009-04-24 21:43:01 -04:00
|
|
|
generic.single combinators deques search-deques macros io
|
|
|
|
source-files.errors stack-checker stack-checker.state
|
|
|
|
stack-checker.inlining stack-checker.errors combinators.short-circuit
|
|
|
|
compiler.errors compiler.units compiler.tree.builder
|
|
|
|
compiler.tree.optimizer compiler.cfg.builder compiler.cfg.optimizer
|
|
|
|
compiler.cfg.linearization compiler.cfg.two-operand
|
|
|
|
compiler.cfg.linear-scan compiler.cfg.stack-frame compiler.codegen
|
|
|
|
compiler.utilities ;
|
2007-09-20 18:09:08 -04:00
|
|
|
IN: compiler
|
|
|
|
|
2008-10-07 17:17:55 -04:00
|
|
|
SYMBOL: compile-queue
|
|
|
|
SYMBOL: compiled
|
|
|
|
|
2009-04-25 20:41:27 -04:00
|
|
|
: compile? ( word -- ? )
|
2009-04-21 23:33:04 -04:00
|
|
|
#! Don't attempt to compile certain words.
|
2008-10-07 17:17:55 -04:00
|
|
|
{
|
2009-02-24 00:55:16 -05:00
|
|
|
[ "forgotten" word-prop ]
|
|
|
|
[ compiled get key? ]
|
|
|
|
[ inlined-block? ]
|
|
|
|
[ primitive? ]
|
|
|
|
} 1|| not ;
|
|
|
|
|
|
|
|
: queue-compile ( word -- )
|
2009-04-25 20:41:27 -04:00
|
|
|
dup compile? [ compile-queue get push-front ] [ drop ] if ;
|
2008-10-07 17:17:55 -04:00
|
|
|
|
2009-04-21 04:23:11 -04:00
|
|
|
: recompile-callers? ( word -- ? )
|
|
|
|
changed-effects get key? ;
|
2008-06-11 03:58:38 -04:00
|
|
|
|
2009-04-21 04:23:11 -04:00
|
|
|
: recompile-callers ( words -- )
|
2009-04-21 23:33:04 -04:00
|
|
|
#! If a word's stack effect changed, recompile all words that
|
|
|
|
#! have compiled calls to it.
|
|
|
|
dup recompile-callers?
|
|
|
|
[ compiled-usage keys [ queue-compile ] each ] [ drop ] if ;
|
2007-12-19 20:55:40 -05:00
|
|
|
|
2008-10-07 17:17:55 -04:00
|
|
|
: start ( word -- )
|
2008-12-08 15:58:00 -05:00
|
|
|
"trace-compilation" get [ dup name>> print flush ] when
|
2008-10-07 17:17:55 -04:00
|
|
|
H{ } clone dependencies set
|
|
|
|
H{ } clone generic-dependencies set
|
2009-04-23 23:17:25 -04:00
|
|
|
clear-compiler-error ;
|
2008-01-01 14:54:14 -05:00
|
|
|
|
2009-04-25 20:41:27 -04:00
|
|
|
GENERIC: no-compile? ( word -- ? )
|
|
|
|
|
|
|
|
M: word no-compile? "no-compile" word-prop ;
|
|
|
|
|
|
|
|
M: method-body no-compile? "method-generic" word-prop no-compile? ;
|
|
|
|
|
|
|
|
M: predicate-engine-word no-compile? "owner-generic" word-prop no-compile? ;
|
|
|
|
|
2009-03-12 18:30:41 -04:00
|
|
|
: ignore-error? ( word error -- ? )
|
2009-04-23 23:17:25 -04:00
|
|
|
#! Ignore some errors on inline combinators, macros, and special
|
2009-04-21 23:33:04 -04:00
|
|
|
#! words such as 'call'.
|
2009-04-12 17:08:46 -04:00
|
|
|
[
|
|
|
|
{
|
|
|
|
[ macro? ]
|
2009-04-21 04:23:11 -04:00
|
|
|
[ inline? ]
|
2009-04-25 20:41:27 -04:00
|
|
|
[ no-compile? ]
|
2009-04-12 17:08:46 -04:00
|
|
|
[ "special" word-prop ]
|
|
|
|
} 1||
|
2009-04-23 23:17:25 -04:00
|
|
|
] [
|
|
|
|
{
|
|
|
|
[ do-not-compile? ]
|
|
|
|
[ literal-expected? ]
|
|
|
|
} 1||
|
|
|
|
] bi* and ;
|
2009-03-12 18:30:41 -04:00
|
|
|
|
2009-04-21 23:33:04 -04:00
|
|
|
: finish ( word -- )
|
|
|
|
#! Recompile callers if the word's stack effect changed, then
|
|
|
|
#! save the word's dependencies so that if they change, the
|
|
|
|
#! word can get recompiled too.
|
2009-04-21 04:23:11 -04:00
|
|
|
[ recompile-callers ]
|
2009-04-17 00:14:11 -04:00
|
|
|
[ compiled-unxref ]
|
2009-04-21 23:33:04 -04:00
|
|
|
[
|
|
|
|
dup crossref? [
|
|
|
|
dependencies get
|
|
|
|
generic-dependencies get
|
|
|
|
compiled-xref
|
|
|
|
] [ drop ] if
|
|
|
|
] tri ;
|
|
|
|
|
|
|
|
: deoptimize-with ( word def -- * )
|
|
|
|
#! If the word failed to infer, compile it with the
|
|
|
|
#! non-optimizing compiler.
|
|
|
|
swap [ finish ] [ compiled get set-at ] bi return ;
|
2008-10-07 17:17:55 -04:00
|
|
|
|
2009-04-20 23:05:41 -04:00
|
|
|
: not-compiled-def ( word error -- def )
|
|
|
|
'[ _ _ not-compiled ] [ ] like ;
|
|
|
|
|
2009-04-21 23:33:04 -04:00
|
|
|
: deoptimize ( word error -- * )
|
|
|
|
#! If the error is ignorable, compile the word with the
|
|
|
|
#! non-optimizing compiler, using its definition. Otherwise,
|
|
|
|
#! if the compiler error is not ignorable, use a dummy
|
|
|
|
#! definition from 'not-compiled-def' which throws an error.
|
2009-04-23 23:17:25 -04:00
|
|
|
2dup ignore-error? [
|
|
|
|
drop
|
|
|
|
[ dup def>> deoptimize-with ]
|
|
|
|
[ clear-compiler-error ]
|
|
|
|
bi
|
|
|
|
] [
|
|
|
|
[ swap <compiler-error> compiler-error ]
|
|
|
|
[ [ drop ] [ not-compiled-def ] 2bi deoptimize-with ]
|
|
|
|
2bi
|
|
|
|
] if ;
|
2009-04-17 00:14:11 -04:00
|
|
|
|
2009-04-25 20:41:27 -04:00
|
|
|
: optimize? ( word -- ? )
|
2009-04-27 15:10:12 -04:00
|
|
|
{
|
|
|
|
[ predicate-engine-word? ]
|
|
|
|
[ contains-breakpoints? ]
|
|
|
|
[ single-generic? ]
|
|
|
|
} 1|| not ;
|
2009-04-25 20:41:27 -04:00
|
|
|
|
2009-02-24 00:55:16 -05:00
|
|
|
: frontend ( word -- nodes )
|
2009-04-21 23:33:04 -04:00
|
|
|
#! If the word contains breakpoints, don't optimize it, since
|
|
|
|
#! the walker does not support this.
|
2009-04-25 20:41:27 -04:00
|
|
|
dup optimize?
|
|
|
|
[ [ build-tree ] [ deoptimize ] recover optimize-tree ]
|
|
|
|
[ dup def>> deoptimize-with ]
|
|
|
|
if ;
|
2008-01-01 14:54:14 -05:00
|
|
|
|
2009-04-21 23:33:04 -04:00
|
|
|
: compile-dependency ( word -- )
|
|
|
|
#! If a word calls an unoptimized word, try to compile the callee.
|
|
|
|
dup optimized>> [ drop ] [ queue-compile ] if ;
|
|
|
|
|
2008-10-12 18:37:42 -04:00
|
|
|
! Only switch this off for debugging.
|
|
|
|
SYMBOL: compile-dependencies?
|
|
|
|
|
|
|
|
t compile-dependencies? set-global
|
|
|
|
|
2009-04-21 23:33:04 -04:00
|
|
|
: compile-dependencies ( asm -- )
|
|
|
|
compile-dependencies? get
|
|
|
|
[ calls>> [ compile-dependency ] each ] [ drop ] if ;
|
|
|
|
|
2008-10-07 17:17:55 -04:00
|
|
|
: save-asm ( asm -- )
|
|
|
|
[ [ code>> ] [ label>> ] bi compiled get set-at ]
|
2009-04-21 23:33:04 -04:00
|
|
|
[ compile-dependencies ]
|
2008-10-07 17:17:55 -04:00
|
|
|
bi ;
|
|
|
|
|
|
|
|
: backend ( nodes word -- )
|
|
|
|
build-cfg [
|
2008-10-22 19:39:41 -04:00
|
|
|
optimize-cfg
|
2008-10-07 17:17:55 -04:00
|
|
|
build-mr
|
2008-10-28 05:38:37 -04:00
|
|
|
convert-two-operand
|
2008-10-07 17:17:55 -04:00
|
|
|
linear-scan
|
|
|
|
build-stack-frame
|
|
|
|
generate
|
|
|
|
save-asm
|
|
|
|
] each ;
|
|
|
|
|
2009-04-21 23:33:04 -04:00
|
|
|
: compile-word ( word -- )
|
|
|
|
#! We return early if the word has breakpoints or if it
|
|
|
|
#! failed to infer.
|
2008-08-15 00:35:19 -04:00
|
|
|
'[
|
2008-09-10 23:11:40 -04:00
|
|
|
_ {
|
2008-10-07 17:17:55 -04:00
|
|
|
[ start ]
|
|
|
|
[ frontend ]
|
|
|
|
[ backend ]
|
|
|
|
[ finish ]
|
2008-05-07 08:49:36 -04:00
|
|
|
} cleave
|
2008-08-15 00:35:19 -04:00
|
|
|
] with-return ;
|
2007-12-24 21:41:46 -05:00
|
|
|
|
2008-08-19 15:06:20 -04:00
|
|
|
: compile-loop ( deque -- )
|
2009-04-21 23:33:04 -04:00
|
|
|
[ compile-word yield-hook get call( -- ) ] slurp-deque ;
|
2007-12-17 16:29:54 -05:00
|
|
|
|
2008-02-24 03:19:38 -05:00
|
|
|
: decompile ( word -- )
|
2009-04-20 23:05:41 -04:00
|
|
|
dup def>> 2array 1array modify-code-heap ;
|
2008-02-24 03:19:38 -05:00
|
|
|
|
2009-02-24 00:55:16 -05:00
|
|
|
: compile-call ( quot -- )
|
|
|
|
[ dup infer define-temp ] with-compilation-unit execute ;
|
|
|
|
|
2009-04-12 17:08:46 -04:00
|
|
|
\ compile-call t "no-compile" set-word-prop
|
|
|
|
|
2009-03-13 20:39:32 -04:00
|
|
|
SINGLETON: optimizing-compiler
|
|
|
|
|
|
|
|
M: optimizing-compiler recompile ( words -- alist )
|
2007-12-17 16:29:54 -05:00
|
|
|
[
|
2008-06-11 03:58:38 -04:00
|
|
|
<hashed-dlist> compile-queue set
|
2007-12-24 21:41:46 -05:00
|
|
|
H{ } clone compiled set
|
2009-04-24 21:54:30 -04:00
|
|
|
[
|
|
|
|
[ queue-compile ]
|
|
|
|
[ subwords [ compile-dependency ] each ] bi
|
|
|
|
] each
|
2007-12-24 21:41:46 -05:00
|
|
|
compile-queue get compile-loop
|
2008-11-12 01:10:50 -05:00
|
|
|
compiled get >alist
|
2008-02-24 03:19:38 -05:00
|
|
|
] with-scope ;
|
2007-09-20 18:09:08 -04:00
|
|
|
|
2008-04-02 22:27:49 -04:00
|
|
|
: enable-compiler ( -- )
|
2009-03-13 20:39:32 -04:00
|
|
|
optimizing-compiler compiler-impl set-global ;
|
2008-04-02 22:27:49 -04:00
|
|
|
|
|
|
|
: disable-compiler ( -- )
|
2009-03-13 20:39:32 -04:00
|
|
|
f compiler-impl set-global ;
|
2008-04-02 22:27:49 -04:00
|
|
|
|
2007-12-27 17:26:39 -05:00
|
|
|
: recompile-all ( -- )
|
2009-04-20 19:44:45 -04:00
|
|
|
all-words compile ;
|