mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 23:29:55 +00:00
simplify expressions
This commit is contained in:
parent
c0920a43a3
commit
b8251b2e26
@ -3188,10 +3188,10 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
"""
|
"""
|
||||||
},
|
},
|
||||||
|
|
||||||
// more efficient versions of x+1 and x-1 to avoid pushing the 1 on the stack @todo what about 1+x? reorder? what about x+ (-1) and x-(-1)? is that rewritten already?
|
// more efficient versions of x+1 and x-1 to avoid pushing the 1 on the stack @todo what about 1+x? reorder?
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.ADD_B), listOf(Opcode.PUSH_BYTE, Opcode.ADD_UB)) { segment ->
|
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.ADD_B), listOf(Opcode.PUSH_BYTE, Opcode.ADD_UB)) { segment ->
|
||||||
val amount = segment[0].arg!!.integerValue()
|
val amount = segment[0].arg!!.integerValue()
|
||||||
if(amount in 1..8) {
|
if(amount in 1..2) {
|
||||||
" inc ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
" inc ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3199,7 +3199,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
},
|
},
|
||||||
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.ADD_UW), listOf(Opcode.PUSH_WORD, Opcode.ADD_W)) { segment ->
|
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.ADD_UW), listOf(Opcode.PUSH_WORD, Opcode.ADD_W)) { segment ->
|
||||||
val amount = segment[0].arg!!.integerValue()
|
val amount = segment[0].arg!!.integerValue()
|
||||||
if(amount in 1..8) {
|
if(amount in 1..2) {
|
||||||
" inc ${(ESTACK_LO + 1).toHex()},x | bne + | inc ${(ESTACK_HI + 1).toHex()},x |+ | ".repeat(amount)
|
" inc ${(ESTACK_LO + 1).toHex()},x | bne + | inc ${(ESTACK_HI + 1).toHex()},x |+ | ".repeat(amount)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3207,7 +3207,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
},
|
},
|
||||||
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.SUB_B), listOf(Opcode.PUSH_BYTE, Opcode.SUB_UB)) { segment ->
|
AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.SUB_B), listOf(Opcode.PUSH_BYTE, Opcode.SUB_UB)) { segment ->
|
||||||
val amount = segment[0].arg!!.integerValue()
|
val amount = segment[0].arg!!.integerValue()
|
||||||
if(amount in 1..8) {
|
if(amount in 1..2) {
|
||||||
" dec ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
" dec ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3215,7 +3215,7 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram,
|
|||||||
},
|
},
|
||||||
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.SUB_UW), listOf(Opcode.PUSH_WORD, Opcode.SUB_W)) { segment ->
|
AsmPattern(listOf(Opcode.PUSH_WORD, Opcode.SUB_UW), listOf(Opcode.PUSH_WORD, Opcode.SUB_W)) { segment ->
|
||||||
val amount = segment[0].arg!!.integerValue()
|
val amount = segment[0].arg!!.integerValue()
|
||||||
if(amount in 1..8) {
|
if(amount in 1..2) {
|
||||||
" lda ${(ESTACK_LO + 1).toHex()},x | bne + | dec ${(ESTACK_HI + 1).toHex()},x |+ | dec ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
" lda ${(ESTACK_LO + 1).toHex()},x | bne + | dec ${(ESTACK_HI + 1).toHex()},x |+ | dec ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -8,11 +8,10 @@ import kotlin.math.log2
|
|||||||
/*
|
/*
|
||||||
todo simplify expression terms:
|
todo simplify expression terms:
|
||||||
|
|
||||||
X*Y - X -> X*(Y-1)
|
X*Y - X -> X*(Y-1) ???
|
||||||
X*Y - Y -> Y*(X-1)
|
Y*X - X -> X*(Y-1) ???
|
||||||
-X + A -> A - X
|
|
||||||
X+ (-A) -> X - A
|
value <associative_operator> X --> X <associative_operator> value <<<<< should be done already
|
||||||
X- (-A) -> X + A
|
|
||||||
|
|
||||||
|
|
||||||
todo expression optimization: common (sub) expression elimination (turn common expressions into single subroutine call + introduce variable to hold it)
|
todo expression optimization: common (sub) expression elimination (turn common expressions into single subroutine call + introduce variable to hold it)
|
||||||
@ -28,6 +27,15 @@ class SimplifyExpressions(private val namespace: INameScope, private val heap: H
|
|||||||
return super.process(assignment)
|
return super.process(assignment)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun process(expr: PrefixExpression): IExpression {
|
||||||
|
if(expr.operator == "+") {
|
||||||
|
// +X --> X
|
||||||
|
optimizationsDone++
|
||||||
|
return expr.expression.process(this)
|
||||||
|
}
|
||||||
|
return super.process(expr)
|
||||||
|
}
|
||||||
|
|
||||||
override fun process(expr: BinaryExpression): IExpression {
|
override fun process(expr: BinaryExpression): IExpression {
|
||||||
super.process(expr)
|
super.process(expr)
|
||||||
val leftVal = expr.left.constValue(namespace, heap)
|
val leftVal = expr.left.constValue(namespace, heap)
|
||||||
@ -45,6 +53,74 @@ class SimplifyExpressions(private val namespace: INameScope, private val heap: H
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Value <associativeoperator> X --> X <associativeoperator> Value
|
||||||
|
if(leftVal!=null && expr.operator in associativeOperators && rightVal==null) {
|
||||||
|
val tmp = expr.left
|
||||||
|
expr.left = expr.right
|
||||||
|
expr.right = tmp
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
|
||||||
|
// X + (-A) --> X - A
|
||||||
|
if(expr.operator=="+" && (expr.right as? PrefixExpression)?.operator=="-") {
|
||||||
|
expr.operator = "-"
|
||||||
|
expr.right = (expr.right as PrefixExpression).expression
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
|
||||||
|
// (-A) + X --> X - A
|
||||||
|
if(expr.operator=="+" && (expr.left as? PrefixExpression)?.operator=="-") {
|
||||||
|
expr.operator = "-"
|
||||||
|
val newRight = (expr.left as PrefixExpression).expression
|
||||||
|
expr.left = expr.right
|
||||||
|
expr.right = newRight
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
|
||||||
|
// X + (-value) --> X - value
|
||||||
|
if(expr.operator=="+" && rightVal!=null) {
|
||||||
|
val rv = rightVal.asNumericValue?.toDouble()
|
||||||
|
if(rv!=null && rv<0.0) {
|
||||||
|
expr.operator = "-"
|
||||||
|
expr.right = LiteralValue.fromNumber(-rv, rightVal.type, rightVal.position)
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// (-value) + X --> X - value
|
||||||
|
if(expr.operator=="+" && leftVal!=null) {
|
||||||
|
val lv = leftVal.asNumericValue?.toDouble()
|
||||||
|
if(lv!=null && lv<0.0) {
|
||||||
|
expr.operator = "-"
|
||||||
|
expr.right = LiteralValue.fromNumber(-lv, leftVal.type, leftVal.position)
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// X - (-A) --> X + A
|
||||||
|
if(expr.operator=="-" && (expr.right as? PrefixExpression)?.operator=="-") {
|
||||||
|
expr.operator = "+"
|
||||||
|
expr.right = (expr.right as PrefixExpression).expression
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
|
||||||
|
// X - (-value) --> X + value
|
||||||
|
if(expr.operator=="-" && rightVal!=null) {
|
||||||
|
val rv = rightVal.asNumericValue?.toDouble()
|
||||||
|
if(rv!=null && rv<0.0) {
|
||||||
|
expr.operator = "+"
|
||||||
|
expr.right = LiteralValue.fromNumber(-rv, rightVal.type, rightVal.position)
|
||||||
|
optimizationsDone++
|
||||||
|
return expr
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// simplify when a term is constant and determines the outcome
|
// simplify when a term is constant and determines the outcome
|
||||||
when(expr.operator) {
|
when(expr.operator) {
|
||||||
"or" -> {
|
"or" -> {
|
||||||
@ -204,6 +280,8 @@ class SimplifyExpressions(private val namespace: INameScope, private val heap: H
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// todo: get rid of this?
|
||||||
private data class ReorderedAssociativeBinaryExpr(val expr: BinaryExpression, val leftVal: LiteralValue?, val rightVal: LiteralValue?)
|
private data class ReorderedAssociativeBinaryExpr(val expr: BinaryExpression, val leftVal: LiteralValue?, val rightVal: LiteralValue?)
|
||||||
|
|
||||||
private fun reorderAssociative(expr: BinaryExpression, leftVal: LiteralValue?): ReorderedAssociativeBinaryExpr {
|
private fun reorderAssociative(expr: BinaryExpression, leftVal: LiteralValue?): ReorderedAssociativeBinaryExpr {
|
||||||
|
@ -183,14 +183,16 @@ class StatementOptimizer(private val namespace: INameScope, private val heap: He
|
|||||||
|
|
||||||
// remove assignments that have no effect X=X , X+=0, X-=0, X*=1, X/=1, X//=1, A |= 0, A ^= 0, A<<=0, etc etc
|
// remove assignments that have no effect X=X , X+=0, X-=0, X*=1, X/=1, X//=1, A |= 0, A ^= 0, A<<=0, etc etc
|
||||||
// A = A <operator> B
|
// A = A <operator> B
|
||||||
|
val vardeclDt = (target.identifier?.targetStatement(namespace) as? VarDecl)?.type
|
||||||
|
|
||||||
when (bexpr.operator) {
|
when (bexpr.operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
if (cv == 0.0) {
|
if (cv == 0.0) {
|
||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
return NopStatement(assignment.position)
|
return NopStatement(assignment.position)
|
||||||
} else if (cv in 1.0..8.0 && targetDt in IntegerDatatypes && floor(cv) == cv) {
|
} else if (targetDt in IntegerDatatypes && floor(cv) == cv) {
|
||||||
// replace by several INCs
|
if((vardeclDt == VarDeclType.MEMORY && cv in 1.0..3.0) || (vardeclDt!=VarDeclType.MEMORY && cv in 1.0..8.0)) {
|
||||||
|
// replace by several INCs (a bit less when dealing with memory targets)
|
||||||
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
||||||
repeat(cv.toInt()) {
|
repeat(cv.toInt()) {
|
||||||
decs.statements.add(PostIncrDecr(target, "++", assignment.position))
|
decs.statements.add(PostIncrDecr(target, "++", assignment.position))
|
||||||
@ -198,12 +200,14 @@ class StatementOptimizer(private val namespace: INameScope, private val heap: He
|
|||||||
return decs
|
return decs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
if (cv == 0.0) {
|
if (cv == 0.0) {
|
||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
return NopStatement(assignment.position)
|
return NopStatement(assignment.position)
|
||||||
} else if (cv in 1.0..8.0 && targetDt in IntegerDatatypes && floor(cv) == cv) {
|
} else if (targetDt in IntegerDatatypes && floor(cv) == cv) {
|
||||||
// replace by several DECs
|
if((vardeclDt == VarDeclType.MEMORY && cv in 1.0..3.0) || (vardeclDt!=VarDeclType.MEMORY && cv in 1.0..8.0)) {
|
||||||
|
// replace by several DECs (a bit less when dealing with memory targets)
|
||||||
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
||||||
repeat(cv.toInt()) {
|
repeat(cv.toInt()) {
|
||||||
decs.statements.add(PostIncrDecr(target, "--", assignment.position))
|
decs.statements.add(PostIncrDecr(target, "--", assignment.position))
|
||||||
@ -211,6 +215,7 @@ class StatementOptimizer(private val namespace: INameScope, private val heap: He
|
|||||||
return decs
|
return decs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
"*" -> if (cv == 1.0) {
|
"*" -> if (cv == 1.0) {
|
||||||
optimizationsDone++
|
optimizationsDone++
|
||||||
return NopStatement(assignment.position)
|
return NopStatement(assignment.position)
|
||||||
|
@ -16,14 +16,20 @@
|
|||||||
float f1 = 1.1
|
float f1 = 1.1
|
||||||
float f2 = 2.2
|
float f2 = 2.2
|
||||||
|
|
||||||
i %= 1
|
b2 = j + (-1)
|
||||||
i %= 2
|
b2 = (-1) + j
|
||||||
ub2 = i % 1
|
b2 = j - (-1)
|
||||||
ub2 = i % 2
|
b2 = (-1) -j ; should not be reordered
|
||||||
|
b2 = j+1
|
||||||
|
b2 = 1+j
|
||||||
|
b2 = 1-j ; should not be reordered
|
||||||
|
|
||||||
uw %= 1
|
j = j + (-1)
|
||||||
uw %= 2
|
j = (-1) + j
|
||||||
uw2 = uw % 1
|
j = j - (-1)
|
||||||
uw2 = uw % 2
|
j = (-1) -j ; should not be reordered
|
||||||
|
j = j+1
|
||||||
|
j = 1+j
|
||||||
|
j = 1-j ; should not be reordered
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user