properly optimize X - -1 and X + -1, this also fixes type change of ubyte - 2 + 10

This commit is contained in:
Irmen de Jong 2022-06-05 15:35:29 +02:00
parent 031f647952
commit 46ca0ac10d
5 changed files with 116 additions and 66 deletions

View File

@ -192,6 +192,21 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
modifications += IAstModification.ReplaceNode(expr, result, parent)
}
if(leftconst==null && rightconst!=null && rightconst.number<0.0) {
if (expr.operator == "-") {
// X - -1 ---> X + 1
val posNumber = NumericLiteral.optimalNumeric(-rightconst.number, rightconst.position)
val plusExpr = BinaryExpression(expr.left, "+", posNumber, expr.position)
return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent))
}
else if (expr.operator == "+") {
// X + -1 ---> X - 1
val posNumber = NumericLiteral.optimalNumeric(-rightconst.number, rightconst.position)
val plusExpr = BinaryExpression(expr.left, "-", posNumber, expr.position)
return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent))
}
}
val leftBinExpr = expr.left as? BinaryExpression
val rightBinExpr = expr.right as? BinaryExpression

View File

@ -152,4 +152,35 @@ class TestNumericLiteral: FunSpec({
(NumericLiteral(DataType.FLOAT, 100.0, dummyPos) <= NumericLiteral(DataType.FLOAT, 99.9, dummyPos)) shouldBe false
}
test("optimalInteger") {
NumericLiteral.optimalInteger(10, Position.DUMMY).type shouldBe DataType.UBYTE
NumericLiteral.optimalInteger(10, Position.DUMMY).number shouldBe 10.0
NumericLiteral.optimalInteger(-10, Position.DUMMY).type shouldBe DataType.BYTE
NumericLiteral.optimalInteger(-10, Position.DUMMY).number shouldBe -10.0
NumericLiteral.optimalInteger(1000, Position.DUMMY).type shouldBe DataType.UWORD
NumericLiteral.optimalInteger(-1000, Position.DUMMY).number shouldBe -1000.0
NumericLiteral.optimalInteger(1000u, Position.DUMMY).type shouldBe DataType.UWORD
NumericLiteral.optimalInteger(1000u, Position.DUMMY).number shouldBe 1000.0
}
test("optimalNumeric") {
NumericLiteral.optimalNumeric(10, Position.DUMMY).type shouldBe DataType.UBYTE
NumericLiteral.optimalNumeric(10, Position.DUMMY).number shouldBe 10.0
NumericLiteral.optimalNumeric(-10, Position.DUMMY).type shouldBe DataType.BYTE
NumericLiteral.optimalNumeric(-10, Position.DUMMY).number shouldBe -10.0
NumericLiteral.optimalNumeric(1000, Position.DUMMY).type shouldBe DataType.UWORD
NumericLiteral.optimalNumeric(1000, Position.DUMMY).number shouldBe 1000.0
NumericLiteral.optimalNumeric(-1000, Position.DUMMY).type shouldBe DataType.WORD
NumericLiteral.optimalNumeric(-1000, Position.DUMMY).number shouldBe -1000.0
NumericLiteral.optimalNumeric(1.123, Position.DUMMY).type shouldBe DataType.FLOAT
NumericLiteral.optimalNumeric(1.123, Position.DUMMY).number shouldBe 1.123
NumericLiteral.optimalNumeric(1.0, Position.DUMMY).type shouldBe DataType.UBYTE
NumericLiteral.optimalNumeric(1.0, Position.DUMMY).number shouldBe 1.0
NumericLiteral.optimalNumeric(-1.0, Position.DUMMY).type shouldBe DataType.BYTE
NumericLiteral.optimalNumeric(-1.0, Position.DUMMY).number shouldBe -1.0
NumericLiteral.optimalNumeric(1234.0, Position.DUMMY).type shouldBe DataType.UWORD
NumericLiteral.optimalNumeric(1234.0, Position.DUMMY).number shouldBe 1234.0
NumericLiteral.optimalNumeric(-1234.0, Position.DUMMY).type shouldBe DataType.WORD
NumericLiteral.optimalNumeric(-1234.0, Position.DUMMY).number shouldBe -1234.0
}
})

View File

