mirror of
https://github.com/irmen/prog8.git
synced 2025-02-19 11:31:07 +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
|
val booleanCondition = stmt.condition as BinaryExpression
|
||||||
|
|
||||||
if (stmt.elsepart.isEmpty()) {
|
if (stmt.elsepart.isEmpty()) {
|
||||||
// TODO specialize this
|
if(stmt.truepart.statements.singleOrNull() is Jump) {
|
||||||
// if(stmt.truepart.statements.singleOrNull() is Jump) {
|
translateCompareAndJumpIfTrue(booleanCondition, stmt.truepart.statements[0] as Jump)
|
||||||
// translateCompareAndJumpIfTrue(booleanCondition, stmt.truepart.statements[0] as Jump)
|
} else {
|
||||||
// } else {
|
|
||||||
val endLabel = makeLabel("if_end")
|
val endLabel = makeLabel("if_end")
|
||||||
translateCompareAndJumpIfFalse(booleanCondition, endLabel)
|
translateCompareAndJumpIfFalse(booleanCondition, endLabel)
|
||||||
translate(stmt.truepart)
|
translate(stmt.truepart)
|
||||||
out(endLabel)
|
out(endLabel)
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// both true and else parts
|
// both true and else parts
|
||||||
@ -1613,16 +1612,29 @@ $label nop""")
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translateCompareAndJumpIfTrue(expr: BinaryExpression, jump: Jump) {
|
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 left = expr.left
|
||||||
val right = expr.right
|
val right = expr.right
|
||||||
val operator = expr.operator
|
|
||||||
val leftConstVal = left.constValue(program)
|
|
||||||
val rightConstVal = right.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)
|
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
||||||
testZeroAndJump(left, operator, jump, null)
|
testZeroAndJump(left, invertedComparisonOperator, label)
|
||||||
else
|
else {
|
||||||
testNonzeroComparisonAndJump(left, operator, right, jump, null, leftConstVal, rightConstVal)
|
val leftConstVal = left.constValue(program)
|
||||||
|
testNonzeroComparisonAndJump(left, invertedComparisonOperator, right, label, leftConstVal, rightConstVal)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translateCompareAndJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) {
|
private fun translateCompareAndJumpIfFalse(expr: BinaryExpression, jumpIfFalseLabel: String) {
|
||||||
@ -1633,18 +1645,16 @@ $label nop""")
|
|||||||
val rightConstVal = right.constValue(program)
|
val rightConstVal = right.constValue(program)
|
||||||
|
|
||||||
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
if (rightConstVal!=null && rightConstVal.number == 0.0)
|
||||||
testZeroAndJump(left, operator, null, jumpIfFalseLabel)
|
testZeroAndJump(left, operator, jumpIfFalseLabel)
|
||||||
else
|
else
|
||||||
testNonzeroComparisonAndJump(left, operator, right, null, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
testNonzeroComparisonAndJump(left, operator, right, jumpIfFalseLabel, leftConstVal, rightConstVal)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testZeroAndJump(
|
private fun testZeroAndJump(
|
||||||
left: Expression,
|
left: Expression,
|
||||||
operator: String,
|
operator: String,
|
||||||
jumpIfTrue: Jump?,
|
jumpIfFalseLabel: String
|
||||||
jumpIfFalseLabel: String?
|
|
||||||
) {
|
) {
|
||||||
require(jumpIfTrue!=null || jumpIfFalseLabel!=null)
|
|
||||||
when(val dt = left.inferType(program).getOr(DataType.UNDEFINED)) {
|
when(val dt = left.inferType(program).getOr(DataType.UNDEFINED)) {
|
||||||
DataType.UBYTE, DataType.UWORD -> {
|
DataType.UBYTE, DataType.UWORD -> {
|
||||||
if(operator=="<") {
|
if(operator=="<") {
|
||||||
@ -1733,16 +1743,12 @@ $label nop""")
|
|||||||
left: Expression,
|
left: Expression,
|
||||||
operator: String,
|
operator: String,
|
||||||
right: Expression,
|
right: Expression,
|
||||||
jumpIfTrue: Jump?,
|
jumpIfFalseLabel: String,
|
||||||
jumpIfFalseLabel: String?,
|
|
||||||
leftConstVal: NumericLiteralValue?,
|
leftConstVal: NumericLiteralValue?,
|
||||||
rightConstVal: NumericLiteralValue?
|
rightConstVal: NumericLiteralValue?
|
||||||
) {
|
) {
|
||||||
require(jumpIfTrue!=null || jumpIfFalseLabel!=null)
|
|
||||||
val dt = left.inferType(program).getOrElse { throw AssemblyError("unknown dt") }
|
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 (operator) {
|
||||||
"==" -> {
|
"==" -> {
|
||||||
when (dt) {
|
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?)
|
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.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.compilerinterface.IErrorReporter
|
import prog8.compilerinterface.IErrorReporter
|
||||||
import prog8.optimizer.invertedComparisonOperator
|
|
||||||
|
|
||||||
|
|
||||||
internal class VariousCleanups(val program: Program, val errors: IErrorReporter): AstWalker() {
|
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 LogicalOperators = setOf("and", "or", "xor", "not")
|
||||||
val BitwiseOperators = setOf("&", "|", "^")
|
val BitwiseOperators = setOf("&", "|", "^")
|
||||||
|
|
||||||
|
fun invertedComparisonOperator(operator: String) =
|
||||||
|
when (operator) {
|
||||||
|
"==" -> "!="
|
||||||
|
"!=" -> "=="
|
||||||
|
"<" -> ">="
|
||||||
|
">" -> "<="
|
||||||
|
"<=" -> ">"
|
||||||
|
">=" -> "<"
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
sealed class Expression: Node {
|
sealed class Expression: Node {
|
||||||
abstract override fun copy(): Expression
|
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)
|
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
|
Blocked by an official Commander-x16 v39 release
|
||||||
|
Loading…
x
Reference in New Issue
Block a user