| 
									
										
										
										
											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-05-14 17:54:16 -04:00
										 |  |  | generic.single combinators deques search-deques macros | 
					
						
							| 
									
										
										
										
											2009-05-31 13:20:46 -04:00
										 |  |  | source-files.errors combinators.short-circuit | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | stack-checker stack-checker.state stack-checker.inlining stack-checker.errors | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | compiler.errors compiler.units compiler.utilities | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | compiler.tree.builder | 
					
						
							|  |  |  | compiler.tree.optimizer | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | compiler.cfg.builder | 
					
						
							|  |  |  | compiler.cfg.optimizer | 
					
						
							|  |  |  | compiler.cfg.mr | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | compiler.codegen ;
 | 
					
						
							| 
									
										
										
										
											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-06-01 03:32:42 -04:00
										 |  |  | : deoptimize* ( word -- * )
 | 
					
						
							|  |  |  |     dup def>> deoptimize-with ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-29 20:39:04 -04:00
										 |  |  | : ignore-error ( word error -- * )
 | 
					
						
							| 
									
										
										
										
											2009-06-01 03:32:42 -04:00
										 |  |  |     drop [ clear-compiler-error ] [ deoptimize* ] bi ;
 | 
					
						
							| 
									
										
										
										
											2009-04-29 20:39:04 -04:00
										 |  |  | 
 | 
					
						
							|  |  |  | : remember-error ( word error -- * )
 | 
					
						
							|  |  |  |     [ swap <compiler-error> compiler-error ] | 
					
						
							|  |  |  |     [ [ drop ] [ not-compiled-def ] 2bi deoptimize-with ] | 
					
						
							|  |  |  |     2bi ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											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-29 20:39:04 -04:00
										 |  |  |     { | 
					
						
							|  |  |  |         { [ dup inference-error? not ] [ rethrow ] } | 
					
						
							|  |  |  |         { [ 2dup ignore-error? ] [ ignore-error ] } | 
					
						
							|  |  |  |         [ remember-error ] | 
					
						
							|  |  |  |     } cond ;
 | 
					
						
							| 
									
										
										
										
											2009-04-17 00:14:11 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-04-25 20:41:27 -04:00
										 |  |  | : optimize? ( word -- ? )
 | 
					
						
							| 
									
										
										
										
											2009-05-05 10:12:32 -04:00
										 |  |  |     { [ predicate-engine-word? ] [ single-generic? ] } 1|| not ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : contains-breakpoints? ( -- ? )
 | 
					
						
							|  |  |  |     dependencies get keys [ "break?" word-prop ] any? ;
 | 
					
						
							| 
									
										
										
										
											2009-04-25 20:41:27 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 03:32:42 -04:00
										 |  |  | : frontend ( word -- tree )
 | 
					
						
							| 
									
										
										
										
											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-05-05 10:12:32 -04:00
										 |  |  |     dup optimize? [ | 
					
						
							|  |  |  |         [ [ build-tree ] [ deoptimize ] recover optimize-tree ] keep
 | 
					
						
							| 
									
										
										
										
											2009-06-01 03:32:42 -04:00
										 |  |  |         contains-breakpoints? [ nip deoptimize* ] [ drop ] if
 | 
					
						
							|  |  |  |     ] [ deoptimize* ] 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. | 
					
						
							| 
									
										
										
										
											2009-04-28 18:26:11 -04:00
										 |  |  |     dup optimized? [ drop ] [ queue-compile ] if ;
 | 
					
						
							| 
									
										
										
										
											2009-04-21 23:33:04 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											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 ;
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-06-01 03:32:42 -04:00
										 |  |  | : backend ( tree word -- )
 | 
					
						
							| 
									
										
										
										
											2008-10-07 17:17:55 -04:00
										 |  |  |     build-cfg [ | 
					
						
							| 
									
										
										
										
											2008-10-22 19:39:41 -04:00
										 |  |  |         optimize-cfg | 
					
						
							| 
									
										
										
										
											2009-05-29 14:11:34 -04:00
										 |  |  |         build-mr | 
					
						
							| 
									
										
										
										
											2008-10-07 17:17:55 -04:00
										 |  |  |         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
 | 
					
						
							| 
									
										
										
										
											2009-06-05 18:32:37 -04:00
										 |  |  |     ] with-scope
 | 
					
						
							|  |  |  |     "trace-compilation" get [ "--- compile done" print flush ] when ;
 | 
					
						
							| 
									
										
										
										
											2007-09-20 18:09:08 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-01 06:52:05 -04:00
										 |  |  | : with-optimizer ( quot -- )
 | 
					
						
							|  |  |  |     [ optimizing-compiler compiler-impl ] dip with-variable ; inline
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | : enable-optimizer ( -- )
 | 
					
						
							| 
									
										
										
										
											2009-03-13 20:39:32 -04:00
										 |  |  |     optimizing-compiler compiler-impl set-global ;
 | 
					
						
							| 
									
										
										
										
											2008-04-02 22:27:49 -04:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2009-05-01 06:52:05 -04:00
										 |  |  | : disable-optimizer ( -- )
 | 
					
						
							| 
									
										
										
										
											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 ;
 |