]> gitweb.factorcode.org Git - factor.git/commitdiff
compiler cleanups
authorSlava Pestov <slava@factorcode.org>
Mon, 13 Dec 2004 21:28:28 +0000 (21:28 +0000)
committerSlava Pestov <slava@factorcode.org>
Mon, 13 Dec 2004 21:28:28 +0000 (21:28 +0000)
library/compiler/alien-macros.factor
library/compiler/assembly-x86.factor
library/compiler/generator-x86.factor
library/compiler/linearizer.factor
library/compiler/optimizer.factor
library/inference/branches.factor
library/inference/dataflow.factor
library/kernel.factor
library/test/dataflow.factor

index 717d1d4576278e81542c78a6d627297425214ad4..27f816d7268df0957d1ceb98ff215756022d31e0 100644 (file)
@@ -32,6 +32,10 @@ USE: lists
 USE: math
 USE: namespaces
 
+: SELF-CALL ( name -- )
+    #! Call named C function in Factor interpreter executable.
+    dlsym-self CALL JUMP-FIXUP ;
+
 : UNBOX ( name -- )
     #! Move top of datastack to C stack.
     SELF-CALL  EAX PUSH-R ;
index 1e4c2533fae17fb5f3333454eb9bd0e77cc91bd6..5c4253d1b433c54267f0520edbc9d5fb06dc4cbd 100644 (file)
@@ -170,6 +170,12 @@ USE: math
     BIN: 100 BIN: 11 MOD-R/M
     compile-byte ;
 
+: R>>I ( imm reg -- )
+    #! SHIFT <reg> BY <imm>, STORE RESULT IN <reg>
+    HEX: c1 compile-byte
+    BIN: 111 BIN: 11 MOD-R/M
+    compile-byte ;
+
 : CMP-I-R ( imm reg -- )
     #! There are three forms of CMP we assemble
     #! 83 f8 03                cmpl   $0x3,%eax
index 8b3ae3228289a81472a9228ecba97fd91a1b0e54..1f342beb1aeccd49371428e134df3c8cad9aa2b6 100644 (file)
 IN: compiler
 USE: alien
 USE: inference
-USE: errors
 USE: kernel
-USE: lists
-USE: math
 USE: namespaces
-USE: strings
 USE: words
-USE: vectors
 
 : DS ( -- address ) "ds" dlsym-self ;
 
-: PUSH-DS ( -- )
-    #! Push contents of EAX onto datastack.
-    DS ECX [I]>R
-    4 ECX R+I
-    EAX ECX R>[R]
-    ECX DS R>[I] ;
-
 : POP-DS ( -- )
     #! Pop datastack to EAX.
     DS ECX [I]>R
@@ -53,21 +41,6 @@ USE: vectors
     4 ECX R-I
     ECX DS R>[I] ;
 
-: PEEK-DS ( -- )
-    #! Peek datastack to EAX.
-    DS ECX [I]>R
-    ECX EAX [R]>R ;
-
-: PEEK-2-DS ( -- )
-    #! Peek second value on datastack to EAX.
-    DS ECX [I]>R
-    4 ECX R-I
-    ECX EAX [R]>R ;
-
-: SELF-CALL ( name -- )
-    #! Call named C function in Factor interpreter executable.
-    dlsym-self CALL JUMP-FIXUP ;
-
 #push-immediate [
     DS ECX [I]>R
     4 ECX R+I
@@ -110,75 +83,20 @@ USE: vectors
 
 #return [ drop RET ] "generator" set-word-property
 
