mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
preparing optimizations for if statements
This commit is contained in:
parent
0a03c46351
commit
319ac3a641
@ -1,6 +1,7 @@
|
||||
package prog8.compiler
|
||||
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.INameScope
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.*
|
||||
@ -183,7 +184,37 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: I
|
||||
val booleanExpr = BinaryExpression(ifStatement.condition, "!=", NumericLiteralValue.optimalInteger(0, ifStatement.condition.position), ifStatement.condition.position)
|
||||
return listOf(IAstModification.ReplaceNode(ifStatement.condition, booleanExpr, ifStatement))
|
||||
}
|
||||
|
||||
return noModifications
|
||||
// TODO split the conditional expression into separate variables if the operand(s) is not simple.
|
||||
// val modifications = mutableListOf<IAstModification>()
|
||||
// if(!binExpr.left.isSimple) {
|
||||
// val sub = binExpr.definingSubroutine()!!
|
||||
// val (variable, isNew, assignment) = addIfOperandVar(sub, "left", binExpr.left)
|
||||
// if(isNew)
|
||||
// modifications.add(IAstModification.InsertFirst(variable, sub))
|
||||
// modifications.add(IAstModification.InsertBefore(ifStatement, assignment, parent as INameScope))
|
||||
// modifications.add(IAstModification.ReplaceNode(binExpr.left, IdentifierReference(listOf(variable.name), binExpr.position), binExpr))
|
||||
// }
|
||||
// if(!binExpr.right.isSimple) {
|
||||
// val sub = binExpr.definingSubroutine()!!
|
||||
// val (variable, isNew, assignment) = addIfOperandVar(sub, "right", binExpr.right)
|
||||
// if(isNew)
|
||||
// modifications.add(IAstModification.InsertFirst(variable, sub))
|
||||
// modifications.add(IAstModification.InsertBefore(ifStatement, assignment, parent as INameScope))
|
||||
// modifications.add(IAstModification.ReplaceNode(binExpr.right, IdentifierReference(listOf(variable.name), binExpr.position), binExpr))
|
||||
// }
|
||||
// return modifications
|
||||
}
|
||||
|
||||
private fun addIfOperandVar(sub: Subroutine, side: String, operand: Expression): Triple<VarDecl, Boolean, Assignment> {
|
||||
val dt = operand.inferType(program).typeOrElse(DataType.STRUCT)
|
||||
val varname = "prog8_ifvar_${side}_${dt.name.toLowerCase()}"
|
||||
// TODO check occurrence in sub
|
||||
val vardecl = VarDecl(VarDeclType.VAR, dt, ZeropageWish.DONTCARE, null, varname, null, null, false, true, operand.position)
|
||||
val tgt = AssignTarget(IdentifierReference(listOf(varname), operand.position), null, null, operand.position)
|
||||
val assign = Assignment(tgt, operand, operand.position)
|
||||
return Triple(vardecl, true, assign)
|
||||
}
|
||||
|
||||
override fun after(untilLoop: UntilLoop, parent: Node): Iterable<IAstModification> {
|
||||
|
@ -17,7 +17,9 @@ internal fun Program.checkValid(compilerOptions: CompilationOptions, errors: IEr
|
||||
internal fun Program.processAstBeforeAsmGeneration(errors: IErrorReporter, compTarget: ICompilationTarget) {
|
||||
val fixer = BeforeAsmGenerationAstChanger(this, errors, compTarget)
|
||||
fixer.visit(this)
|
||||
fixer.applyModifications()
|
||||
while(errors.noErrors() && fixer.applyModifications()>0) {
|
||||
fixer.visit(this)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Program.reorderStatements(errors: IErrorReporter) {
|
||||
|
@ -931,6 +931,10 @@ internal class AsmGen(private val program: Program,
|
||||
checkBooleanExpression(stmt.condition) // we require the condition to be of the form 'x <comparison> <value>'
|
||||
val booleanCondition = stmt.condition as BinaryExpression
|
||||
|
||||
// TODO check this:
|
||||
// if(!booleanCondition.left.isSimple || !booleanCondition.right.isSimple)
|
||||
// throw AssemblyError("both operands for if comparison expression should have been simplified")
|
||||
|
||||
if (stmt.elsepart.containsNoCodeNorVars()) {
|
||||
// empty else
|
||||
val endLabel = makeLabel("if_end")
|
||||
|
@ -247,7 +247,7 @@ class ArrayIndexedExpression(var arrayvar: IdentifierReference,
|
||||
indexer.linkParents(this)
|
||||
}
|
||||
|
||||
override val isSimple = false
|
||||
override val isSimple = indexer.indexExpr is NumericLiteralValue || indexer.indexExpr is IdentifierReference
|
||||
|
||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||
when {
|
||||
|
@ -1,6 +1,10 @@
|
||||
====
|
||||
TODO
|
||||
====
|
||||
|
||||
- fix: cube3d is suddenly way bigger than it was a few changes ago
|
||||
|
||||
|
||||
- make sure that in if statements, the left and right operand of the comparison is never a complex expression
|
||||
anymore (only number, variable, addressof or memread) by rewriting if <left> <op> <right> {..} into:
|
||||
if_eval_left = left
|
||||
|
Loading…
x
Reference in New Issue
Block a user