mirror of
https://github.com/irmen/prog8.git
synced 2024-10-18 16:24:26 +00:00
don't use the temp-variables introducing optimizations for the vm target
This commit is contained in:
parent
06b38506d1
commit
97b3a0b093
@ -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.
|
||||
|
@ -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<IAstModification> {
|
||||
|
||||
if(compTarget.name==VMTarget.NAME)
|
||||
return noModifications
|
||||
|
||||
fun returnViaIntermediaryVar(value: Expression): Iterable<IAstModification>? {
|
||||
val subr = returnStmt.definingSubroutine!!
|
||||
val returnDt = subr.returntypes.single()
|
||||
|
@ -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 <COMPARISON-OPERATOR> 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
|
||||
|
@ -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()``
|
||||
|
Loading…
Reference in New Issue
Block a user