diff --git a/basis/compiler/cfg/representations/peephole/peephole.factor b/basis/compiler/cfg/representations/peephole/peephole.factor index 4080e8077c..1c590f88ff 100644 --- a/basis/compiler/cfg/representations/peephole/peephole.factor +++ b/basis/compiler/cfg/representations/peephole/peephole.factor @@ -106,38 +106,29 @@ M: ##load-reference optimize-insn [ 2drop int-rep ##copy here ] } cond ; -: inert-tag-imm? ( insn -- ? ) - src1>> rep-of tagged-rep? ; +: dst-tagged? ( insn -- ? ) dst>> rep-of tagged-rep? ; +: src1-tagged? ( insn -- ? ) src1>> rep-of tagged-rep? ; +: src2-tagged? ( insn -- ? ) src2>> rep-of tagged-rep? ; -: inert-tag/untag-imm? ( insn -- ? ) - { - [ dst>> rep-of tagged-rep? ] - [ inert-tag-imm? ] - } 1&& ; +: src2-tagged-arithmetic? ( insn -- ? ) src2>> tag-fixnum immediate-arithmetic? ; +: src2-tagged-bitwise? ( insn -- ? ) src2>> tag-fixnum immediate-bitwise? ; +: src2-tagged-shift-count? ( insn -- ? ) src2>> tag-bits get + immediate-shift-count? ; + +: >tagged-shift ( insn -- ) [ tag-bits get + ] change-src2 finish ; inline M: ##shl-imm optimize-insn { { - [ dup inert-tag/untag-imm? ] + [ dup { [ dst-tagged? ] [ src1-tagged? ] } 1&& ] [ unchanged ] } { - [ dup dst>> rep-of tagged-rep? ] - [ - [ emit-use-conversion ] - [ [ tag-bits get + ] change-src2 finish ] - [ no-def-conversion ] - tri - ] + [ dup { [ dst-tagged? ] [ src2-tagged-shift-count? ] } 1&& ] + [ [ emit-use-conversion ] [ >tagged-shift ] [ no-def-conversion ] tri ] } { - [ dup src1>> rep-of tagged-rep? ] - [ - [ no-use-conversion ] - [ combine-shl-imm-input ] - [ emit-def-conversion ] - tri - ] + [ dup src1-tagged? ] + [ [ no-use-conversion ] [ combine-shl-imm-input ] [ emit-def-conversion ] tri ] } [ call-next-method ] } cond ; @@ -148,25 +139,11 @@ M: ##shl-imm optimize-insn ! Into ! ##sar-imm by X + tag-bits ! assuming X + tag-bits is a valid shift count. -: combine-sar-imm? ( insn -- ? ) - { - [ src1>> rep-of tagged-rep? ] - [ src2>> tag-bits get + immediate-shift-count? ] - } 1&& ; - -: combine-sar-imm ( insn -- ) - [ dst>> ] [ src1>> ] [ src2>> tag-bits get + ] tri ##sar-imm here ; - M: ##sar-imm optimize-insn { { - [ dup combine-sar-imm? ] - [ - [ no-use-conversion ] - [ combine-sar-imm ] - [ emit-def-conversion ] - tri - ] + [ dup { [ src1-tagged? ] [ src2-tagged-shift-count? ] } 1&& ] + [ [ no-use-conversion ] [ >tagged-shift ] [ emit-def-conversion ] tri ] } [ call-next-method ] } cond ; @@ -177,18 +154,12 @@ M: ##sar-imm optimize-insn ! ! so if all inputs and outputs of ##X or ##X-imm are tagged, ! don't have to insert any conversions -: inert-tag? ( insn -- ? ) - { - [ src1>> rep-of tagged-rep? ] - [ src2>> rep-of tagged-rep? ] - } 1&& ; - -: inert-tag/untag? ( insn -- ? ) - { [ dst>> rep-of tagged-rep? ] [ inert-tag? ] } 1&& ; - M: inert-tag-untag-insn optimize-insn { - { [ dup inert-tag/untag? ] [ unchanged ] } + { + [ dup { [ dst-tagged? ] [ src1-tagged? ] [ src2-tagged? ] } 1&& ] + [ unchanged ] + } [ call-next-method ] } cond ; @@ -196,41 +167,53 @@ M: inert-tag-untag-insn optimize-insn : >tagged-imm ( insn -- ) [ tag-fixnum ] change-src2 unchanged ; inline -M: inert-tag-untag-imm-insn optimize-insn +M: inert-arithmetic-tag-untag-insn optimize-insn { - { [ dup inert-tag/untag-imm? ] [ >tagged-imm ] } + { + [ dup { [ dst-tagged? ] [ src1-tagged? ] [ src2-tagged-arithmetic? ] } 1&& ] + [ >tagged-imm ] + } + [ call-next-method ] + } cond ; + +M: inert-bitwise-tag-untag-insn optimize-insn + { + { + [ dup { [ dst-tagged? ] [ src1-tagged? ] [ src2-tagged-bitwise? ] } 1&& ] + [ >tagged-imm ] + } [ call-next-method ] } cond ; M: ##mul-imm optimize-insn { - { [ dup inert-tag/untag-imm? ] [ unchanged ] } - { [ dup dst>> rep-of tagged-rep? ] [ >tagged-imm ] } + { [ dup { [ dst-tagged? ] [ src1-tagged? ] } 1&& ] [ unchanged ] } + { [ dup { [ dst-tagged? ] [ src2-tagged-arithmetic? ] } 1&& ] [ >tagged-imm ] } [ call-next-method ] } cond ; ! Similar optimization for comparison operators M: ##compare-integer-imm optimize-insn { - { [ dup inert-tag-imm? ] [ >tagged-imm ] } + { [ dup { [ src1-tagged? ] [ src2-tagged-arithmetic? ] } 1&& ] [ >tagged-imm ] } [ call-next-method ] } cond ; M: ##compare-integer-imm-branch optimize-insn { - { [ dup inert-tag-imm? ] [ >tagged-imm ] } + { [ dup { [ src1-tagged? ] [ src2-tagged-arithmetic? ] } 1&& ] [ >tagged-imm ] } [ call-next-method ] } cond ; M: ##compare-integer optimize-insn { - { [ dup inert-tag? ] [ unchanged ] } + { [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] } [ call-next-method ] } cond ; M: ##compare-integer-branch optimize-insn { - { [ dup inert-tag? ] [ unchanged ] } + { [ dup { [ src1-tagged? ] [ src2-tagged? ] } 1&& ] [ unchanged ] } [ call-next-method ] } cond ; @@ -248,11 +231,7 @@ M: ##neg optimize-insn { [ dup inert-tag/untag-unary? ] [ unchanged ] } { [ dup dst>> rep-of tagged-rep? ] - [ - [ emit-use-conversion ] - [ combine-neg-tag ] - [ no-def-conversion ] tri - ] + [ [ emit-use-conversion ] [ combine-neg-tag ] [ no-def-conversion ] tri ] } [ call-next-method ] } cond ; @@ -268,12 +247,7 @@ M: ##not optimize-insn { { [ dup inert-tag/untag-unary? ] - [ - [ no-use-conversion ] - [ emit-tagged-not ] - [ no-def-conversion ] - tri - ] + [ [ no-use-conversion ] [ emit-tagged-not ] [ no-def-conversion ] tri ] } [ call-next-method ] } cond ; diff --git a/basis/compiler/cfg/representations/representations-tests.factor b/basis/compiler/cfg/representations/representations-tests.factor index f4728bc7e7..ef64908f78 100644 --- a/basis/compiler/cfg/representations/representations-tests.factor +++ b/basis/compiler/cfg/representations/representations-tests.factor @@ -560,6 +560,42 @@ cpu x86.32? [ } test-peephole ] unit-test +! Make sure we don't exceed immediate bounds +cpu x86.64? [ + 4 \ vreg-counter set-global + + [ + V{ + T{ ##peek f 0 D 0 } + T{ ##sar-imm f 5 0 $[ tag-bits get ] } + T{ ##add-imm f 6 5 $[ 30 2^ ] } + T{ ##shl-imm f 2 6 $[ tag-bits get ] } + T{ ##replace f 2 D 0 } + } + ] [ + V{ + T{ ##peek f 0 D 0 } + T{ ##add-imm f 2 0 $[ 30 2^ ] } + T{ ##replace f 2 D 0 } + } test-peephole + ] unit-test + + [ + V{ + T{ ##load-integer f 0 100 } + T{ ##mul-imm f 7 0 $[ 30 2^ ] } + T{ ##shl-imm f 1 7 $[ tag-bits get ] } + T{ ##replace f 1 D 0 } + } + ] [ + V{ + T{ ##load-integer f 0 100 } + T{ ##mul-imm f 1 0 $[ 30 2^ ] } + T{ ##replace f 1 D 0 } + } test-peephole + ] unit-test +] when + ! Tag/untag elimination for ##mul-imm [ V{ diff --git a/basis/compiler/cfg/representations/selection/selection.factor b/basis/compiler/cfg/representations/selection/selection.factor index 73e536ebee..6cabe27e85 100644 --- a/basis/compiler/cfg/representations/selection/selection.factor +++ b/basis/compiler/cfg/representations/selection/selection.factor @@ -96,9 +96,11 @@ UNION: inert-tag-untag-insn ##min ##max ; -UNION: inert-tag-untag-imm-insn +UNION: inert-arithmetic-tag-untag-insn ##add-imm -##sub-imm +##sub-imm ; + +UNION: inert-bitwise-tag-untag-insn ##and-imm ##or-imm ##xor-imm ; @@ -111,7 +113,8 @@ M: ##load-reference has-peephole-opts? drop t ; M: ##neg has-peephole-opts? drop t ; M: ##not has-peephole-opts? drop t ; M: inert-tag-untag-insn has-peephole-opts? drop t ; -M: inert-tag-untag-imm-insn has-peephole-opts? drop t ; +M: inert-arithmetic-tag-untag-insn has-peephole-opts? drop t ; +M: inert-bitwise-tag-untag-insn has-peephole-opts? drop t ; M: ##mul-imm has-peephole-opts? drop t ; M: ##shl-imm has-peephole-opts? drop t ; M: ##shr-imm has-peephole-opts? drop t ;