mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 22:30:46 +00:00
optimized if-goto codegeneration
This commit is contained in:
parent
97e84d0977
commit
1c7c4fc3b0
@ -1098,15 +1098,14 @@ class AsmGen(private val program: Program,
|
||||
val booleanCondition = stmt.condition as BinaryExpression
|
||||
|
||||
if (stmt.elsepart.isEmpty()) {
|
||||
// TODO specialize this
|
||||
// if(stmt.truepart.statements.singleOrNull() is Jump) {
|
||||
// translateCompareAndJumpIfTrue(booleanCondition, stmt.truepart.statements[0] as Jump)
|
||||
// } else {
|
||||
if(stmt.truepart.statements.singleOrNull() is Jump) {
|
||||
translateCompareAndJumpIfTrue(booleanCondition, stmt.truepart.statements[0] as Jump)
|
||||
} else {
|
||||
val endLabel = makeLabel("if_end")
|
||||
translateCompareAndJumpIfFalse(booleanCondition, endLabel)
|
||||
translate(stmt.truepart)
|
||||
out(endLabel)
|
||||
// }
|
||||
}
|
||||
}
|
||||
else {
|
||||
// both true and else parts
|
||||
@ -1613,16 +1612,29 @@ $label nop""")
|
||||
}
|
||||
|
||||
private fun translateCompareAndJumpIfTrue(expr: BinaryExpression, jump: Jump) {
|
||||
if(expr.operator !in ComparisonOperators)
|
||||
throw AssemblyError("must be comparison expression")
|
||||
|
||||
// invert the comparison, so we can reuse the JumpIfFalse code generation routines
|
||||
val invertedComparisonOperator = invertedComparisonOperator(expr.operator)
|
||||
?: throw AssemblyError("can't invert comparison $expr")
|
||||
|
||||
val left = expr.left
|
||||
val right = expr.right
|
||||
val operator = expr.operator
|
||||
val leftConstVal = left.constValue(program)
|
||||
val rightConstVal = right.constValue(program)
|
||||
|
||||
val label = when {
|
||||
jump.generatedLabel!=null -> jump.generatedLabel!!
|
||||
jump.identifier!=null -> asmSymbolName(jump.identifier!!)
|
||||
jump.address!=null -> jump.address!!.toHex()
|
||||
else -> throw AssemblyError("weird jump")
|
||||
}
|
||||
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
||||
testZeroAndJump(left, operator, jump, null)
|
||||
else
|
||||
testNonzeroComparisonAndJump(left, operator, right, jump, null, leftConstVal, rightConstVal)
|
||||
testZeroAndJump(left, invertedComparisonOperator, label)
|
||||
else {
|
||||
val leftConstVal = left.constValue(program)
|
||||
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
||||
}
|
||||
}
|
||||
|
||||
private fun translateCompareAndJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) {
|
||||
@ -1633,18 +1645,16 @@ $label nop""")
|
||||
val rightConstVal = right.constValue(program)
|
||||
|
||||
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
||||
testZeroAndJump(left, operator, null, jumpIfFalseLabel)
|
||||
testZeroAndJump(left, operator, jumpIfFalseLabel)
|
||||
else
|
||||
testNonzeroComparisonAndJump(left, operator, right, null, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
||||
testNonzeroComparisonAndJump(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
||||
}
|
||||
|
||||
private fun testZeroAndJump(
|
||||
left: Expression,
|
||||
operator: String,
|
||||
jumpIfTrue: Jump?,
|
||||
jumpIfFalseLabel: String?
|
||||
jumpIfFalseLabel: String
|
||||
) {
|
||||
require(jumpIfTrue!=null || jumpIfFalseLabel!=null)
|
||||
when(val dt = left.inferType(program).getOr(DataType.UNDEFINED)) {
|
||||
DataType.UBYTE, DataType.UWORD -> {
|
||||
if(operator=="<") {
|
||||
@ -1733,16 +1743,12 @@ $label nop""")
|
||||
left: Expression,
|
||||
operator: String,
|
||||
right: Expression,
|
||||
jumpIfTrue: Jump?,
|
||||
jumpIfFalseLabel: String?,
|
||||
jumpIfFalseLabel: String,
|
||||
leftConstVal: NumericLiteralValue?,
|
||||
rightConstVal: NumericLiteralValue?
|
||||
) {
|
||||
require(jumpIfTrue!=null || jumpIfFalseLabel!=null)
|
||||
val dt = left.inferType(program).getOrElse { throw AssemblyError("unknown dt") }
|
||||
|
||||
jumpIfFalseLabel!! // TODO jump if true... or rewrite everything to use just jump-if-false
|
||||
|
||||
when (operator) {
|
||||
"==" -> {
|
||||
when (dt) {
|
||||
|
@ -724,25 +724,4 @@ class ExpressionSimplifier(private val program: Program) : AstWalker() {
|
||||
|
||||
private data class BinExprWithConstants(val expr: BinaryExpression, val leftVal: NumericLiteralValue?, val rightVal: NumericLiteralValue?)
|
||||
|
||||
}
|
||||
|
||||
|
||||
fun invertCondition(cond: Expression): BinaryExpression? {
|
||||
if(cond is BinaryExpression) {
|
||||
val invertedOperator = invertedComparisonOperator(cond.operator)
|
||||
if (invertedOperator != null)
|
||||
return BinaryExpression(cond.left, invertedOperator, cond.right, cond.position)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun invertedComparisonOperator(operator: String) =
|
||||
when (operator) {
|
||||
"==" -> "!="
|
||||
"!=" -> "=="
|
||||
"<" -> ">="
|
||||
">" -> "<="
|
||||
"<=" -> ">"
|
||||
">=" -> "<"
|
||||
else -> null
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.compilerinterface.IErrorReporter
|
||||
import prog8.optimizer.invertedComparisonOperator
|
||||
|
||||
|
||||
internal class VariousCleanups(val program: Program, val errors: IErrorReporter): AstWalker() {
|
||||
|
@ -15,6 +15,17 @@ val AugmentAssignmentOperators = setOf("+", "-", "/", "*", "**", "&", "|", "^",
|
||||
val LogicalOperators = setOf("and", "or", "xor", "not")
|
||||
val BitwiseOperators = setOf("&", "|", "^")
|
||||
|
||||
fun invertedComparisonOperator(operator: String) =
|
||||
when (operator) {
|
||||
"==" -> "!="
|
||||
"!=" -> "=="
|
||||
"<" -> ">="
|
||||
">" -> "<="
|
||||
"<=" -> ">"
|
||||
">=" -> "<"
|
||||
else -> null
|
||||
}
|
||||
|
||||
|
||||
sealed class Expression: Node {
|
||||
abstract override fun copy(): Expression
|
||||
@ -938,3 +949,13 @@ class FunctionCall(override var target: IdentifierReference,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun invertCondition(cond: Expression): BinaryExpression? {
|
||||
if(cond is BinaryExpression) {
|
||||
val invertedOperator = invertedComparisonOperator(cond.operator)
|
||||
if (invertedOperator != null)
|
||||
return BinaryExpression(cond.left, invertedOperator, cond.right, cond.position)
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
@ -3,7 +3,10 @@ TODO
|
||||
|
||||
For next compiler release (7.6)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
optimize ifs containing only a jump: reuse old code from AsmGen translateComparisonExpressionWithJumpIfFalse?
|
||||
fix imageviewer pcx decoding, broken since if/goto changes...
|
||||
also wormfood: worm freezes when you press fire...
|
||||
also petaxian: gameplay doesn't work at all anymore
|
||||
also textelite: after showing map, it just exits
|
||||
|
||||
|
||||
Blocked by an official Commander-x16 v39 release
|
||||
|
Loading…
x
Reference in New Issue
Block a user