-[
-    [ #drop drop ]
-    [ #dup  dup  ]
-    [ #swap swap ]
-    [ #over over ]
-    [ #pick pick ]
-    [ #>r   >r   ]
-    [ #r>   r>   ]
-] [
-    uncons [
-        car CALL compiled-offset defer-xt drop
-    ] cons "generator" set-word-property
-] each
-
-: begin-jump-table ( -- )
+#dispatch [
     #! Compile a piece of code that jumps to an offset in a
-    #! jump table indexed by the type of the Factor object in
-    #! EAX.
+    #! jump table indexed by the fixnum at the top of the stack.
     #! The jump table must immediately follow this macro.
-    2 EAX R<<I ( -- fixup )
+    drop
+    POP-DS
+    1 EAX R>>I ( -- fixup )
     EAX+/PARTIAL
     EAX JUMP-[R]
     cell compile-aligned
-    compiled-offset swap set-compiled-cell ( fixup -- ) ;
+    compiled-offset swap set-compiled-cell ( fixup -- )
+] "generator" set-word-property
 
-: jump-table-entry ( word -- )
+#target [
     #! Jump table entries are absolute addresses.
-    ( dup postpone-word )
-    compiled-offset 0 compile-cell 0 defer-xt ;
-
-: check-jump-table ( vtable -- )
-    length num-types = [
-        "Jump table must have " num-types " entries" cat3 throw
-    ] unless ;
-
-: compile-jump-table ( vtable -- )
-    #! Compile a table of words as a word-array of XTs.
-    begin-jump-table
-    dup check-jump-table
-    [ jump-table-entry ] each ;
-
-: TYPE ( -- )
-    #! Peek datastack, store type # in EAX.
-    PEEK-DS
-    EAX PUSH-R
-    "type_of" SELF-CALL
-    4 ESP R+I ;
-
-: compile-generic ( vtable -- )
-    #! Compile a faster alternative to
-    #! : generic ( obj vtable -- )
-    #!     >r dup type r> vector-nth execute ;
-    TYPE  compile-jump-table ;
-
-#generic [ compile-generic ] "generator" set-word-property
-
-: ARITHMETIC-TYPE ( -- )
-    #! Peek top two on datastack, store arithmetic type # in EAX.
-    PEEK-DS
-    EAX PUSH-R
-    PEEK-2-DS
-    EAX PUSH-R
-    "arithmetic_type" SELF-CALL
-    8 ESP R+I ;
-
-: compile-2generic ( vtable -- )
-    #! Compile a faster alternative to
-    #! : 2generic ( obj vtable -- )
-    #!     >r 2dup arithmetic-type r> vector-nth execute ;
-    ARITHMETIC-TYPE  compile-jump-table ;
-
-#2generic [ compile-2generic ] "generator" set-word-property
+    compiled-offset 0 compile-cell 0 defer-xt
+] "generator" set-word-property
index 02d54c658b9b9a09681b49576a96792502192335..ccc3baaf0c36e4b26ab900abcdf12ae80a68512f 100644 (file)
@@ -32,6 +32,8 @@ USE: lists
 USE: math
 USE: namespaces
 USE: words
+USE: strings
+USE: errors
 
 ! The linear IR is close to assembly language. It also resembles
 ! Forth code in some sense. It exists so that pattern matching
@@ -47,6 +49,11 @@ SYMBOL: #jump-label ( unconditional branch )
 SYMBOL: #jump ( tail-call )
 SYMBOL: #return-to ( push addr on C stack )
 
+! #dispatch is linearized as #dispatch followed by a #target
+! for each dispatch table entry. The linearizer ensures the
+! correct number of #targets is emitted.
+SYMBOL: #target ( part of jump table )
+
 : linear, ( node -- )
     #! Add a node to the linear IR.
     [ node-op get node-param get ] bind cons , ;
@@ -128,31 +135,45 @@ SYMBOL: #return-to ( push addr on C stack )
     [ node-param get ] bind linearize-ifte
 ] "linearizer" set-word-property
 
-: generic-head ( param op -- end label/param )
+: dispatch-head ( vtable -- end label/code )
     #! Output the jump table insn and return a list of
     #! label/branch pairs.
-    >r
+    [ #dispatch ] ,
     <label> ( end label ) swap
-    [ <label> cons ] map
-    dup [ cdr ] map r> swons , ;
+    [ <label> dup #target swons ,  cons ] map ;
 
-: generic-body ( end label/param -- )
+: dispatch-body ( end label/param -- )
     #! Output each branch, with a jump to the end label.
     [
         uncons label,  (linearize)  dup #jump-label swons ,
     ] each drop ;
 
-: linearize-generic ( param op -- )
+: check-dispatch ( vtable -- )
+    length num-types = [
+        "Dispatch must have " num-types " entries" cat3 throw
+    ] unless ;
+
+: linearize-dispatch ( vtable -- )
     #! The parameter is a list of lists, each one is a branch to
     #! take in case the top of stack has that type.
-    generic-head dupd generic-body label, ;
+    dup check-dispatch dispatch-head dupd dispatch-body label, ;
 
-#generic [
-    [ node-param get node-op get ] bind linearize-generic
-] "linearizer" set-word-property
-
-#2generic [
-    [ node-param get node-op get ] bind linearize-generic
+#dispatch [
+    [ node-param get ] bind linearize-dispatch
 ] "linearizer" set-word-property
 
 #values [ drop ] "linearizer" set-word-property
+
+[
+    [ #drop drop ]
+    [ #dup  dup  ]
+    [ #swap swap ]
+    [ #over over ]
+    [ #pick pick ]
+    [ #>r   >r   ]
+    [ #r>   r>   ]
+] [
+    uncons
+    [ car #call swons , drop ] cons
+    "linearizer" set-word-property
+] each
index 70a4695225ed7ddbc9d20eec8597078a91b978a5..3f480256f4aa8d6c9d0f113cd9243aa7109d8f9a 100644 (file)
@@ -153,11 +153,7 @@ USE: prettyprint
     [ node-param get ] bind branches-call-label?
 ] "calls-label" set-word-property
 
-#generic [
-    [ node-param get ] bind branches-call-label?
-] "calls-label" set-word-property
-
-#2generic [
+#dispatch [
     [ node-param get ] bind branches-call-label?
 ] "calls-label" set-word-property
 
@@ -177,13 +173,9 @@ USE: prettyprint
 #ifte [ can-kill-branches? ] "can-kill" set-word-property
 #ifte [ kill-branches ] "kill-node" set-word-property
 
-#generic [ scan-branches ] "scan-literal" set-word-property
-#generic [ can-kill-branches? ] "can-kill" set-word-property
-#generic [ kill-branches ] "kill-node" set-word-property
-
-#2generic [ scan-branches ] "scan-literal" set-word-property
-#2generic [ can-kill-branches? ] "can-kill" set-word-property
-#2generic [ kill-branches ] "kill-node" set-word-property
+#dispatch [ scan-branches ] "scan-literal" set-word-property
+#dispatch [ can-kill-branches? ] "can-kill" set-word-property
+#dispatch [ kill-branches ] "kill-node" set-word-property
 
 ! Don't care about inputs to recursive combinator calls
 #call-label [ 2drop t ] "can-kill" set-word-property
index 96519b2f0bd68db6b082af79241fbda86ce7769e..249533ef9fb19f25f571dff6b5cd3b1c621f8ced 100644 (file)
@@ -106,7 +106,8 @@ USE: hashtables
     [
         f infer-branch [
             d-in get meta-d get vector-length cons
-        ] bind recursive-state get set-base
+            recursive-state get set-base
+        ] bind
     ] [
         [ 2drop ] when
     ] catch ;
@@ -150,27 +151,18 @@ USE: hashtables
     pop-d drop ( condition )
     infer-branches ;
 
+\ ifte [ infer-ifte ] "infer" set-word-property
+
 : vtable>list ( [ vtable | rstate ] -- list )
     unswons vector>list [ over cons ] map nip ;
 
-: infer-generic ( -- )
+: infer-dispatch ( -- )
     #! Infer effects for all branches, unify.
     2 ensure-d
     dataflow-drop, pop-d vtable>list
-    >r 1 meta-d get vector-tail* #generic r>
-    infer-branches ;
-
-: infer-2generic ( -- )
-    #! Infer effects for all branches, unify.
-    3 ensure-d
-    dataflow-drop, pop-d vtable>list
-    >r 2 meta-d get vector-tail* #2generic r>
+    >r 1 meta-d get vector-tail* #dispatch r>
+    pop-d drop ( n )
     infer-branches ;
 
-\ ifte [ infer-ifte ] "infer" set-word-property
-
-\ generic [ infer-generic ] "infer" set-word-property
-\ generic [ 2 | 0 ] "infer-effect" set-word-property
-
-\ 2generic [ infer-2generic ] "infer" set-word-property
-\ 2generic [ 3 | 0 ] "infer-effect" set-word-property
+\ dispatch [ infer-dispatch ] "infer" set-word-property
+\ dispatch [ 2 | 0 ] "infer-effect" set-word-property
index 0b04292a273a3e3cc2ecdc8dab9addacd2c8b982..772c8d60d9f21a37ae7e84f873f38f5f57f29228 100644 (file)
@@ -50,8 +50,7 @@ SYMBOL: #call-label
 SYMBOL: #push ( literal )
 
 SYMBOL: #ifte
-SYMBOL: #generic
-SYMBOL: #2generic
+SYMBOL: #dispatch
 
 ! This is purely a marker for values we retain after a
 ! conditional. It does not generate code, but merely alerts the
index 47c8df51eb786272c8f97a994db85ba14194e12e..0f94ef4aa5383403e1d7c283bb399e443d1f6635 100644 (file)
@@ -50,11 +50,14 @@ USE: vectors
 ! It is quite clumsy, however. A higher-level CLOS-style
 ! 'generic words' system will be built later.
 
+: dispatch ( n vtable -- )
+    vector-nth call ;
+
 : generic ( obj vtable -- )
-    >r dup type r> vector-nth call ;
+    >r dup type r> dispatch ; inline
 
 : 2generic ( n n vtable -- )
-    >r 2dup arithmetic-type r> vector-nth call ;
+    >r 2dup arithmetic-type r> dispatch ; inline
 
 : hashcode ( obj -- hash )
     #! If two objects are =, they must have equal hashcodes.
index 143e24122266d32922c0859e1e8faa57696fb4cf..44a73cee9d2c94b2a61f4e572929d4373af6d219 100644 (file)
@@ -63,7 +63,7 @@ USE: generic
 
 [ t ] [
     [ { [ drop ] [ undefined-method ] [ drop ] [ undefined-method ] } generic ] dataflow
-    #generic swap dataflow-contains-op? car [
+    #dispatch swap dataflow-contains-op? car [
         node-param get [
             [ [ node-param get \ undefined-method = ] bind ] some?
         ] some?