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) 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 leftBinExpr = expr.left as? BinaryExpression
val rightBinExpr = expr.right 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 (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 prog8.code.core.*
import java.util.* import java.util.*
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.floor
import kotlin.math.round 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) NumericLiteral(DataType.UBYTE, if (bool) 1.0 else 0.0, position)
fun optimalNumeric(value: Number, position: Position): NumericLiteral { 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) NumericLiteral(DataType.FLOAT, value, position)
} else { } else {
val dvalue = value.toDouble() val dvalue = value.toDouble()

View File

@ -3,7 +3,6 @@ TODO
For next release 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: make them work as subroutine paramers
- optimize pointervar indexing codegen: writing (all sorts of things) - 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. - 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() { sub start() {
; mcCarthy() ; mcCarthy()
uword uw = -2 uword uw1 = 9999
ubyte ub = -2 uword uw2 = uw1 - 2000 + 10000
uw = -2 as uword ubyte ub1 = 99
ub = -2 as ubyte ubyte ub2 = ub1 - 2 + 10
txt.print_uw(uw) ubyte ubb = ub2 - -10
txt.print_uw(uw2)
txt.spc() txt.spc()
txt.print_ub(ub) txt.print_ub(ub2)
txt.spc()
txt.print_ub(ubb)
txt.nl() txt.nl()
;test_stack.test() ;test_stack.test()
ubyte value = 0 ; ubyte value = 0
ubyte one = 1 ; ubyte one = 1
ubyte[10] data = [11,22,33,4,5,6,7,8,9,10] ; ubyte[10] data = [11,22,33,4,5,6,7,8,9,10]
uword bitmapbuf = &data ; uword bitmapbuf = &data
;
value = bitmapbuf[2] ; value = bitmapbuf[2]
txt.print_ub(value) ;; 33 ; txt.print_ub(value) ;; 33
txt.nl() ; txt.nl()
;
; 11 22 33 ; ; 11 22 33
txt.print_ub(bitmapbuf[0]) ; txt.print_ub(bitmapbuf[0])
txt.spc() ; txt.spc()
txt.print_ub(bitmapbuf[1]) ; txt.print_ub(bitmapbuf[1])
txt.spc() ; txt.spc()
txt.print_ub(bitmapbuf[2]) ; txt.print_ub(bitmapbuf[2])
txt.nl() ; txt.nl()
rol(bitmapbuf[0]) ; rol(bitmapbuf[0])
rol(bitmapbuf[0]) ; rol(bitmapbuf[0])
txt.print_ub(bitmapbuf[0]) ; 44 ; txt.print_ub(bitmapbuf[0]) ; 44
txt.spc() ; txt.spc()
ror(bitmapbuf[0]) ; ror(bitmapbuf[0])
ror(bitmapbuf[0]) ; ror(bitmapbuf[0])
txt.print_ub(bitmapbuf[0]) ; 11 ; txt.print_ub(bitmapbuf[0]) ; 11
txt.nl() ; txt.nl()
;
; 22 44 66 ; ; 22 44 66
txt.print_ub(bitmapbuf[0]*2) ; txt.print_ub(bitmapbuf[0]*2)
txt.spc() ; txt.spc()
txt.print_ub(bitmapbuf[1]*2) ; txt.print_ub(bitmapbuf[1]*2)
txt.spc() ; txt.spc()
txt.print_ub(bitmapbuf[2]*2) ; txt.print_ub(bitmapbuf[2]*2)
txt.nl() ; txt.nl()
;
value = one+one+one+one+one ; value = one+one+one+one+one
txt.print_ub(value) ; 5 ; txt.print_ub(value) ; 5
txt.nl() ; txt.nl()
;
bitmapbuf[0] = one ; bitmapbuf[0] = one
bitmapbuf[1] = one+one ; bitmapbuf[1] = one+one
bitmapbuf[2] = one+one+one ; bitmapbuf[2] = one+one+one
bitmapbuf[2] += 4 ; bitmapbuf[2] += 4
bitmapbuf[2] -= 2 ; bitmapbuf[2] -= 2
bitmapbuf[2] -= 2 ; bitmapbuf[2] -= 2
swap(bitmapbuf[0], bitmapbuf[1]) ; swap(bitmapbuf[0], bitmapbuf[1])
;
; 2 1 3 ; ; 2 1 3
txt.print_ub(bitmapbuf[0]) ; txt.print_ub(bitmapbuf[0])
txt.spc() ; txt.spc()
txt.print_ub(bitmapbuf[1]) ; txt.print_ub(bitmapbuf[1])
txt.spc() ; txt.spc()
txt.print_ub(bitmapbuf[2]) ; txt.print_ub(bitmapbuf[2])
txt.nl() ; txt.nl()
;
for value in data { ; for value in data {
txt.print_ub(value) ; txt.print_ub(value)
txt.spc() ; txt.spc()
} ; }
txt.nl() ; txt.nl()
;test_stack.test() ;test_stack.test()