mirror of
https://github.com/irmen/prog8.git
synced 2024-08-21 12:29:02 +00:00
reduce slow estack usage by splitting up simple binary expressions
This commit is contained in:
parent
a51fad3aab
commit
d020a7974a
@ -1686,7 +1686,6 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
eor #$80
|
eor #$80
|
||||||
sta ${target.asmVarname}+1
|
sta ${target.asmVarname}+1
|
||||||
""")
|
""")
|
||||||
asmgen.restoreRegister(CpuRegister.X)
|
|
||||||
}
|
}
|
||||||
TargetStorageKind.ARRAY -> TODO("in-place negate float array")
|
TargetStorageKind.ARRAY -> TODO("in-place negate float array")
|
||||||
TargetStorageKind.STACK -> TODO("stack float negate")
|
TargetStorageKind.STACK -> TODO("stack float negate")
|
||||||
|
@ -395,21 +395,21 @@ internal class StatementOptimizer(private val program: Program,
|
|||||||
val targetDt = targetIDt.typeOrElse(DataType.STRUCT)
|
val targetDt = targetIDt.typeOrElse(DataType.STRUCT)
|
||||||
val bexpr=assignment.value as? BinaryExpression
|
val bexpr=assignment.value as? BinaryExpression
|
||||||
if(bexpr!=null) {
|
if(bexpr!=null) {
|
||||||
val cv = bexpr.right.constValue(program)?.number?.toDouble()
|
val rightCv = bexpr.right.constValue(program)?.number?.toDouble()
|
||||||
if (cv != null && assignment.target isSameAs bexpr.left) {
|
if (rightCv != null && assignment.target isSameAs bexpr.left) {
|
||||||
// assignments of the form: X = X <operator> <expr>
|
// assignments of the form: X = X <operator> <expr>
|
||||||
// remove assignments that have no effect (such as X=X+0)
|
// remove assignments that have no effect (such as X=X+0)
|
||||||
// optimize/rewrite some other expressions
|
// optimize/rewrite some other expressions
|
||||||
val vardeclDt = (assignment.target.identifier?.targetVarDecl(program.namespace))?.type
|
val vardeclDt = (assignment.target.identifier?.targetVarDecl(program.namespace))?.type
|
||||||
when (bexpr.operator) {
|
when (bexpr.operator) {
|
||||||
"+" -> {
|
"+" -> {
|
||||||
if (cv == 0.0) {
|
if (rightCv == 0.0) {
|
||||||
return listOf(IAstModification.Remove(assignment, parent))
|
return listOf(IAstModification.Remove(assignment, parent))
|
||||||
} else if (targetDt in IntegerDatatypes && floor(cv) == cv) {
|
} else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) {
|
||||||
if (vardeclDt != VarDeclType.MEMORY && cv in 1.0..4.0) {
|
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..4.0) {
|
||||||
// replace by several INCs if it's not a memory address (inc on a memory mapped register doesn't work very well)
|
// replace by several INCs if it's not a memory address (inc on a memory mapped register doesn't work very well)
|
||||||
val incs = AnonymousScope(mutableListOf(), assignment.position)
|
val incs = AnonymousScope(mutableListOf(), assignment.position)
|
||||||
repeat(cv.toInt()) {
|
repeat(rightCv.toInt()) {
|
||||||
incs.statements.add(PostIncrDecr(assignment.target, "++", assignment.position))
|
incs.statements.add(PostIncrDecr(assignment.target, "++", assignment.position))
|
||||||
}
|
}
|
||||||
return listOf(IAstModification.ReplaceNode(assignment, incs, parent))
|
return listOf(IAstModification.ReplaceNode(assignment, incs, parent))
|
||||||
@ -417,36 +417,73 @@ internal class StatementOptimizer(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
"-" -> {
|
"-" -> {
|
||||||
if (cv == 0.0) {
|
if (rightCv == 0.0) {
|
||||||
return listOf(IAstModification.Remove(assignment, parent))
|
return listOf(IAstModification.Remove(assignment, parent))
|
||||||
} else if (targetDt in IntegerDatatypes && floor(cv) == cv) {
|
} else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) {
|
||||||
if (vardeclDt != VarDeclType.MEMORY && cv in 1.0..4.0) {
|
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..4.0) {
|
||||||
// replace by several DECs if it's not a memory address (dec on a memory mapped register doesn't work very well)
|
// replace by several DECs if it's not a memory address (dec on a memory mapped register doesn't work very well)
|
||||||
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
val decs = AnonymousScope(mutableListOf(), assignment.position)
|
||||||
repeat(cv.toInt()) {
|
repeat(rightCv.toInt()) {
|
||||||
decs.statements.add(PostIncrDecr(assignment.target, "--", assignment.position))
|
decs.statements.add(PostIncrDecr(assignment.target, "--", assignment.position))
|
||||||
}
|
}
|
||||||
return listOf(IAstModification.ReplaceNode(assignment, decs, parent))
|
return listOf(IAstModification.ReplaceNode(assignment, decs, parent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"*" -> if (cv == 1.0) return listOf(IAstModification.Remove(assignment, parent))
|
"*" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent))
|
||||||
"/" -> if (cv == 1.0) return listOf(IAstModification.Remove(assignment, parent))
|
"/" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent))
|
||||||
"**" -> if (cv == 1.0) return listOf(IAstModification.Remove(assignment, parent))
|
"**" -> if (rightCv == 1.0) return listOf(IAstModification.Remove(assignment, parent))
|
||||||
"|" -> if (cv == 0.0) return listOf(IAstModification.Remove(assignment, parent))
|
"|" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, parent))
|
||||||
"^" -> if (cv == 0.0) return listOf(IAstModification.Remove(assignment, parent))
|
"^" -> if (rightCv == 0.0) return listOf(IAstModification.Remove(assignment, parent))
|
||||||
"<<" -> {
|
"<<" -> {
|
||||||
if (cv == 0.0)
|
if (rightCv == 0.0)
|
||||||
return listOf(IAstModification.Remove(assignment, parent))
|
return listOf(IAstModification.Remove(assignment, parent))
|
||||||
}
|
}
|
||||||
">>" -> {
|
">>" -> {
|
||||||
if (cv == 0.0)
|
if (rightCv == 0.0)
|
||||||
return listOf(IAstModification.Remove(assignment, parent))
|
return listOf(IAstModification.Remove(assignment, parent))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun isSimpleTarget(target: AssignTarget): Boolean {
|
||||||
|
return when {
|
||||||
|
target.identifier!=null -> true
|
||||||
|
target.memoryAddress!=null -> {
|
||||||
|
target.memoryAddress.addressExpression is NumericLiteralValue || target.memoryAddress.addressExpression is IdentifierReference
|
||||||
}
|
}
|
||||||
|
target.arrayindexed!=null -> {
|
||||||
|
target.arrayindexed!!.arrayspec.index is NumericLiteralValue || target.arrayindexed!!.arrayspec.index is IdentifierReference
|
||||||
|
}
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// reduce the complexity of a (binary) expression that has to be evaluated on the eval stack,
|
||||||
|
// by attempting to splitting it up into individual simple steps:
|
||||||
|
// X = <some-expression-not-X> <operator> <not-binary-expression>
|
||||||
|
// or X = <not-binary-expression> <associativeoperator> <some-expression-not-X>
|
||||||
|
// split that into X = <some-expression-not-X> ; X = X <operator> <not-binary-expression>
|
||||||
|
if(!assignment.isAugmentable && isSimpleTarget(assignment.target)) {
|
||||||
|
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 augExpr = BinaryExpression(assignment.target.toExpression(), bexpr.operator, bexpr.right, bexpr.position)
|
||||||
|
return listOf(
|
||||||
|
IAstModification.InsertBefore(assignment, firstAssign, parent),
|
||||||
|
IAstModification.ReplaceNode(assignment.value, augExpr, assignment))
|
||||||
|
} 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 augExpr = BinaryExpression(assignment.target.toExpression(), bexpr.operator, bexpr.left, bexpr.position)
|
||||||
|
return listOf(
|
||||||
|
IAstModification.InsertBefore(assignment, firstAssign, parent),
|
||||||
|
IAstModification.ReplaceNode(assignment.value, augExpr, assignment))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -40,11 +40,13 @@ _saveX .byte 0
|
|||||||
float ff1 = 1000
|
float ff1 = 1000
|
||||||
float ff2 = -1000
|
float ff2 = -1000
|
||||||
|
|
||||||
ff1 = 1+((-ff1) *3) ; TODO why is splitting undone when OPTIMIZATION is ON?
|
ff1 = 1+((-ff1) *3)
|
||||||
floats.print_f(ff1)
|
floats.print_f(ff1)
|
||||||
|
floats.print_f(1+((-1000) *3))
|
||||||
testX()
|
testX()
|
||||||
ff1 = 1+((-ff2) *3) ; TODO why is splitting undone when OPTIMIZATION is ON?
|
ff1 = 1+((-ff2) *3)
|
||||||
floats.print_f(ff1)
|
floats.print_f(ff1)
|
||||||
|
floats.print_f(1+((- (-1000)) *3))
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
testX()
|
testX()
|
||||||
return
|
return
|
||||||
|
Loading…
Reference in New Issue
Block a user