mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
optimize dangling else
This commit is contained in:
parent
0aac9350d5
commit
a587482edf
@ -43,9 +43,9 @@ fun Program.constantFold(errors: IErrorReporter, compTarget: ICompilationTarget)
|
||||
|
||||
fun Program.optimizeStatements(errors: IErrorReporter,
|
||||
functions: IBuiltinFunctions,
|
||||
compTarget: ICompilationTarget
|
||||
options: CompilationOptions
|
||||
): Int {
|
||||
val optimizer = StatementOptimizer(this, errors, functions, compTarget)
|
||||
val optimizer = StatementOptimizer(this, errors, functions, options)
|
||||
optimizer.visit(this)
|
||||
val optimizationCount = optimizer.applyModifications()
|
||||
|
||||
|
@ -13,7 +13,7 @@ import kotlin.math.floor
|
||||
class StatementOptimizer(private val program: Program,
|
||||
private val errors: IErrorReporter,
|
||||
private val functions: IBuiltinFunctions,
|
||||
private val compTarget: ICompilationTarget
|
||||
private val options: CompilationOptions
|
||||
) : AstWalker() {
|
||||
|
||||
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
|
||||
@ -39,7 +39,7 @@ class StatementOptimizer(private val program: Program,
|
||||
if(string!=null) {
|
||||
val pos = functionCallStatement.position
|
||||
if (string.value.length == 1) {
|
||||
val firstCharEncoded = compTarget.encodeString(string.value, string.encoding)[0]
|
||||
val firstCharEncoded = options.compTarget.encodeString(string.value, string.encoding)[0]
|
||||
val chrout = FunctionCallStatement(
|
||||
IdentifierReference(listOf("txt", "chrout"), pos),
|
||||
mutableListOf(NumericLiteral(DataType.UBYTE, firstCharEncoded.toDouble(), pos)),
|
||||
@ -51,7 +51,7 @@ class StatementOptimizer(private val program: Program,
|
||||
IAstModification.Remove(stringDecl, stringDecl.parent as IStatementContainer)
|
||||
)
|
||||
} else if (string.value.length == 2) {
|
||||
val firstTwoCharsEncoded = compTarget.encodeString(string.value.take(2), string.encoding)
|
||||
val firstTwoCharsEncoded = options.compTarget.encodeString(string.value.take(2), string.encoding)
|
||||
val chrout1 = FunctionCallStatement(
|
||||
IdentifierReference(listOf("txt", "chrout"), pos),
|
||||
mutableListOf(NumericLiteral(DataType.UBYTE, firstTwoCharsEncoded[0].toDouble(), pos)),
|
||||
@ -108,6 +108,16 @@ class StatementOptimizer(private val program: Program,
|
||||
}
|
||||
}
|
||||
|
||||
// remove obvious dangling elses (else after a return)
|
||||
if(ifElse.elsepart.isNotEmpty() && ifElse.truepart.statements.singleOrNull() is Return) {
|
||||
val elsePart = AnonymousScope(ifElse.elsepart.statements, ifElse.elsepart.position)
|
||||
if(options.slowCodegenWarnings)
|
||||
errors.warn("else can be omitted", ifElse.elsepart.position)
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(ifElse.elsepart, AnonymousScope(mutableListOf(), ifElse.elsepart.position), ifElse),
|
||||
IAstModification.InsertAfter(ifElse, elsePart, parent as IStatementContainer)
|
||||
)
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
@ -141,7 +151,7 @@ class StatementOptimizer(private val program: Program,
|
||||
val size = sv.value.length
|
||||
if(size==1) {
|
||||
// loop over string of length 1 -> just assign the single character
|
||||
val character = compTarget.encodeString(sv.value, sv.encoding)[0]
|
||||
val character = options.compTarget.encodeString(sv.value, sv.encoding)[0]
|
||||
val byte = NumericLiteral(DataType.UBYTE, character.toDouble(), iterable.position)
|
||||
val scope = AnonymousScope(mutableListOf(), forLoop.position)
|
||||
scope.statements.add(Assignment(AssignTarget(forLoop.loopVar, null, null, forLoop.position), byte, AssignmentOrigin.OPTIMIZER, forLoop.position))
|
||||
@ -326,7 +336,7 @@ class StatementOptimizer(private val program: Program,
|
||||
if (rightCv == 0.0) {
|
||||
return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
} else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) {
|
||||
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..3.0 && compTarget.name!=VMTarget.NAME) {
|
||||
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..3.0 && options.compTarget.name!=VMTarget.NAME) {
|
||||
// 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)
|
||||
repeat(rightCv.toInt()) {
|
||||
@ -340,7 +350,7 @@ class StatementOptimizer(private val program: Program,
|
||||
if (rightCv == 0.0) {
|
||||
return listOf(IAstModification.Remove(assignment, parent as IStatementContainer))
|
||||
} else if (targetDt in IntegerDatatypes && floor(rightCv) == rightCv) {
|
||||
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..3.0 && compTarget.name!=VMTarget.NAME) {
|
||||
if (vardeclDt != VarDeclType.MEMORY && rightCv in 1.0..3.0 && options.compTarget.name!=VMTarget.NAME) {
|
||||
// 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)
|
||||
repeat(rightCv.toInt()) {
|
||||
|
@ -371,7 +371,7 @@ private fun optimizeAst(program: Program, compilerOptions: CompilationOptions, e
|
||||
// keep optimizing expressions and statements until no more steps remain
|
||||
val optsDone1 = program.simplifyExpressions(errors, compTarget)
|
||||
val optsDone2 = program.splitBinaryExpressions(compilerOptions)
|
||||
val optsDone3 = program.optimizeStatements(errors, functions, compTarget)
|
||||
val optsDone3 = program.optimizeStatements(errors, functions, compilerOptions)
|
||||
val optsDone4 = program.inlineSubroutines()
|
||||
program.constantFold(errors, compTarget) // because simplified statements and expressions can result in more constants that can be folded away
|
||||
errors.report()
|
||||
|
@ -1,8 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- optimize a "dangling else"
|
||||
|
||||
...
|
||||
|
||||
|
||||
|
@ -1,67 +1,41 @@
|
||||
%import math
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
|
||||
main {
|
||||
|
||||
const ubyte WIDTH=255
|
||||
const ubyte HEIGHT=240
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
sys.gfx_enable(0) ; enable lo res screen
|
||||
;; gfx2.screen_mode(4)
|
||||
repeat {
|
||||
txt.print_ub(danglingelse(32))
|
||||
txt.spc()
|
||||
txt.print_ub(danglingelse(99))
|
||||
txt.spc()
|
||||
txt.print_ub(danglingelse(1))
|
||||
txt.spc()
|
||||
txt.print_ub(danglingelse(100))
|
||||
txt.nl()
|
||||
txt.print_ub(danglingelse2(32))
|
||||
txt.spc()
|
||||
txt.print_ub(danglingelse2(99))
|
||||
txt.spc()
|
||||
txt.print_ub(danglingelse2(1))
|
||||
txt.spc()
|
||||
txt.print_ub(danglingelse2(100))
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
ubyte xx
|
||||
ubyte yy
|
||||
sub danglingelse(ubyte bb) -> ubyte {
|
||||
if bb==32
|
||||
return 32
|
||||
else if bb==99
|
||||
return 99
|
||||
else
|
||||
return 0
|
||||
}
|
||||
|
||||
for yy in 0 to HEIGHT-1 {
|
||||
for xx in 0 to WIDTH-1 {
|
||||
ubyte value = math.direction(WIDTH/2, HEIGHT/2, xx, yy)
|
||||
;; gfx2.plot(xx,yy,value)
|
||||
sys.gfx_plot(xx, yy, value*10)
|
||||
}
|
||||
}
|
||||
}
|
||||
sub danglingelse2(ubyte bb) -> ubyte {
|
||||
if bb==32
|
||||
return 32
|
||||
if bb==99
|
||||
return 99
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
;main {
|
||||
;
|
||||
; sub start() {
|
||||
;
|
||||
; const ubyte HEIGHT = txt.DEFAULT_HEIGHT
|
||||
; const ubyte WIDTH = txt.DEFAULT_WIDTH
|
||||
; const ubyte HALFWIDTH = txt.DEFAULT_WIDTH/2
|
||||
; const ubyte HALFHEIGHT = txt.DEFAULT_HEIGHT/2
|
||||
;
|
||||
; ubyte @zp value
|
||||
; ubyte xx
|
||||
; ubyte yy
|
||||
;; for yy in 0 to HEIGHT-1 {
|
||||
;; for xx in 0 to WIDTH-1 {
|
||||
;; value = math.atan(HALFWIDTH, HALFHEIGHT, xx, yy)
|
||||
;; txt.setchr(xx,yy,value)
|
||||
;; }
|
||||
;; }
|
||||
;;
|
||||
;; byte sx
|
||||
;; byte sy
|
||||
;; for sy in -HEIGHT/2 to HEIGHT/2 {
|
||||
;; for sx in -WIDTH/2 to WIDTH/2 {
|
||||
;; value = math.direction_sc(0, 0, sx, sy)
|
||||
;; txt.setchr(sx+WIDTH/2 as ubyte,sy+HEIGHT/2 as ubyte,value)
|
||||
;; }
|
||||
;; }
|
||||
;
|
||||
; for yy in 0 to HEIGHT-1 {
|
||||
; for xx in 0 to WIDTH-1 {
|
||||
; value = math.direction(HALFWIDTH, HALFHEIGHT, xx, yy)
|
||||
; txt.setchr(xx,yy,value)
|
||||
; }
|
||||
; }
|
||||
;
|
||||
; goto start
|
||||
; }
|
||||
;}
|
||||
|
Loading…
Reference in New Issue
Block a user