From 3410aea788ac93af48ae37fbdce2b9aaa97944e5 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 2 Nov 2021 21:23:59 +0100 Subject: [PATCH] fix regression: don't add 0 initializer when variable is assigned to anyway (or is loopvar in a for-loop) --- compiler/res/prog8lib/prog8_lib.p8 | 1 + .../compiler/astprocessing/StatementReorderer.kt | 14 +++++++++++--- docs/source/todo.rst | 1 - 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/compiler/res/prog8lib/prog8_lib.p8 b/compiler/res/prog8lib/prog8_lib.p8 index 5804022a6..d4927b6ff 100644 --- a/compiler/res/prog8lib/prog8_lib.p8 +++ b/compiler/res/prog8lib/prog8_lib.p8 @@ -10,6 +10,7 @@ prog8_lib { word @zp retval_interm_w ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size) ubyte @zp retval_interm_ub ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size) byte @zp retval_interm_b ; to store intermediary expression results for return values (hopefully allocated on ZP to reduce code size) + ; NOTE: these variables are checked in the StatementReorderer (in fun after(decl: VarDecl)), for these exact names! asmsub pattern_match(str string @AY, str pattern @R0) clobbers(Y) -> ubyte @A { %asm {{ diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 1d04a5096..f96098c55 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -47,12 +47,20 @@ internal class StatementReorderer(val program: Program, val errors: IErrorReport if (decl.value == null) { if (!decl.autogeneratedDontRemove && decl.allowInitializeWithZero) { // A numeric vardecl without an initial value is initialized with zero, - // unless there's already an assignment below, that initializes the value. + // unless there's already an assignment below it, that initializes the value (or a for loop that uses it as loopvar). // This allows you to restart the program and have the same starting values of the variables // So basically consider 'ubyte xx' as a short form for 'ubyte xx; xx=0' decl.value = null - val nextAssign = decl.nextSibling() as? Assignment - if (nextAssign == null || !(nextAssign.target isSameAs IdentifierReference(listOf(decl.name), Position.DUMMY))) { + if(decl.name.startsWith("retval_interm_") && decl.definingScope.name=="prog8_lib") { + // no need to zero out the special internal returnvalue intermediates. + return noModifications + } + val nextStmt = decl.nextSibling() + val nextAssign = nextStmt as? Assignment + val nextFor = nextStmt as? ForLoop + val hasNextForWithThisLoopvar = nextFor?.loopVar?.nameInSource==listOf(decl.name) + val hasNextAssignment = nextAssign!=null && nextAssign.target isSameAs IdentifierReference(listOf(decl.name), Position.DUMMY) + if (!hasNextAssignment && !hasNextForWithThisLoopvar) { // Add assignment to initialize with zero // Note: for block-level vars, this will introduce assignments in the block scope. These have to be dealt with correctly later. val identifier = IdentifierReference(listOf(decl.name), decl.position) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 901ef45b2..8a53d973f 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -6,7 +6,6 @@ For next compiler release (7.2) - fix the asm-labels problem (github issue #62) - find a way to optimize asm-subroutine param passing where it now sometimes uses the evalstack? - analyze (and fix?): TODO why are these bigger now than before the var-initializer optimization: - ; wizzine ; wormfood ; cube3d-float (THIS ONE IS A LOT BIGGER!!) ; cube3d-sprites