compiler.cfg.instructions
compiler.cfg.gvn.math
compiler.cfg.gvn.graph
+compiler.cfg.gvn.avail
compiler.cfg.gvn.rewrite ;
IN: compiler.cfg.gvn.alien
##add
] { } make ;
-! XXX the vregs that src>> vreg>insn uses are not necessarily available
: rewrite-unbox-any-c-ptr ( insn -- insn/f )
dup src>> vreg>insn
{
- { [ dup ##box-alien? ] [ rewrite-unbox-alien ] }
- { [ dup ##box-displaced-alien? ] [ rewrite-unbox-displaced-alien ] }
+ {
+ [ dup [ ##box-alien? ] with-available-uses? ]
+ [ rewrite-unbox-alien ]
+ }
+ {
+ [ dup [ ##box-displaced-alien? ] with-available-uses? ]
+ [ rewrite-unbox-displaced-alien ]
+ }
[ 2drop f ]
} cond ;
! Fuse ##add-imm into ##load-memory(-imm) and ##store-memory(-imm)
! just update the offset in the instruction
: fuse-base-offset? ( insn -- ? )
- base>> vreg>insn ##add-imm? ;
+ base>> vreg>insn [ ##add-imm? ] with-available-uses? ;
-! XXX base>> vreg>insn src1>> not necessarily available
: fuse-base-offset ( insn -- insn' )
clone dup base>> vreg>insn
[ src1>> ] [ src2>> ] bi
! Fuse ##add-imm into ##load-memory and ##store-memory
! just update the offset in the instruction
: fuse-displacement-offset? ( insn -- ? )
- { [ scale>> 0 = ] [ displacement>> vreg>insn ##add-imm? ] } 1&& ;
+ {
+ [ scale>> 0 = ]
+ [ displacement>> vreg>insn [ ##add-imm? ] with-available-uses? ]
+ } 1&& ;
-! XXX displacement>> vreg>insn src1>> not necessarily available
: fuse-displacement-offset ( insn -- insn' )
clone dup displacement>> vreg>insn
[ src1>> ] [ src2>> ] bi
: fuse-displacement? ( insn -- ? )
{
[ offset>> 0 = complex-addressing? or ]
- [ base>> vreg>insn ##add? ]
+ [ base>> vreg>insn [ ##add? ] with-available-uses? ]
} 1&& ;
GENERIC: alien-insn-value ( insn -- value )
M: ##load-memory-imm new-alien-insn drop \ ##load-memory new-insn ;
M: ##store-memory-imm new-alien-insn drop \ ##store-memory new-insn ;
-! XXX base>> vreg>insn src1>> & src2>> not necessarily
-! available
: fuse-displacement ( insn -- insn' )
{
[ alien-insn-value ]
{ [ ##shl-imm? ] [ src2>> { 1 2 3 } member? ] } 1&& ;
: fuse-scale? ( insn -- ? )
- { [ scale>> 0 = ] [ displacement>> vreg>insn scale-insn? ] } 1&& ;
+ {
+ [ scale>> 0 = ]
+ [ displacement>> vreg>insn [ scale-insn? ] with-available-uses? ]
+ } 1&& ;
-! XXX displacement>> vreg>insn src1>> not necessarily available
: fuse-scale ( insn -- insn' )
clone dup displacement>> vreg>insn
[ src1>> ] [ src2>> ] bi
! Copyright (C) 2011 Alex Vondrak.
! See http://factorcode.org/license.txt for BSD license.
-USING: accessors assocs compiler.cfg
+USING: accessors assocs hashtables kernel namespaces sequences
+sets
+compiler.cfg
compiler.cfg.dataflow-analysis
compiler.cfg.def-use
-compiler.cfg.predecessors compiler.cfg.rpo deques dlists
-hashtables kernel locals namespaces sequences sets ;
+compiler.cfg.gvn.graph
+compiler.cfg.predecessors
+compiler.cfg.rpo ;
FROM: namespaces => set ;
IN: compiler.cfg.gvn.avail
M: avail-analysis transfer-set drop defined assoc-union ;
+! Strict idea of availability, for now. Would like to see if
+! searching the VN congruence classes for the smallest
+! available vn would work at all / better.
+
: available? ( vn -- ? )
- basic-block get avail-ins get at key? ;
+ final-iteration? get [
+ basic-block get avail-ins get at key?
+ ] [ drop t ] if ;
+
+: available-uses? ( insn -- ? )
+ uses-vregs [ available? ] all? ;
+
+: with-available-uses? ( quot -- ? )
+ [ available-uses? ] bi and ; inline
: make-available ( insn -- insn )
dup dst>>
compiler.cfg.registers
compiler.cfg.gvn.math
compiler.cfg.gvn.graph
+compiler.cfg.gvn.avail
compiler.cfg.gvn.rewrite ;
IN: compiler.cfg.gvn.comparisons
: rewrite-redundant-comparison? ( insn -- ? )
{
- [ src1>> vreg>insn scalar-compare-insn? ]
+ [ src1>> vreg>insn [ scalar-compare-insn? ] with-available-uses? ]
[ src2>> not ]
[ cc>> { cc= cc/= } member? ]
} 1&& ; inline
-! XXX the vregs that src1>> vreg>insn uses are not necessarily available
: rewrite-redundant-comparison ( insn -- insn' )
[ cc>> ] [ dst>> ] [ src1>> vreg>insn ] tri {
{ [ dup ##compare? ] [ >compare< next-vreg \ ##compare new-insn ] }
[ drop f ]
} cond ;
-! XXX the vregs (src1>> and src2>>) that src1>> vreg>insn uses
-! are not necessarily available
+: simplify-test? ( insn -- ? )
+ src1>> vreg>insn [ ##and? ] with-available-uses? ;
+
: (simplify-test) ( insn -- src1 src2 cc )
[ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
: simplify-test-branch ( insn -- insn )
(simplify-test) \ ##test-branch new-insn ; inline
-! XXX the vregs (src1>> and src2>>) that src1>> vreg>insn uses
-! are not necessarily available
+: simplify-test-imm? ( insn -- ? )
+ src1>> vreg>insn [ ##and-imm? ] with-available-uses? ;
+
: (simplify-test-imm) ( insn -- src1 src2 cc )
[ src1>> vreg>insn [ src1>> ] [ src2>> ] bi ] [ cc>> ] bi ; inline
{ [ dup src2>> vreg-immediate-comparand? ] [ f >test-imm ] }
{ [ dup diagonal? ] [
{
- { [ dup src1>> vreg>insn ##and? ] [ simplify-test ] }
- { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm ] }
+ { [ dup simplify-test? ] [ simplify-test ] }
+ { [ dup simplify-test-imm? ] [ simplify-test-imm ] }
[ drop f ]
} cond
] }
{ [ dup src2>> vreg-immediate-comparand? ] [ f >test-imm-branch ] }
{ [ dup diagonal? ] [
{
- { [ dup src1>> vreg>insn ##and? ] [ simplify-test-branch ] }
- { [ dup src1>> vreg>insn ##and-imm? ] [ simplify-test-imm-branch ] }
+ { [ dup simplify-test? ] [ simplify-test-branch ] }
+ { [ dup simplify-test-imm? ] [ simplify-test-imm-branch ] }
[ drop f ]
} cond
] }
compiler.cfg.utilities
compiler.cfg.gvn.folding
compiler.cfg.gvn.graph
+compiler.cfg.gvn.avail
compiler.cfg.gvn.rewrite ;
IN: compiler.cfg.gvn.math
[ 2drop f ]
} cond ;
-! XXX src>> vreg>insn src>> not necessarily available
+: self-inverse? ( insn quot -- ? )
+ [ src>> vreg>insn ] dip with-available-uses? ; inline
+
: self-inverse ( insn -- insn' )
[ dst>> ] [ src>> vreg>insn src>> ] bi <copy> ;
M: ##neg rewrite
{
- { [ dup src>> vreg>insn ##neg? ] [ self-inverse ] }
+ { [ dup [ ##neg? ] self-inverse? ] [ self-inverse ] }
{ [ dup unary-constant-fold? ] [ unary-constant-fold ] }
[ drop f ]
} cond ;
M: ##not rewrite
{
- { [ dup src>> vreg>insn ##not? ] [ self-inverse ] }
+ { [ dup [ ##not? ] self-inverse? ] [ self-inverse ] }
{ [ dup unary-constant-fold? ] [ unary-constant-fold ] }
[ drop f ]
} cond ;
: mul-to-shl ( insn -- insn' )
[ [ dst>> ] [ src1>> ] bi ] [ src2>> log2 ] bi \ ##shl-imm new-insn ;
-! XXX not sure if availability is an issue
! Distribution converts
! ##+-imm 2 1 X
! ##*-imm 3 2 Y
] [ f ] if ; inline
: distribute-over-add? ( insn -- ? )
- src1>> vreg>insn ##add-imm? ;
+ src1>> vreg>insn [ ##add-imm? ] with-available-uses? ;
: distribute-over-sub? ( insn -- ? )
- src1>> vreg>insn ##sub-imm? ;
+ src1>> vreg>insn [ ##sub-imm? ] with-available-uses? ;
: distribute ( insn add-op mul-op -- new-insns/f )
[
compiler.cfg.instructions
compiler.cfg.gvn.math
compiler.cfg.gvn.graph
+compiler.cfg.gvn.avail
compiler.cfg.gvn.rewrite ;
IN: compiler.cfg.gvn.simd
! Some lame constant folding for SIMD intrinsics. Eventually this
! should be redone completely.
-! XXX pretty much all of these rely on the vregs used by some
-! vreg>insn, but they aren't necessarily available
-
: useless-shuffle-vector-imm? ( insn -- ? )
[ shuffle>> ] [ rep>> rep-length iota ] bi sequence= ;
M: ##shuffle-vector-imm rewrite
dup src>> vreg>insn {
{ [ over useless-shuffle-vector-imm? ] [ drop [ dst>> ] [ src>> ] bi <copy> ] }
- { [ dup ##shuffle-vector-imm? ] [ compose-shuffle-vector-imm ] }
+ { [ dup [ ##shuffle-vector-imm? ] with-available-uses? ] [ compose-shuffle-vector-imm ] }
{ [ dup ##load-reference? ] [ fold-shuffle-vector-imm ] }
[ 2drop f ]
} cond ;
M: ##scalar>vector rewrite
dup src>> vreg>insn {
{ [ dup literal-insn? ] [ fold-scalar>vector ] }
- { [ dup ##vector>scalar? ] [ [ dst>> ] [ src>> ] bi* <copy> ] }
+ { [ dup [ ##vector>scalar? ] with-available-uses? ] [ [ dst>> ] [ src>> ] bi* <copy> ] }
[ 2drop f ]
} cond ;
: vector-not? ( insn -- ? )
{
- [ ##not-vector? ]
+ [ [ ##not-vector? ] with-available-uses? ]
[ {
- [ ##xor-vector? ]
+ [ [ ##xor-vector? ] with-available-uses? ]
[ [ src1>> ] [ src2>> ] bi [ vreg>insn ##fill-vector? ] either? ]
} 1&& ]
} 1|| ;
kernel math
compiler.cfg.instructions
compiler.cfg.gvn.graph
+compiler.cfg.gvn.avail
compiler.cfg.gvn.rewrite ;
IN: compiler.cfg.gvn.slots
: simplify-slot-addressing? ( insn -- ? )
- complex-addressing?
- [ slot>> vreg>insn ##add-imm? ] [ drop f ] if ;
+ complex-addressing? [
+ slot>> vreg>insn [ ##add-imm? ] with-available-uses?
+ ] [ drop f ] if ;
-! XXX the vregs that slot>> vreg>insn uses are not necessarily available
: simplify-slot-addressing ( insn -- insn/f )
dup simplify-slot-addressing? [
clone dup slot>> vreg>insn