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

View File

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

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 // 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)

View File

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