removing non-branching fixnum comparison vops
parent
2bdd82ea53
commit
d2eddcb4e8
|
@ -105,24 +105,35 @@ sequences vectors words ;
|
||||||
: binary-op ( node op -- )
|
: binary-op ( node op -- )
|
||||||
>r load-inputs first2 swap dup r> execute , out-1 ; inline
|
>r load-inputs first2 swap dup r> execute , out-1 ; inline
|
||||||
|
|
||||||
[
|
{
|
||||||
[[ fixnum+ %fixnum+ ]]
|
{ fixnum+ %fixnum+ }
|
||||||
[[ fixnum- %fixnum- ]]
|
{ fixnum- %fixnum- }
|
||||||
[[ fixnum* %fixnum* ]]
|
{ fixnum* %fixnum* }
|
||||||
[[ fixnum/i %fixnum/i ]]
|
{ fixnum/i %fixnum/i }
|
||||||
[[ fixnum-bitand %fixnum-bitand ]]
|
{ fixnum-bitand %fixnum-bitand }
|
||||||
[[ fixnum-bitor %fixnum-bitor ]]
|
{ fixnum-bitor %fixnum-bitor }
|
||||||
[[ fixnum-bitxor %fixnum-bitxor ]]
|
{ fixnum-bitxor %fixnum-bitxor }
|
||||||
[[ fixnum<= %fixnum<= ]]
|
} [
|
||||||
[[ fixnum< %fixnum< ]]
|
first2 [ literalize , \ binary-op , ] [ ] make
|
||||||
[[ fixnum>= %fixnum>= ]]
|
|
||||||
[[ fixnum> %fixnum> ]]
|
|
||||||
[[ eq? %eq? ]]
|
|
||||||
] [
|
|
||||||
uncons [ literalize , \ binary-op , ] [ ] make
|
|
||||||
"intrinsic" set-word-prop
|
"intrinsic" set-word-prop
|
||||||
] each
|
] each
|
||||||
|
|
||||||
|
: binary-jump ( node label op -- )
|
||||||
|
>r >r node-in-d values>vregs
|
||||||
|
dup length neg %inc-d , first2 swap
|
||||||
|
r> r> execute , ; inline
|
||||||
|
|
||||||
|
{
|
||||||
|
{ fixnum<= %jump-fixnum<= }
|
||||||
|
{ fixnum< %jump-fixnum< }
|
||||||
|
{ fixnum>= %jump-fixnum>= }
|
||||||
|
{ fixnum> %jump-fixnum> }
|
||||||
|
{ eq? %jump-eq? }
|
||||||
|
} [
|
||||||
|
first2 [ literalize , \ binary-jump , ] [ ] make
|
||||||
|
"ifte-intrinsic" set-word-prop
|
||||||
|
] each
|
||||||
|
|
||||||
\ fixnum-mod [
|
\ fixnum-mod [
|
||||||
! This is not clever. Because of x86, %fixnum-mod is
|
! This is not clever. Because of x86, %fixnum-mod is
|
||||||
! hard-coded to put its output in vreg 2, which happends to
|
! hard-coded to put its output in vreg 2, which happends to
|
||||||
|
|
|
@ -35,24 +35,33 @@ M: #label linearize* ( node -- )
|
||||||
|
|
||||||
: intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ;
|
: intrinsic ( #call -- quot ) node-param "intrinsic" word-prop ;
|
||||||
|
|
||||||
|
: ifte-intrinsic ( #call -- quot )
|
||||||
|
dup node-successor #ifte?
|
||||||
|
[ node-param "ifte-intrinsic" word-prop ] [ drop f ] ifte ;
|
||||||
|
|
||||||
|
: linearize-ifte ( node label -- )
|
||||||
|
#! Assume the quotation emits a VOP that jumps to the label
|
||||||
|
#! if some condition holds; we linearize the false branch,
|
||||||
|
#! then the label, then the true branch.
|
||||||
|
>r node-children first2 linearize* r> %label , linearize* ;
|
||||||
|
|
||||||
M: #call linearize* ( node -- )
|
M: #call linearize* ( node -- )
|
||||||
dup intrinsic [
|
dup ifte-intrinsic [
|
||||||
dupd call linearize-next
|
>r <label> 2dup r> call
|
||||||
|
>r node-successor r> linearize-ifte
|
||||||
] [
|
] [
|
||||||
\ %call \ %jump ?tail-call
|
dup intrinsic [
|
||||||
|
dupd call linearize-next
|
||||||
|
] [
|
||||||
|
\ %call \ %jump ?tail-call
|
||||||
|
] ifte*
|
||||||
] ifte* ;
|
] ifte* ;
|
||||||
|
|
||||||
M: #call-label linearize* ( node -- )
|
M: #call-label linearize* ( node -- )
|
||||||
\ %call-label \ %jump-label ?tail-call ;
|
\ %call-label \ %jump-label ?tail-call ;
|
||||||
|
|
||||||
: ifte-head ( label -- ) in-1 -1 %inc-d , 0 %jump-t , ;
|
|
||||||
|
|
||||||
M: #ifte linearize* ( node -- )
|
M: #ifte linearize* ( node -- )
|
||||||
node-children first2
|
<label> dup in-1 -1 %inc-d , 0 %jump-t , linearize-ifte ;
|
||||||
<label> dup ifte-head
|
|
||||||
swap linearize* ( false branch )
|
|
||||||
%label , ( branch target of BRANCH-T )
|
|
||||||
linearize* ( true branch ) ;
|
|
||||||
|
|
||||||
: dispatch-head ( vtable -- label/code )
|
: dispatch-head ( vtable -- label/code )
|
||||||
#! Output the jump table insn and return a list of
|
#! Output the jump table insn and return a list of
|
||||||
|
|
|
@ -141,37 +141,12 @@ M: %fixnum>> generate-node ( vop -- )
|
||||||
M: %fixnum-sgn generate-node ( vop -- )
|
M: %fixnum-sgn generate-node ( vop -- )
|
||||||
dest/src dupd 31 SRAWI dup untag ;
|
dest/src dupd 31 SRAWI dup untag ;
|
||||||
|
|
||||||
: compare ( vop -- )
|
|
||||||
dup 1 vop-in v>operand swap 0 vop-in dup integer? [
|
|
||||||
0 -rot address CMPI
|
|
||||||
] [
|
|
||||||
0 swap v>operand CMP
|
|
||||||
] ifte ;
|
|
||||||
|
|
||||||
: load-boolean ( dest cond -- )
|
|
||||||
#! Compile this after a conditional jump to store f or t
|
|
||||||
#! in dest depending on the jump being taken or not.
|
|
||||||
<label> "true" set
|
|
||||||
<label> "end" set
|
|
||||||
"true" get swap execute
|
|
||||||
f address over LI
|
|
||||||
"end" get B
|
|
||||||
"true" get save-xt
|
|
||||||
t load-indirect
|
|
||||||
"end" get save-xt ; inline
|
|
||||||
|
|
||||||
: fixnum-pred ( vop word -- dest )
|
|
||||||
>r [ compare ] keep 0 vop-out v>operand r> load-boolean ;
|
|
||||||
inline
|
|
||||||
|
|
||||||
M: %fixnum< generate-node ( vop -- ) \ BLT fixnum-pred ;
|
|
||||||
M: %fixnum<= generate-node ( vop -- ) \ BLE fixnum-pred ;
|
|
||||||
M: %fixnum> generate-node ( vop -- ) \ BGT fixnum-pred ;
|
|
||||||
M: %fixnum>= generate-node ( vop -- ) \ BGE fixnum-pred ;
|
|
||||||
M: %eq? generate-node ( vop -- ) \ BEQ fixnum-pred ;
|
|
||||||
|
|
||||||
: fixnum-jump ( vop -- label )
|
: fixnum-jump ( vop -- label )
|
||||||
[ compare ] keep vop-label ;
|
[
|
||||||
|
dup 1 vop-in v>operand
|
||||||
|
swap 0 vop-in v>operand
|
||||||
|
0 swap CMP
|
||||||
|
] keep vop-label ;
|
||||||
|
|
||||||
M: %jump-fixnum< generate-node ( vop -- ) fixnum-jump BLT ;
|
M: %jump-fixnum< generate-node ( vop -- ) fixnum-jump BLT ;
|
||||||
M: %jump-fixnum<= generate-node ( vop -- ) fixnum-jump BLE ;
|
M: %jump-fixnum<= generate-node ( vop -- ) fixnum-jump BLE ;
|
||||||
|
|
|
@ -261,17 +261,6 @@ TUPLE: %fixnum-bitnot ;
|
||||||
C: %fixnum-bitnot make-vop ; : %fixnum-bitnot 2-vop <%fixnum-bitnot> ;
|
C: %fixnum-bitnot make-vop ; : %fixnum-bitnot 2-vop <%fixnum-bitnot> ;
|
||||||
M: %fixnum-bitnot basic-block? drop t ;
|
M: %fixnum-bitnot basic-block? drop t ;
|
||||||
|
|
||||||
TUPLE: %fixnum<= ;
|
|
||||||
C: %fixnum<= make-vop ; : %fixnum<= 3-vop <%fixnum<=> ;
|
|
||||||
TUPLE: %fixnum< ;
|
|
||||||
C: %fixnum< make-vop ; : %fixnum< 3-vop <%fixnum<> ;
|
|
||||||
TUPLE: %fixnum>= ;
|
|
||||||
C: %fixnum>= make-vop ; : %fixnum>= 3-vop <%fixnum>=> ;
|
|
||||||
TUPLE: %fixnum> ;
|
|
||||||
C: %fixnum> make-vop ; : %fixnum> 3-vop <%fixnum>> ;
|
|
||||||
TUPLE: %eq? ;
|
|
||||||
C: %eq? make-vop ; : %eq? 3-vop <%eq?> ;
|
|
||||||
|
|
||||||
! At the VOP level, the 'shift' operation is split into five
|
! At the VOP level, the 'shift' operation is split into five
|
||||||
! distinct operations:
|
! distinct operations:
|
||||||
! - shifts with a large positive count: calls runtime to make
|
! - shifts with a large positive count: calls runtime to make
|
||||||
|
@ -293,7 +282,6 @@ TUPLE: %fixnum-sgn ;
|
||||||
C: %fixnum-sgn make-vop ; : %fixnum-sgn src/dest-vop <%fixnum-sgn> ;
|
C: %fixnum-sgn make-vop ; : %fixnum-sgn src/dest-vop <%fixnum-sgn> ;
|
||||||
M: %fixnum-sgn basic-block? drop t ;
|
M: %fixnum-sgn basic-block? drop t ;
|
||||||
|
|
||||||
|
|
||||||
! Integer comparison followed by a conditional branch is
|
! Integer comparison followed by a conditional branch is
|
||||||
! optimized
|
! optimized
|
||||||
TUPLE: %jump-fixnum<= ;
|
TUPLE: %jump-fixnum<= ;
|
||||||
|
@ -316,20 +304,6 @@ TUPLE: %jump-eq? ;
|
||||||
C: %jump-eq? make-vop ;
|
C: %jump-eq? make-vop ;
|
||||||
: %jump-eq? 2-in/label-vop <%jump-eq?> ;
|
: %jump-eq? 2-in/label-vop <%jump-eq?> ;
|
||||||
|
|
||||||
: fast-branch ( class -- class )
|
|
||||||
{{
|
|
||||||
[[ %fixnum<= %jump-fixnum<= ]]
|
|
||||||
[[ %fixnum< %jump-fixnum< ]]
|
|
||||||
[[ %fixnum>= %jump-fixnum>= ]]
|
|
||||||
[[ %fixnum> %jump-fixnum> ]]
|
|
||||||
[[ %eq? %jump-eq? ]]
|
|
||||||
}} hash ;
|
|
||||||
|
|
||||||
PREDICATE: tuple fast-branch
|
|
||||||
#! Class of VOPs whose class is a key in fast-branch
|
|
||||||
#! hashtable.
|
|
||||||
class fast-branch ;
|
|
||||||
|
|
||||||
! some slightly optimized inline assembly
|
! some slightly optimized inline assembly
|
||||||
TUPLE: %type ;
|
TUPLE: %type ;
|
||||||
C: %type make-vop ;
|
C: %type make-vop ;
|
||||||
|
|
|
@ -157,36 +157,6 @@ M: %fixnum-sgn generate-node
|
||||||
! give it a fixnum tag.
|
! give it a fixnum tag.
|
||||||
0 vop-out v>operand tag-bits SHL ;
|
0 vop-out v>operand tag-bits SHL ;
|
||||||
|
|
||||||
: load-boolean ( dest cond -- )
|
|
||||||
#! Compile this after a conditional jump to store f or t
|
|
||||||
#! in dest depending on the jump being taken or not.
|
|
||||||
<label> "true" set
|
|
||||||
<label> "end" set
|
|
||||||
"true" get swap execute
|
|
||||||
dup f address MOV
|
|
||||||
"end" get JMP
|
|
||||||
"true" get save-xt
|
|
||||||
t load-indirect
|
|
||||||
"end" get save-xt ; inline
|
|
||||||
|
|
||||||
: fixnum-compare ( vop -- dest )
|
|
||||||
dup 0 vop-out v>operand dup rot 0 vop-in v>operand CMP ;
|
|
||||||
|
|
||||||
M: %fixnum< generate-node ( vop -- )
|
|
||||||
fixnum-compare \ JL load-boolean ;
|
|
||||||
|
|
||||||
M: %fixnum<= generate-node ( vop -- )
|
|
||||||
fixnum-compare \ JLE load-boolean ;
|
|
||||||
|
|
||||||
M: %fixnum> generate-node ( vop -- )
|
|
||||||
fixnum-compare \ JG load-boolean ;
|
|
||||||
|
|
||||||
M: %fixnum>= generate-node ( vop -- )
|
|
||||||
fixnum-compare \ JGE load-boolean ;
|
|
||||||
|
|
||||||
M: %eq? generate-node ( vop -- )
|
|
||||||
fixnum-compare \ JE load-boolean ;
|
|
||||||
|
|
||||||
: fixnum-jump ( vop -- label )
|
: fixnum-jump ( vop -- label )
|
||||||
dup 1 vop-in v>operand over 0 vop-in v>operand CMP
|
dup 1 vop-in v>operand over 0 vop-in v>operand CMP
|
||||||
vop-label ;
|
vop-label ;
|
||||||
|
|
|
@ -30,14 +30,14 @@ memory parser sequences strings vectors words prettyprint ;
|
||||||
\ eq? t "flushable" set-word-prop
|
\ eq? t "flushable" set-word-prop
|
||||||
\ eq? t "foldable" set-word-prop
|
\ eq? t "foldable" set-word-prop
|
||||||
|
|
||||||
! : manual-branch ( word -- )
|
: manual-branch ( word -- )
|
||||||
! dup "infer-effect" word-prop consume/produce
|
dup "infer-effect" word-prop consume/produce
|
||||||
! [ [ t ] [ f ] ifte ] infer-quot ;
|
[ [ t ] [ f ] ifte ] infer-quot ;
|
||||||
!
|
|
||||||
! { fixnum<= fixnum< fixnum>= fixnum> eq? } [
|
{ fixnum<= fixnum< fixnum>= fixnum> eq? } [
|
||||||
! dup dup literalize [ manual-branch ] cons
|
dup dup literalize [ manual-branch ] cons
|
||||||
! "infer" set-word-prop
|
"infer" set-word-prop
|
||||||
! ] each
|
] each
|
||||||
|
|
||||||
! Primitive combinators
|
! Primitive combinators
|
||||||
\ call [ [ general-list ] [ ] ] "infer-effect" set-word-prop
|
\ call [ [ general-list ] [ ] ] "infer-effect" set-word-prop
|
||||||
|
|
|
@ -172,6 +172,7 @@ math-internals test words ;
|
||||||
[ t ] [ { 1 2 3 } { 1 2 3 } [ over type over type eq? ] compile-1 2nip ] unit-test
|
[ t ] [ { 1 2 3 } { 1 2 3 } [ over type over type eq? ] compile-1 2nip ] unit-test
|
||||||
|
|
||||||
! regression
|
! regression
|
||||||
: blah over cons? [ "x" get >r 2cdr r> ] [ 2drop f f f ] ifte ; compiled
|
: bleh 3 ;
|
||||||
|
: blah over cons? [ bleh >r 2cdr r> ] [ 2drop f f f ] ifte ; compiled
|
||||||
|
|
||||||
[ f ] [ f "x" set [ 1 2 3 ] [ 1 3 2 ] blah drop 2car = ] unit-test
|
[ f ] [ f [ 1 2 3 ] [ 1 3 2 ] blah drop 2car = ] unit-test
|
||||||
|
|
Loading…
Reference in New Issue