mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +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 ->
|
||||
val amount = segment[0].arg!!.integerValue()
|
||||
if(amount in 1..8) {
|
||||
if(amount in 1..2) {
|
||||
" inc ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
||||
}
|
||||
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 ->
|
||||
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)
|
||||
}
|
||||
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 ->
|
||||
val amount = segment[0].arg!!.integerValue()
|
||||
if(amount in 1..8) {
|
||||
if(amount in 1..2) {
|
||||
" dec ${(ESTACK_LO + 1).toHex()},x | ".repeat(amount)
|
||||
}
|
||||
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 ->
|
||||
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)
|
||||
}
|
||||
else
|
||||
|
@ -8,11 +8,10 @@ import kotlin.math.log2
|
||||
/*
|
||||
todo simplify expression terms:
|
||||
|
||||
X*Y - X -> X*(Y-1)
|
||||
X*Y - Y -> Y*(X-1)
|
||||
-X + A -> A - X
|
||||
X+ (-A) -> X - A
|
||||
X- (-A) -> X + A
|
||||
X*Y - X -> X*(Y-1) ???
|
||||
Y*X - X -> X*(Y-1) ???
|
||||
|
||||
value <associative_operator> X --> X <associative_operator> value <<<<< should be done already
|
||||
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
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 {
|
||||
super.process(expr)
|
||||
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
|
||||
when(expr.operator) {
|
||||
"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 fun reorderAssociative(expr: BinaryExpression, leftVal: LiteralValue?): ReorderedAssociativeBinaryExpr {
|
||||
|
@ -183,32 +183,37 @@ 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
|
||||
// A = A <operator> B
|
||||
val vardeclDt = (target.identifier?.targetStatement(namespace) as? VarDecl)?.type
|
||||
|
||||
when (bexpr.operator) {
|
||||
"+" -> {
|
||||
if (cv == 0.0) {
|
||||
optimizationsDone++
|
||||
return NopStatement(assignment.position)
|
||||
} else if (cv in 1.0..8.0 && targetDt in IntegerDatatypes && floor(cv) == cv) {
|
||||
// replace by several INCs
|
||||
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
||||
repeat(cv.toInt()) {
|
||||
decs.statements.add(PostIncrDecr(target, "++", assignment.position))
|
||||
} else if (targetDt in IntegerDatatypes && floor(cv) == cv) {
|
||||
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)
|
||||
repeat(cv.toInt()) {
|
||||
decs.statements.add(PostIncrDecr(target, "++", assignment.position))
|
||||
}
|
||||
return decs
|
||||
}
|
||||
return decs
|
||||
}
|
||||
}
|
||||
"-" -> {
|
||||
if (cv == 0.0) {
|
||||
optimizationsDone++
|
||||
return NopStatement(assignment.position)
|
||||
} else if (cv in 1.0..8.0 && targetDt in IntegerDatatypes && floor(cv) == cv) {
|
||||
// replace by several DECs
|
||||
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
||||
repeat(cv.toInt()) {
|
||||
decs.statements.add(PostIncrDecr(target, "--", assignment.position))
|
||||
} else if (targetDt in IntegerDatatypes && floor(cv) == cv) {
|
||||
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)
|
||||
repeat(cv.toInt()) {
|
||||
decs.statements.add(PostIncrDecr(target, "--", assignment.position))
|
||||
}
|
||||
return decs
|
||||
}
|
||||
return decs
|
||||
}
|
||||
}
|
||||
"*" -> if (cv == 1.0) {
|
||||
|
@ -16,14 +16,20 @@
|
||||
float f1 = 1.1
|
||||
float f2 = 2.2
|
||||
|
||||
i %= 1
|
||||
i %= 2
|
||||
ub2 = i % 1
|
||||
ub2 = i % 2
|
||||
b2 = j + (-1)
|
||||
b2 = (-1) + j
|
||||
b2 = j - (-1)
|
||||
b2 = (-1) -j ; should not be reordered
|
||||
b2 = j+1
|
||||
b2 = 1+j
|
||||
b2 = 1-j ; should not be reordered
|
||||
|
||||
uw %= 1
|
||||
uw %= 2
|
||||
uw2 = uw % 1
|
||||
uw2 = uw % 2
|
||||
j = j + (-1)
|
||||
j = (-1) + j
|
||||
j = j - (-1)
|
||||
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