compiler.cfg.intrinsics.slots: refactor + docs & tests
parent
686975ec29
commit
02c80423ba
|
@ -1,6 +1,6 @@
|
|||
USING: classes classes.builtin compiler.cfg.instructions compiler.tree
|
||||
compiler.tree.propagation.info help.markup help.syntax math layouts sequences
|
||||
slots.private words ;
|
||||
USING: classes classes.builtin compiler.tree
|
||||
compiler.tree.propagation.info help.markup help.syntax layouts math
|
||||
slots.private ;
|
||||
IN: compiler.cfg.intrinsics.slots
|
||||
|
||||
HELP: class-tag
|
||||
|
@ -26,15 +26,17 @@ HELP: immediate-slot-offset?
|
|||
}
|
||||
} ;
|
||||
|
||||
HELP: value-tag
|
||||
{ $values { "info" value-info-state } { "n" number } }
|
||||
{ $description "Finds the class number for this value-info-states class (an index in the " { $link builtins } " list), or " { $link f } " if it hasn't one." } ;
|
||||
HELP: node>set-slot-data
|
||||
{ $values
|
||||
{ "#call" #call }
|
||||
{ "write-barrier?" "whether a write barrier is needed, it always is unless the item to set is an " { $link immediate } }
|
||||
{ "tag" "a number or f" }
|
||||
{ "literal" "a literal" }
|
||||
} { $description "Grabs the data needed from a call node to determine what intrinsic CFG instructions to emit for the " { $link set-slot } " call." } ;
|
||||
|
||||
HELP: emit-write-barrier?
|
||||
{ $values { "infos" "a " { $link sequence } " of " { $link value-info-state } " tuples." } { "?" "true or false" } }
|
||||
{ $description
|
||||
"Whether a given call to " { $link set-slot } " requires a write barrier to be emitted or not. Write barriers are always needed except when the element to set in the slot is known by the compiler to be " { $link immediate } "." }
|
||||
{ $see-also ##write-barrier } ;
|
||||
HELP: value-tag
|
||||
{ $values { "info" value-info-state } { "n/f" number } }
|
||||
{ $description "Finds the class number for this value-info-states class (an index in the " { $link builtins } " list), or " { $link f } " if it hasn't one." } ;
|
||||
|
||||
HELP: emit-set-slot
|
||||
{ $values { "node" node } }
|
||||
|
|
|
@ -0,0 +1,170 @@
|
|||
USING: accessors arrays compiler.cfg compiler.cfg.instructions
|
||||
compiler.cfg.intrinsics.slots compiler.test compiler.tree
|
||||
compiler.tree.propagation.info kernel make math math.intervals
|
||||
namespaces sequences slots.private tools.test ;
|
||||
IN: compiler.cfg.intrinsics.slots.tests
|
||||
|
||||
: call-node-1 ( -- node )
|
||||
T{ #call
|
||||
{ word set-slot }
|
||||
{ in-d V{ 9133848 9133849 9133850 } }
|
||||
{ out-d { } }
|
||||
{ info
|
||||
H{
|
||||
{
|
||||
9133848
|
||||
T{ value-info-state
|
||||
{ class object }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
{
|
||||
9133849
|
||||
T{ value-info-state
|
||||
{ class object }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
{
|
||||
9133850
|
||||
T{ value-info-state
|
||||
{ class object }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
: call-node-2 ( -- node )
|
||||
T{ #call
|
||||
{ word set-slot }
|
||||
{ in-d V{ 1 2 3 } }
|
||||
{ out-d { } }
|
||||
{ info
|
||||
H{
|
||||
{
|
||||
1
|
||||
T{ value-info-state
|
||||
{ class object }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
{
|
||||
2
|
||||
T{ value-info-state
|
||||
{ class array }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
{
|
||||
3
|
||||
T{ value-info-state
|
||||
{ class object }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
: call-node-3 ( -- node )
|
||||
T{ #call
|
||||
{ word set-slot }
|
||||
{ in-d V{ 1 2 3 } }
|
||||
{ out-d { } }
|
||||
{ info
|
||||
H{
|
||||
{
|
||||
1
|
||||
T{ value-info-state
|
||||
{ class object }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
{
|
||||
2
|
||||
T{ value-info-state
|
||||
{ class array }
|
||||
{ interval full-interval }
|
||||
}
|
||||
}
|
||||
{
|
||||
3
|
||||
T{ value-info-state
|
||||
{ class fixnum }
|
||||
{ interval
|
||||
T{ interval
|
||||
{ from { 9 t } }
|
||||
{ to { 9 t } }
|
||||
}
|
||||
}
|
||||
{ literal 9 }
|
||||
{ literal? t }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} ;
|
||||
|
||||
! emit-set-slot
|
||||
{
|
||||
V{ T{ ##call { word set-slot } } T{ ##branch } }
|
||||
} [
|
||||
call-node-1 [ emit-set-slot ] V{ } make drop
|
||||
basic-block get successors>> first instructions>>
|
||||
] cfg-unit-test
|
||||
|
||||
{
|
||||
V{
|
||||
T{ ##set-slot
|
||||
{ src 1 }
|
||||
{ obj 2 }
|
||||
{ slot 3 }
|
||||
{ scale 3 }
|
||||
{ tag 2 }
|
||||
}
|
||||
T{ ##write-barrier
|
||||
{ src 2 }
|
||||
{ slot 3 }
|
||||
{ scale 3 }
|
||||
{ tag 2 }
|
||||
{ temp1 4 }
|
||||
{ temp2 5 }
|
||||
}
|
||||
}
|
||||
} [
|
||||
call-node-2 [ emit-set-slot ] V{ } make
|
||||
] cfg-unit-test
|
||||
|
||||
{
|
||||
V{
|
||||
T{ ##set-slot-imm { src 1 } { obj 2 } { slot 9 } { tag 2 } }
|
||||
T{ ##write-barrier-imm
|
||||
{ src 2 }
|
||||
{ slot 9 }
|
||||
{ tag 2 }
|
||||
{ temp1 3 }
|
||||
{ temp2 4 }
|
||||
}
|
||||
}
|
||||
} [
|
||||
call-node-3 [ emit-set-slot ] V{ } make
|
||||
] cfg-unit-test
|
||||
|
||||
! immediate-slot-offset?
|
||||
{ t f } [
|
||||
33 immediate-slot-offset?
|
||||
"foo" immediate-slot-offset?
|
||||
] unit-test
|
||||
|
||||
! node>set-slot-data
|
||||
{
|
||||
t f f
|
||||
t 2 f
|
||||
t 2 9
|
||||
} [
|
||||
call-node-1 node>set-slot-data
|
||||
call-node-2 node>set-slot-data
|
||||
call-node-3 node>set-slot-data
|
||||
] unit-test
|
|
@ -2,16 +2,16 @@
|
|||
! See http://factorcode.org/license.txt for BSD license.
|
||||
USING: accessors classes.algebra classes.builtin
|
||||
combinators.short-circuit compiler.cfg.builder.blocks
|
||||
compiler.cfg.hats compiler.cfg.instructions
|
||||
compiler.cfg.registers compiler.cfg.stacks
|
||||
compiler.tree.propagation.info cpu.architecture kernel layouts
|
||||
locals math namespaces sequences ;
|
||||
compiler.cfg.hats compiler.cfg.instructions compiler.cfg.registers
|
||||
compiler.cfg.stacks compiler.tree.propagation.info cpu.architecture
|
||||
kernel layouts locals math namespaces sequences slots.private ;
|
||||
IN: compiler.cfg.intrinsics.slots
|
||||
|
||||
: class-tag ( class -- tag/f )
|
||||
builtins get [ class<= ] with find drop ;
|
||||
|
||||
: value-tag ( info -- n ) class>> class-tag ;
|
||||
: value-tag ( info -- n/f )
|
||||
class>> class-tag ;
|
||||
|
||||
: slot-indexing ( slot tag -- slot scale tag )
|
||||
complex-addressing?
|
||||
|
@ -27,52 +27,48 @@ IN: compiler.cfg.intrinsics.slots
|
|||
[ [ second literal>> ] [ first value-tag ] bi ] bi*
|
||||
^^slot-imm ;
|
||||
|
||||
: immediate-slot-offset? ( value-info -- ? )
|
||||
literal>> {
|
||||
[ fixnum? ]
|
||||
[ cell * immediate-arithmetic? ]
|
||||
} 1&& ;
|
||||
: immediate-slot-offset? ( object -- ? )
|
||||
{ [ fixnum? ] [ cell * immediate-arithmetic? ] } 1&& ;
|
||||
|
||||
: emit-slot ( node -- )
|
||||
dup node-input-infos
|
||||
dup first value-tag [
|
||||
nip
|
||||
dup second immediate-slot-offset?
|
||||
dup second literal>> immediate-slot-offset?
|
||||
[ (emit-slot-imm) ] [ (emit-slot) ] if
|
||||
ds-push
|
||||
] [ drop emit-primitive ] if ;
|
||||
|
||||
: emit-write-barrier? ( infos -- ? )
|
||||
first class>> immediate class<= not ;
|
||||
|
||||
:: (emit-set-slot) ( infos -- )
|
||||
3inputs :> ( src obj slot )
|
||||
|
||||
infos second value-tag :> tag
|
||||
|
||||
slot tag slot-indexing :> ( slot scale tag )
|
||||
src obj slot scale tag ##set-slot,
|
||||
|
||||
infos emit-write-barrier?
|
||||
[ obj slot scale tag next-vreg next-vreg ##write-barrier, ] when ;
|
||||
|
||||
:: (emit-set-slot-imm) ( infos -- )
|
||||
:: (emit-set-slot-imm) ( write-barrier? tag slot -- )
|
||||
ds-drop
|
||||
|
||||
2inputs :> ( src obj )
|
||||
|
||||
infos third literal>> :> slot
|
||||
infos second value-tag :> tag
|
||||
|
||||
src obj slot tag ##set-slot-imm,
|
||||
|
||||
infos emit-write-barrier?
|
||||
write-barrier?
|
||||
[ obj slot tag next-vreg next-vreg ##write-barrier-imm, ] when ;
|
||||
|
||||
:: (emit-set-slot) ( write-barrier? tag -- )
|
||||
3inputs :> ( src obj slot )
|
||||
|
||||
slot tag slot-indexing :> ( slot scale tag )
|
||||
|
||||
src obj slot scale tag ##set-slot,
|
||||
|
||||
write-barrier?
|
||||
[ obj slot scale tag next-vreg next-vreg ##write-barrier, ] when ;
|
||||
|
||||
: node>set-slot-data ( #call -- write-barrier? tag literal )
|
||||
node-input-infos first3
|
||||
[ class>> immediate class<= not ] [ value-tag ] [ literal>> ] tri* ;
|
||||
|
||||
: emit-intrinsic-set-slot ( write-barrier? tag index-info -- )
|
||||
dup immediate-slot-offset? [
|
||||
(emit-set-slot-imm)
|
||||
] [ drop (emit-set-slot) ] if ;
|
||||
|
||||
: emit-set-slot ( node -- )
|
||||
dup node-input-infos
|
||||
dup second value-tag [
|
||||
nip
|
||||
dup third immediate-slot-offset?
|
||||
[ (emit-set-slot-imm) ] [ (emit-set-slot) ] if
|
||||
] [ drop emit-primitive ] if ;
|
||||
dup node>set-slot-data over [
|
||||
emit-intrinsic-set-slot drop
|
||||
] [ 3drop emit-primitive ] if ;
|
||||
|
|
Loading…
Reference in New Issue