mirror of
https://github.com/irmen/prog8.git
synced 2024-09-08 10:55:08 +00:00
reduce slow estack usage by splitting up simple binary expressions
This commit is contained in:
parent
d020a7974a
commit
bda1c1c1eb
@ -35,4 +35,5 @@ internal interface IMachineDefinition {
|
|||||||
fun getFloatRomConst(number: Double): String?
|
fun getFloatRomConst(number: Double): String?
|
||||||
fun importLibs(compilerOptions: CompilationOptions, importer: ModuleImporter, program: Program)
|
fun importLibs(compilerOptions: CompilationOptions, importer: ModuleImporter, program: Program)
|
||||||
fun launchEmulator(programName: String)
|
fun launchEmulator(programName: String)
|
||||||
|
fun isRAMaddress(address: Int): Boolean
|
||||||
}
|
}
|
||||||
|
@ -89,6 +89,8 @@ internal object C64MachineDefinition: IMachineDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isRAMaddress(address: Int): Boolean = (address<0xa000) || (address in 0xc000..0xd000)
|
||||||
|
|
||||||
override fun initializeZeropage(compilerOptions: CompilationOptions) {
|
override fun initializeZeropage(compilerOptions: CompilationOptions) {
|
||||||
zeropage = C64Zeropage(compilerOptions)
|
zeropage = C64Zeropage(compilerOptions)
|
||||||
}
|
}
|
||||||
|
@ -52,6 +52,10 @@ internal object CX16MachineDefinition: IMachineDefinition {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun isRAMaddress(address: Int): Boolean {
|
||||||
|
return address < 0x9000 // TODO put correct Cx16 mem ranges here
|
||||||
|
}
|
||||||
|
|
||||||
override fun initializeZeropage(compilerOptions: CompilationOptions) {
|
override fun initializeZeropage(compilerOptions: CompilationOptions) {
|
||||||
zeropage = CX16Zeropage(compilerOptions)
|
zeropage = CX16Zeropage(compilerOptions)
|
||||||
}
|
}
|
||||||
|
@ -449,12 +449,34 @@ internal class StatementOptimizer(private val program: Program,
|
|||||||
|
|
||||||
fun isSimpleTarget(target: AssignTarget): Boolean {
|
fun isSimpleTarget(target: AssignTarget): Boolean {
|
||||||
return when {
|
return when {
|
||||||
target.identifier!=null -> true
|
target.identifier!=null -> {
|
||||||
|
val decl = target.identifier!!.targetVarDecl(program.namespace)!!
|
||||||
|
return if(decl.type!=VarDeclType.MEMORY) {
|
||||||
|
if(decl.value is NumericLiteralValue) {
|
||||||
|
CompilationTarget.instance.machine.isRAMaddress((decl.value as NumericLiteralValue).number.toInt())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
} else true
|
||||||
|
}
|
||||||
target.memoryAddress!=null -> {
|
target.memoryAddress!=null -> {
|
||||||
target.memoryAddress.addressExpression is NumericLiteralValue || target.memoryAddress.addressExpression is IdentifierReference
|
return when (target.memoryAddress.addressExpression) {
|
||||||
|
is NumericLiteralValue -> {
|
||||||
|
CompilationTarget.instance.machine.isRAMaddress((target.memoryAddress.addressExpression as NumericLiteralValue).number.toInt())
|
||||||
|
}
|
||||||
|
is IdentifierReference -> {
|
||||||
|
val decl = (target.memoryAddress.addressExpression as IdentifierReference).targetVarDecl(program.namespace)!!
|
||||||
|
if(decl.value is NumericLiteralValue) {
|
||||||
|
CompilationTarget.instance.machine.isRAMaddress((decl.value as NumericLiteralValue).number.toInt())
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
target.arrayindexed!=null -> {
|
target.arrayindexed!=null -> {
|
||||||
target.arrayindexed!!.arrayspec.index is NumericLiteralValue || target.arrayindexed!!.arrayspec.index is IdentifierReference
|
target.arrayindexed!!.arrayspec.index is NumericLiteralValue
|
||||||
}
|
}
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
@ -465,16 +487,14 @@ internal class StatementOptimizer(private val program: Program,
|
|||||||
// X = <some-expression-not-X> <operator> <not-binary-expression>
|
// X = <some-expression-not-X> <operator> <not-binary-expression>
|
||||||
// or X = <not-binary-expression> <associativeoperator> <some-expression-not-X>
|
// or X = <not-binary-expression> <associativeoperator> <some-expression-not-X>
|
||||||
// split that into X = <some-expression-not-X> ; X = X <operator> <not-binary-expression>
|
// split that into X = <some-expression-not-X> ; X = X <operator> <not-binary-expression>
|
||||||
if(!assignment.isAugmentable && isSimpleTarget(assignment.target)) {
|
if(bexpr.operator !in comparisonOperators && !assignment.isAugmentable && isSimpleTarget(assignment.target)) {
|
||||||
if (bexpr.right !is BinaryExpression) {
|
if (bexpr.right !is BinaryExpression) {
|
||||||
println("SPLIT RIGHT ${bexpr.left}\n ${bexpr.operator}\n ${bexpr.right}")
|
|
||||||
val firstAssign = Assignment(assignment.target, bexpr.left, assignment.position)
|
val firstAssign = Assignment(assignment.target, bexpr.left, assignment.position)
|
||||||
val augExpr = BinaryExpression(assignment.target.toExpression(), bexpr.operator, bexpr.right, bexpr.position)
|
val augExpr = BinaryExpression(assignment.target.toExpression(), bexpr.operator, bexpr.right, bexpr.position)
|
||||||
return listOf(
|
return listOf(
|
||||||
IAstModification.InsertBefore(assignment, firstAssign, parent),
|
IAstModification.InsertBefore(assignment, firstAssign, parent),
|
||||||
IAstModification.ReplaceNode(assignment.value, augExpr, assignment))
|
IAstModification.ReplaceNode(assignment.value, augExpr, assignment))
|
||||||
} else if (bexpr.left !is BinaryExpression && bexpr.operator in associativeOperators) {
|
} else if (bexpr.left !is BinaryExpression && bexpr.operator in associativeOperators) {
|
||||||
println("SPLIT LEFT ${bexpr.left}\n ${bexpr.operator}\n ${bexpr.right}")
|
|
||||||
val firstAssign = Assignment(assignment.target, bexpr.right, assignment.position)
|
val firstAssign = Assignment(assignment.target, bexpr.right, assignment.position)
|
||||||
val augExpr = BinaryExpression(assignment.target.toExpression(), bexpr.operator, bexpr.left, bexpr.position)
|
val augExpr = BinaryExpression(assignment.target.toExpression(), bexpr.operator, bexpr.left, bexpr.position)
|
||||||
return listOf(
|
return listOf(
|
||||||
|
@ -8,6 +8,9 @@ import prog8.ast.processing.AstWalker
|
|||||||
import prog8.ast.processing.IAstModification
|
import prog8.ast.processing.IAstModification
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
|
|
||||||
|
|
||||||
|
// TODO remove unneeded assignments such as: cc = 0 ; cc= xbuf ; ... the first can be removed (unless target is not RAM)
|
||||||
|
|
||||||
internal class UnusedCodeRemover(private val errors: ErrorReporter): AstWalker() {
|
internal class UnusedCodeRemover(private val errors: ErrorReporter): AstWalker() {
|
||||||
|
|
||||||
override fun before(program: Program, parent: Node): Iterable<IAstModification> {
|
override fun before(program: Program, parent: Node): Iterable<IAstModification> {
|
||||||
|
@ -74,13 +74,18 @@ main {
|
|||||||
}
|
}
|
||||||
c2A += 2
|
c2A += 2
|
||||||
c2B -= 3
|
c2B -= 3
|
||||||
|
ubyte cc
|
||||||
|
|
||||||
for y in 24 downto 0 {
|
for y in 24 downto 0 {
|
||||||
for x in 39 downto 0 {
|
for x in 39 downto 0 {
|
||||||
@(screen) = xbuf[x] + ybuf[y]
|
; using a temp var here to enable expression optimization that can't be done on a 'problematic' ROM/RAM memory location
|
||||||
|
ubyte cc = xbuf[x] + ybuf[y] ; TODO should be split!!
|
||||||
|
@(screen) = cc
|
||||||
|
; this is the fastest way to do this inner part:
|
||||||
; %asm {{
|
; %asm {{
|
||||||
; ldy x
|
; ldy i
|
||||||
; lda xbuf,y
|
; lda xbuf,y
|
||||||
; ldy y
|
; ldy ii
|
||||||
; clc
|
; clc
|
||||||
; adc ybuf,y
|
; adc ybuf,y
|
||||||
; ldy #0
|
; ldy #0
|
||||||
|
@ -40,6 +40,18 @@ _saveX .byte 0
|
|||||||
float ff1 = 1000
|
float ff1 = 1000
|
||||||
float ff2 = -1000
|
float ff2 = -1000
|
||||||
|
|
||||||
|
|
||||||
|
ubyte[10] xbuf
|
||||||
|
ubyte[10] ybuf
|
||||||
|
ubyte x
|
||||||
|
ubyte y
|
||||||
|
|
||||||
|
ubyte cc = xbuf[x] + ybuf[y] ; TODO should be split!!
|
||||||
|
ubyte cc2
|
||||||
|
cc2 = xbuf[x] + ybuf[y] ; will be split correctly?
|
||||||
|
|
||||||
|
return
|
||||||
|
|
||||||
ff1 = 1+((-ff1) *3)
|
ff1 = 1+((-ff1) *3)
|
||||||
floats.print_f(ff1)
|
floats.print_f(ff1)
|
||||||
floats.print_f(1+((-1000) *3))
|
floats.print_f(1+((-1000) *3))
|
||||||
|
Loading…
Reference in New Issue
Block a user