factor/library/compiler/linearizer.factor

174 lines
5.1 KiB
Factor
Raw Normal View History

2006-03-02 01:12:32 -05:00
! Copyright (C) 2004, 2006 Slava Pestov.
! See http://factorcode.org/license.txt for BSD license.
IN: compiler
USING: arrays generic hashtables inference
2006-03-07 19:53:58 -05:00
kernel math namespaces sequences words ;
2006-03-07 19:53:58 -05:00
! On PowerPC and AMD64, we use a stack discipline whereby
! stack frames are used to hold parameters. We need to compute
! the stack frame size to compile the prologue on entry to a
! word.
GENERIC: stack-reserve*
M: object stack-reserve* drop 0 ;
: stack-reserve ( node -- )
0 swap [ stack-reserve* max ] each-node ;
2006-03-02 01:12:32 -05:00
DEFER: #terminal?
PREDICATE: #merge #terminal-merge node-successor #terminal? ;
UNION: #terminal POSTPONE: f #return #values #terminal-merge ;
: tail-call? ( -- ? )
node-stack get [ node-successor ] map [ #terminal? ] all? ;
GENERIC: linearize* ( node -- next )
: linearize-child ( node -- )
[ node@ linearize* ] iterate-nodes ;
2005-12-04 19:56:42 -05:00
2005-12-21 02:43:41 -05:00
! A map from words to linear IR.
SYMBOL: linearized
! Renamed labels. To avoid problems with labels with the same
! name in different scopes.
SYMBOL: renamed-labels
2006-02-11 02:30:18 -05:00
: make-linear ( word quot -- )
2006-03-02 01:12:32 -05:00
[
0 { d-height r-height } [ set ] each-with
2006-03-07 19:53:58 -05:00
swap >r { } make r> linearized get set-hash
2006-03-02 01:12:32 -05:00
] with-node-iterator ; inline
2006-02-11 02:30:18 -05:00
2006-03-02 01:12:32 -05:00
: linearize-1 ( word node -- )
2006-03-07 19:53:58 -05:00
swap [
dup stack-reserve %prologue ,
linearize-child
end-basic-block
2006-03-07 19:53:58 -05:00
] make-linear ;
2005-12-21 02:43:41 -05:00
: init-linearizer ( -- )
H{ } clone linearized set
H{ } clone renamed-labels set ;
: linearize ( word dataflow -- linearized )
#! Outputs a hashtable mapping from labels to their
#! respective linear IR.
init-linearizer linearize-1 linearized get ;
2005-05-17 16:13:08 -04:00
2006-03-02 01:12:32 -05:00
M: node linearize* ( node -- next ) drop iterate-next ;
2004-12-05 23:00:52 -05:00
2006-03-02 01:12:32 -05:00
: linearize-call ( label -- next )
tail-call? [ %jump , f ] [ %call , iterate-next ] if ;
2005-05-17 16:13:08 -04:00
2006-03-02 01:12:32 -05:00
: rename-label ( label -- label )
<label> dup rot renamed-labels get set-hash ;
2005-05-17 16:13:08 -04:00
2006-03-02 01:12:32 -05:00
: renamed-label ( label -- label )
renamed-labels get hash ;
2005-12-21 02:43:41 -05:00
2006-03-02 01:12:32 -05:00
: linearize-call-label ( label -- next )
rename-label linearize-call ;
2005-12-21 02:43:41 -05:00
2006-03-02 01:12:32 -05:00
M: #label linearize* ( node -- next )
#! We remap the IR node's label to a new label object here,
#! to avoid problems with two IR #label nodes having the
#! same label in different lexical scopes.
2006-03-02 01:12:32 -05:00
dup node-param dup linearize-call-label >r
renamed-label swap node-child linearize-1 r> ;
2005-06-08 04:49:05 -04:00
2005-09-08 22:23:54 -04:00
: intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ;
2005-06-08 04:49:05 -04:00
2005-09-24 15:21:17 -04:00
: if-intrinsic ( #call -- quot )
dup node-successor #if?
[ node-param "if-intrinsic" word-prop ] [ drop f ] if ;
: linearize-if ( node label -- next )
2006-03-02 01:12:32 -05:00
<label> dup >r >r >r node-children first2 linearize-child
r> r> %jump-label , %label , linearize-child r> %label ,
iterate-next ;
2006-03-04 02:53:22 -05:00
M: #call linearize* ( node -- next )
2005-09-24 15:21:17 -04:00
dup if-intrinsic [
>r <label> 2dup r> call
2006-03-04 02:53:22 -05:00
>r node-successor r> linearize-if node-successor
2005-09-08 22:23:54 -04:00
] [
2006-03-02 01:12:32 -05:00
dup intrinsic
[ call iterate-next ] [ node-param linearize-call ] if*
2005-09-24 15:21:17 -04:00
] if* ;
2005-05-06 18:33:40 -04:00
2006-03-02 01:12:32 -05:00
M: #call-label linearize* ( node -- next )
node-param renamed-label linearize-call ;
2005-06-09 19:49:31 -04:00
SYMBOL: live-d
SYMBOL: live-r
: value-dropped? ( value -- ? )
dup value?
over live-d get member? not
rot live-r get member? not and
or ;
: filter-dropped ( seq -- seq )
[ dup value-dropped? [ drop f ] when ] map ;
: prepare-inputs ( values -- values templates )
filter-dropped dup [ any-reg swap 2array ] map ;
: do-inputs ( node -- )
dup node-in-d prepare-inputs rot node-in-r prepare-inputs
template-inputs ;
: live-stores ( instack outstack -- stack )
#! Avoid storing a value into its former position.
dup length [ pick ?nth dupd eq? [ drop f ] when ] 2map nip ;
: shuffle-height ( node -- )
[ dup node-out-d length swap node-in-d length - ] keep
dup node-out-r length swap node-in-r length -
adjust-stacks end-basic-block ;
M: #shuffle linearize* ( #shuffle -- )
[
0 vreg-allocator set
dup node-in-d over node-out-d live-stores live-d set
dup node-in-r over node-out-r live-stores live-r set
dup do-inputs
shuffle-height
live-d get live-r get template-outputs
] with-scope iterate-next ;
: ?static-branch ( node -- n )
node-in-d first dup value?
[ value-literal 0 1 ? ] [ drop f ] if ;
2006-03-02 01:12:32 -05:00
M: #if linearize* ( node -- next )
dup ?static-branch [
-1 0 adjust-stacks end-basic-block
swap node-children nth linearize-child iterate-next
] [
dup { { 0 "flag" } } { } [
<label> dup "flag" get %jump-t ,
] with-template linearize-if
] if* ;
2006-04-01 19:50:33 -05:00
: dispatch-head ( node -- label/node )
2004-12-05 21:17:09 -05:00
#! Output the jump table insn and return a list of
#! label/branch pairs.
dup { { 0 "n" } } { } [ "n" get %dispatch , ] with-template
2006-04-01 19:50:33 -05:00
node-children [ <label> dup %target-label , 2array ] map ;
2004-12-05 21:17:09 -05:00
2006-03-02 01:12:32 -05:00
: dispatch-body ( label/node -- )
2006-02-28 00:26:45 -05:00
<label> swap [
2006-03-02 01:12:32 -05:00
first2 %label , linearize-child dup %jump-label ,
2006-02-28 00:26:45 -05:00
] each %label , ;
2004-12-13 16:28:28 -05:00
2006-03-02 01:12:32 -05:00
M: #dispatch linearize* ( node -- next )
2005-09-08 22:23:54 -04:00
#! The parameter is a list of nodes, each one is a branch to
2004-12-05 21:17:09 -05:00
#! take in case the top of stack has that type.
2006-04-01 19:50:33 -05:00
dispatch-head dispatch-body iterate-next ;
2006-03-02 01:12:32 -05:00
M: #return linearize* drop %return , f ;