simplify expressions

This commit is contained in:
Irmen de Jong 2019-01-11 22:15:05 +01:00
parent c0920a43a3
commit b8251b2e26
4 changed files with 119 additions and 30 deletions

View File

@ -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

View File

@ -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 {

View File

@ -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
// 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
} 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))
@ -198,12 +200,14 @@ class StatementOptimizer(private val namespace: INameScope, private val heap: He
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
} 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))
@ -211,6 +215,7 @@ class StatementOptimizer(private val namespace: INameScope, private val heap: He
return decs
}
}
}
"*" -> if (cv == 1.0) {
optimizationsDone++
return NopStatement(assignment.position)

View File

@ -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
}
}