mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
preparing optimizing pointer indexing
This commit is contained in:
parent
0349d1d57c
commit
c40cfaa388
@ -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()
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
})
|
||||
|
@ -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 {
|
||||
|
@ -28,6 +28,13 @@ main {
|
||||
; txt.spc()
|
||||
; }
|
||||
|
||||
sub crash () {
|
||||
uword eRef
|
||||
if eRef[3] and 10 {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
sub start() {
|
||||
; mcCarthy()
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user