preparing optimizing pointer indexing

This commit is contained in:
Irmen de Jong 2022-06-04 12:46:32 +02:00
parent 0349d1d57c
commit c40cfaa388
5 changed files with 48 additions and 27 deletions

View File

@ -3,19 +3,16 @@ package prog8.compiler.astprocessing
import prog8.ast.Node
import prog8.ast.Program
import prog8.ast.expressions.ArrayIndexedExpression
import prog8.ast.expressions.BinaryExpression
import prog8.ast.expressions.DirectMemoryRead
import prog8.ast.statements.AssignTarget
import prog8.ast.statements.DirectMemoryWrite
import prog8.ast.statements.Subroutine
import prog8.ast.statements.VarDecl
import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification
import prog8.code.core.DataType
internal class AstVariousTransforms(private val program: Program) : AstWalker() {
// TODO can this be integrated in another walker
override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
// For non-kernal subroutines and non-asm parameters:
// inject subroutine params as local variables (if they're not there yet).
@ -38,29 +35,8 @@ internal class AstVariousTransforms(private val program: Program) : AstWalker()
return noModifications
}
// TODO move this / remove this. Needed here atm otherwise a replacement error occurs later in StatementReorderer
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
return replacePointerVarIndexWithMemreadOrMemwrite(program, arrayIndexedExpression, parent)
}
}
internal fun replacePointerVarIndexWithMemreadOrMemwrite(program: Program, arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
// rewrite pointervar[index] into @(pointervar+index)
val indexer = arrayIndexedExpression.indexer
val add = BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexer.indexExpr, arrayIndexedExpression.position)
return if(parent is AssignTarget) {
// we're part of the target of an assignment, we have to actually change the assign target itself
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position)
listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
} else {
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
}
}
return emptyList()
}

View File

@ -576,3 +576,25 @@ private fun makeGosubWithArgsViaCpuStack(
}
return listOf(IAstModification.ReplaceNode(call as Node, scope, parent))
}
internal fun replacePointerVarIndexWithMemreadOrMemwrite(program: Program, arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program)
if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) {
// rewrite pointervar[index] into @(pointervar+index)
val indexer = arrayIndexedExpression.indexer
val add = BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexer.indexExpr, arrayIndexedExpression.position)
return if(parent is AssignTarget) {
// we're part of the target of an assignment, we have to actually change the assign target itself
val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position)
val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position)
listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent))
} else {
val memread = DirectMemoryRead(add, arrayIndexedExpression.position)
listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent))
}
}
return emptyList()
}

View File

@ -757,4 +757,19 @@ class TestOptimization: FunSpec({
val ifStmt = stmts[4] as IfElse
ifStmt.condition shouldBe instanceOf<BinaryExpression>()
}
test("pointer indexing inside other expression ok") {
val src="""
main{
sub start () {
uword eRef
if eRef[3] and 10 {
return
}
}
}"""
val result = compileText(C64Target(), optimize=true, src, writeAssembly=false)!!
val stmts = result.program.entrypoint.statements
stmts.size shouldBe 3
}
})

View File

@ -3,6 +3,7 @@ TODO
For next release
^^^^^^^^^^^^^^^^
- try to integrated AstVariousTransforms into another walker
- why is this code so much larger:
uword xx
for xx in 0 to size-1 {

View File

@ -28,6 +28,13 @@ main {
; txt.spc()
; }
sub crash () {
uword eRef
if eRef[3] and 10 {
return
}
}
sub start() {
; mcCarthy()