@ -13,6 +13,7 @@ import prog8.ast.walk.IAstVisitor
import prog8.code.core.*
import java.util.*
import kotlin.math.abs
import kotlin.math.floor
import kotlin.math.round
@ -446,7 +447,8 @@ class NumericLiteral(val type: DataType, // only numerical types allowed
NumericLiteral(DataType.UBYTE, if (bool) 1.0 else 0.0, position)
fun optimalNumeric(value: Number, position: Position): NumericLiteral {
return if(value is Double) {
val digits = floor(value.toDouble()) - value.toDouble()
return if(value is Double && digits!=0.0) {
NumericLiteral(DataType.FLOAT, value, position)
} else {
val dvalue = value.toDouble()

View File

@ -3,7 +3,6 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- fix natt's bug: ubyte - 2 + 10 somehow gets promoted to byte?
- optimize pointervar indexing codegen: make them work as subroutine paramers
- optimize pointervar indexing codegen: writing (all sorts of things)
- pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target.

View File

@ -31,75 +31,78 @@ main {
sub start() {
; mcCarthy()
uword uw = -2
ubyte ub = -2
uw = -2 as uword
ub = -2 as ubyte
txt.print_uw(uw)
uword uw1 = 9999
uword uw2 = uw1 - 2000 + 10000
ubyte ub1 = 99
ubyte ub2 = ub1 - 2 + 10
ubyte ubb = ub2 - -10
txt.print_uw(uw2)
txt.spc()
txt.print_ub(ub)
txt.print_ub(ub2)
txt.spc()
txt.print_ub(ubb)
txt.nl()
;test_stack.test()
ubyte value = 0
ubyte one = 1
ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
uword bitmapbuf = &data
value = bitmapbuf[2]
txt.print_ub(value) ;; 33
txt.nl()
; 11 22 33
txt.print_ub(bitmapbuf[0])
txt.spc()
txt.print_ub(bitmapbuf[1])
txt.spc()
txt.print_ub(bitmapbuf[2])
txt.nl()
rol(bitmapbuf[0])
rol(bitmapbuf[0])
txt.print_ub(bitmapbuf[0]) ; 44
txt.spc()
ror(bitmapbuf[0])
ror(bitmapbuf[0])
txt.print_ub(bitmapbuf[0]) ; 11
txt.nl()
; 22 44 66
txt.print_ub(bitmapbuf[0]*2)
txt.spc()
txt.print_ub(bitmapbuf[1]*2)
txt.spc()
txt.print_ub(bitmapbuf[2]*2)
txt.nl()
value = one+one+one+one+one
txt.print_ub(value) ; 5
txt.nl()
bitmapbuf[0] = one
bitmapbuf[1] = one+one
bitmapbuf[2] = one+one+one
bitmapbuf[2] += 4
bitmapbuf[2] -= 2
bitmapbuf[2] -= 2
swap(bitmapbuf[0], bitmapbuf[1])
; 2 1 3
txt.print_ub(bitmapbuf[0])
txt.spc()
txt.print_ub(bitmapbuf[1])
txt.spc()
txt.print_ub(bitmapbuf[2])
txt.nl()
for value in data {
txt.print_ub(value)
txt.spc()
}
txt.nl()
; ubyte value = 0
; ubyte one = 1
; ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
; uword bitmapbuf = &data
;
; value = bitmapbuf[2]
; txt.print_ub(value) ;; 33
; txt.nl()
;
; ; 11 22 33
; txt.print_ub(bitmapbuf[0])
; txt.spc()
; txt.print_ub(bitmapbuf[1])
; txt.spc()
; txt.print_ub(bitmapbuf[2])
; txt.nl()
; rol(bitmapbuf[0])
; rol(bitmapbuf[0])
; txt.print_ub(bitmapbuf[0]) ; 44
; txt.spc()
; ror(bitmapbuf[0])
; ror(bitmapbuf[0])
; txt.print_ub(bitmapbuf[0]) ; 11
; txt.nl()
;
; ; 22 44 66
; txt.print_ub(bitmapbuf[0]*2)
; txt.spc()
; txt.print_ub(bitmapbuf[1]*2)
; txt.spc()
; txt.print_ub(bitmapbuf[2]*2)
; txt.nl()
;
; value = one+one+one+one+one
; txt.print_ub(value) ; 5
; txt.nl()
;
; bitmapbuf[0] = one
; bitmapbuf[1] = one+one
; bitmapbuf[2] = one+one+one
; bitmapbuf[2] += 4
; bitmapbuf[2] -= 2
; bitmapbuf[2] -= 2
; swap(bitmapbuf[0], bitmapbuf[1])
;
; ; 2 1 3
; txt.print_ub(bitmapbuf[0])
; txt.spc()
; txt.print_ub(bitmapbuf[1])
; txt.spc()
; txt.print_ub(bitmapbuf[2])
; txt.nl()
;
; for value in data {
; txt.print_ub(value)
; txt.spc()
; }
; txt.nl()
;test_stack.test()