: emit-actual-if ( #if -- )
! Inputs to the final instruction need to be copied because of
! loc>vreg sync
- ds-pop any-rep ^^copy \ f type-number cc/= ##compare-imm-branch emit-if ;
+ ds-pop any-rep ^^copy f cc/= ##compare-imm-branch emit-if ;
M: #if emit-node
{
} cond
swap cc= eq? [ [ negate-cc ] change-cc ] when ;
-ERROR: bad-comparison ;
-
: (fold-compare-imm) ( insn -- ? )
- [ [ src1>> vreg>constant ] [ src2>> ] bi ] [ cc>> ] bi
- pick integer?
- [ [ <=> ] dip evaluate-cc ]
- [
- 2nip {
- { cc= [ f ] }
- { cc/= [ t ] }
- [ bad-comparison ]
+ [ src1>> vreg>constant ] [ src2>> ] [ cc>> ] tri
+ 2over [ integer? ] both? [ [ <=> ] dip evaluate-cc ] [
+ {
+ { cc= [ eq? ] }
+ { cc/= [ eq? not ] }
} case
] if ;
: constant-fold ( insn -- insn' )
[ dst>> ]
- [ [ src1>> vreg>constant ] [ src2>> ] [ ] tri constant-fold* ] bi
+ [
+ [ src1>> vreg>constant \ f type-number or ]
+ [ src2>> ]
+ [ ]
+ tri constant-fold*
+ ] bi
\ ##load-immediate new-insn ; inline
: unary-constant-fold? ( insn -- ? )
[ drop f ]
} cond ;
-: insn>imm-insn ( insn op swap? -- )
+: insn>imm-insn ( insn op swap? -- new-insn )
swap [
[ [ dst>> ] [ src1>> ] [ src2>> ] tri ] dip
[ swap ] when vreg>constant
arithmetic-op?
[ vreg-immediate-arithmetic? ] [ vreg-immediate-bitwise? ] if ;
-: rewrite-arithmetic ( insn op -- ? )
+: rewrite-arithmetic ( insn op -- insn/f )
{
{ [ over src2>> over vreg-immediate? ] [ f insn>imm-insn ] }
[ 2drop f ]
} cond ; inline
-: rewrite-arithmetic-commutative ( insn op -- ? )
+: rewrite-arithmetic-commutative ( insn op -- insn/f )
{
{ [ over src2>> over vreg-immediate? ] [ f insn>imm-insn ] }
{ [ over src1>> over vreg-immediate? ] [ t insn>imm-insn ] }
} value-numbering-step trim-temps
] unit-test
+! Branch folding
+[
+ {
+ T{ ##load-immediate f 1 100 }
+ T{ ##load-immediate f 2 200 }
+ T{ ##load-constant f 3 t }
+ }
+] [
+ {
+ T{ ##load-immediate f 1 100 }
+ T{ ##load-immediate f 2 200 }
+ T{ ##compare f 3 1 2 cc<= }
+ } value-numbering-step trim-temps
+] unit-test
+
+[
+ {
+ T{ ##load-immediate f 1 100 }
+ T{ ##load-immediate f 2 200 }
+ T{ ##load-constant f 3 f }
+ }
+] [
+ {
+ T{ ##load-immediate f 1 100 }
+ T{ ##load-immediate f 2 200 }
+ T{ ##compare f 3 1 2 cc= }
+ } value-numbering-step trim-temps
+] unit-test
+
+[
+ {
+ T{ ##load-immediate f 1 100 }
+ T{ ##load-constant f 2 f }
+ }
+] [
+ {
+ T{ ##load-immediate f 1 100 }
+ T{ ##compare-imm f 2 1 f cc= }
+ } value-numbering-step trim-temps
+] unit-test
+
+[
+ {
+ T{ ##load-constant f 1 f }
+ T{ ##load-constant f 2 t }
+ }
+] [
+ {
+ T{ ##load-constant f 1 f }
+ T{ ##compare-imm f 2 1 f cc= }
+ } value-numbering-step trim-temps
+] unit-test
+
! Reassociation
[
{
} value-numbering-step
] unit-test
+! Stupid constant folding corner case
+[
+ {
+ T{ ##load-constant f 1 f }
+ T{ ##load-immediate f 2 $[ \ f type-number ] }
+ }
+] [
+ {
+ T{ ##load-constant f 1 f }
+ T{ ##and-imm f 2 1 15 }
+ } value-numbering-step
+] unit-test
+
! Displaced alien optimizations
3 vreg-counter set-global
{ [ 3dup use-test? ] [ 2drop dup TEST ] }
{ [ over integer? ] [ drop CMP ] }
{ [ over word? ] [ drop (%compare-tagged) ] }
- { [ over not ] [ 2drop f type-number CMP ] }
+ { [ over not ] [ 2drop \ f type-number CMP ] }
} cond ;
M:: x86 %compare-imm ( dst src1 src2 cc temp -- )