factor/basis/compiler/compiler.factor

177 lines
5.0 KiB
Factor
Raw Normal View History

! Copyright (C) 2004, 2009 Slava Pestov.
2007-09-20 18:09:08 -04:00
! See http://factorcode.org/license.txt for BSD license.
USING: accessors kernel namespaces arrays sequences io words fry
continuations vocabs assocs dlists definitions math graphs generic
2009-04-23 23:17:25 -04:00
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
: queue-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
{
[ "forgotten" word-prop ]
[ compiled get key? ]
[ inlined-block? ]
[ primitive? ]
} 1|| not ;
: queue-compile ( word -- )
dup queue-compile? [ compile-queue get push-front ] [ drop ] if ;
2008-10-07 17:17:55 -04:00
: recompile-callers? ( word -- ? )
changed-effects get key? ;
2008-06-11 03:58:38 -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 ;
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
: 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'.
[
{
[ macro? ]
[ inline? ]
[ "special" word-prop ]
[ "no-compile" word-prop ]
} 1||
2009-04-23 23:17:25 -04:00
] [
{
[ do-not-compile? ]
[ literal-expected? ]
} 1||
] bi* and ;
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.
[ 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
: 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
: 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.
dup contains-breakpoints? [ dup def>> deoptimize-with ] [
[ build-tree ] [ deoptimize ] recover optimize-tree
2009-04-17 00:14:11 -04:00
] 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 ;
! 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 ;
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 ;
: decompile ( word -- )
dup def>> 2array 1array modify-code-heap ;
: compile-call ( quot -- )
[ dup infer define-temp ] with-compilation-unit execute ;
\ compile-call t "no-compile" set-word-prop
SINGLETON: optimizing-compiler
M: optimizing-compiler recompile ( words -- alist )
[
2008-06-11 03:58:38 -04:00
<hashed-dlist> compile-queue set
H{ } clone compiled set
2008-02-25 04:38:37 -05:00
[ queue-compile ] each
compile-queue get compile-loop
compiled get >alist
] with-scope ;
2007-09-20 18:09:08 -04:00
: enable-compiler ( -- )
optimizing-compiler compiler-impl set-global ;
: disable-compiler ( -- )
f compiler-impl set-global ;
: recompile-all ( -- )
all-words compile ;