diff --git a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt index bcec1345b..255f368cd 100644 --- a/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt +++ b/codeOptimizers/src/prog8/optimizer/BinExprSplitter.kt @@ -15,6 +15,7 @@ import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.code.core.CompilationOptions import prog8.code.core.DataType +import prog8.code.target.VMTarget class BinExprSplitter(private val program: Program, private val options: CompilationOptions) : AstWalker() { @@ -91,7 +92,7 @@ X = BinExpr X = LeftExpr val typecast = assignment.value as? TypecastExpression if(typecast!=null) { val origExpr = typecast.expression as? BinaryExpression - if(origExpr!=null) { + if(origExpr!=null && options.compTarget.name!=VMTarget.NAME) { // it's a typecast of a binary expression. // we can see if we can unwrap the binary expression by working on a new temporary variable // (that has the type of the expression), and then finally doing the typecast. diff --git a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt index 6ff193962..e36c81736 100644 --- a/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/StatementOptimizer.kt @@ -6,6 +6,8 @@ import prog8.ast.statements.* import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.code.core.* +import prog8.code.target.VMTarget +import prog8.code.target.virtual.VirtualMachineDefinition import kotlin.math.floor @@ -120,22 +122,23 @@ class StatementOptimizer(private val program: Program, return listOf(IAstModification.Remove(functionCallStatement, parent as IStatementContainer)) } - // see if we can optimize any complex argument expressions to be just a simple variable - // TODO for now, only works for single-argument functions because we use just 1 temp var: R9 - if(functionCallStatement.target.nameInSource !in listOf(listOf("pop"), listOf("popw")) && functionCallStatement.args.size==1) { - val arg = functionCallStatement.args[0] - if(!arg.isSimple && arg !is IFunctionCall) { - val name = getTempRegisterName(arg.inferType(program)) - val tempvar = IdentifierReference(name, functionCallStatement.position) - val assignTempvar = Assignment(AssignTarget(tempvar.copy(), null, null, functionCallStatement.position), arg, AssignmentOrigin.OPTIMIZER, functionCallStatement.position) - return listOf( - IAstModification.InsertBefore(functionCallStatement, assignTempvar, parent as IStatementContainer), - IAstModification.ReplaceNode(arg, tempvar, functionCallStatement) - ) + if(compTarget.name!=VMTarget.NAME) { + // see if we can optimize any complex argument expressions to be just a simple variable + // TODO for now, only works for single-argument functions because we use just 1 temp var: R9 + if(functionCallStatement.target.nameInSource !in listOf(listOf("pop"), listOf("popw")) && functionCallStatement.args.size==1) { + val arg = functionCallStatement.args[0] + if(!arg.isSimple && arg !is IFunctionCall) { + val name = getTempRegisterName(arg.inferType(program)) + val tempvar = IdentifierReference(name, functionCallStatement.position) + val assignTempvar = Assignment(AssignTarget(tempvar.copy(), null, null, functionCallStatement.position), arg, AssignmentOrigin.OPTIMIZER, functionCallStatement.position) + return listOf( + IAstModification.InsertBefore(functionCallStatement, assignTempvar, parent as IStatementContainer), + IAstModification.ReplaceNode(arg, tempvar, functionCallStatement) + ) + } } } - return noModifications } @@ -464,6 +467,10 @@ class StatementOptimizer(private val program: Program, } override fun after(returnStmt: Return, parent: Node): Iterable { + + if(compTarget.name==VMTarget.NAME) + return noModifications + fun returnViaIntermediaryVar(value: Expression): Iterable? { val subr = returnStmt.definingSubroutine!! val returnDt = subr.returntypes.single() diff --git a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt index 504616dd7..1f421bf3f 100644 --- a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt +++ b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt @@ -8,6 +8,7 @@ import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.ast.walk.IAstVisitor import prog8.code.core.* +import prog8.code.target.VMTarget internal class BeforeAsmAstChanger(val program: Program, private val options: CompilationOptions, @@ -224,6 +225,9 @@ internal class BeforeAsmAstChanger(val program: Program, // the actual conditional expression in the statement should be no more than VARIABLE SIMPLE-EXPRESSION // NOTE: do NOT move this to an earler ast transform phase (such as StatementReorderer or StatementOptimizer) - it WILL result in larger code. + if(options.compTarget.name==VMTarget.NAME) + return CondExprSimplificationResult(null, null, null, null) + var leftAssignment: Assignment? = null var leftOperandReplacement: Expression? = null var rightAssignment: Assignment? = null @@ -271,11 +275,12 @@ internal class BeforeAsmAstChanger(val program: Program, return noModifications } - - val index = arrayIndexedExpression.indexer.indexExpr - if(index !is NumericLiteral && index !is IdentifierReference) { - // replace complex indexing expression with a temp variable to hold the computed index first - return getAutoIndexerVarFor(arrayIndexedExpression) + if(options.compTarget.name!=VMTarget.NAME) { + val index = arrayIndexedExpression.indexer.indexExpr + if (index !is NumericLiteral && index !is IdentifierReference) { + // replace complex indexing expression with a temp variable to hold the computed index first + return getAutoIndexerVarFor(arrayIndexedExpression) + } } return noModifications diff --git a/docs/source/todo.rst b/docs/source/todo.rst index e5a8b9379..155511126 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- first for virtual target: do not create tempvars for return statements (StatementOptimizer) - maybe other places as well? - in new AST: combine param assignments + GoSub, back into PtFunctionCall node. PtGosub node should not exist. ... @@ -70,6 +68,10 @@ Expressions: Optimizations: +- various optimizers skip stuff if compTarget.name==VMTarget.NAME. Once (if?) 6502-codegen is no longer done from + the old CompilerAst, those checks should probably be removed. + (most of them avoid the case where extra temporary variables are introduced in an attempt to simplify + the expression code generation) - VariableAllocator: can we think of a smarter strategy for allocating variables into zeropage, rather than first-come-first-served - translateUnaryFunctioncall() in BuiltinFunctionsAsmGen: should be able to assign parameters to a builtin function directly from register(s), this will make the use of a builtin function in a pipe expression more efficient without using a temporary variable compare ``aa = startvalue(1) |> sin8u() |> cos8u() |> sin8u() |> cos8u()``