mirror of
https://github.com/irmen/prog8.git
synced 2025-08-16 05:27:31 +00:00
preparing optimizing pointer indexing
This commit is contained in:
@@ -3,19 +3,16 @@ package prog8.compiler.astprocessing
|
|||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.expressions.ArrayIndexedExpression
|
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.Subroutine
|
||||||
import prog8.ast.statements.VarDecl
|
import prog8.ast.statements.VarDecl
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.code.core.DataType
|
|
||||||
|
|
||||||
|
|
||||||
internal class AstVariousTransforms(private val program: Program) : AstWalker() {
|
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> {
|
override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
|
||||||
// For non-kernal subroutines and non-asm parameters:
|
// For non-kernal subroutines and non-asm parameters:
|
||||||
// inject subroutine params as local variables (if they're not there yet).
|
// 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
|
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> {
|
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
|
||||||
return replacePointerVarIndexWithMemreadOrMemwrite(program, arrayIndexedExpression, parent)
|
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))
|
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
|
val ifStmt = stmts[4] as IfElse
|
||||||
ifStmt.condition shouldBe instanceOf<BinaryExpression>()
|
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
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
|
- try to integrated AstVariousTransforms into another walker
|
||||||
- why is this code so much larger:
|
- why is this code so much larger:
|
||||||
uword xx
|
uword xx
|
||||||
for xx in 0 to size-1 {
|
for xx in 0 to size-1 {
|
||||||
|
@@ -28,6 +28,13 @@ main {
|
|||||||
; txt.spc()
|
; txt.spc()
|
||||||
; }
|
; }
|
||||||
|
|
||||||
|
sub crash () {
|
||||||
|
uword eRef
|
||||||
|
if eRef[3] and 10 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
; mcCarthy()
|
; mcCarthy()
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user