mirror of
https://github.com/irmen/prog8.git
synced 2025-01-13 10:29:52 +00:00
vardecl with initializer expression are now optimized again (unless floats)
This commit is contained in:
parent
74b5124a42
commit
8eb69d6eda
@ -33,7 +33,7 @@ graphics {
|
||||
}
|
||||
word @zp d = 0
|
||||
ubyte positive_ix = true
|
||||
word @zp dx = x2-x1
|
||||
word @zp dx = x2-x1 as word
|
||||
word @zp dy = y2-y1
|
||||
if dx < 0 {
|
||||
dx = -dx
|
||||
|
@ -11,7 +11,7 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte
|
||||
// - 'main' block must be the very first statement UNLESS it has an address set.
|
||||
// - library blocks are put last.
|
||||
// - blocks are ordered by address, where blocks without address are placed last.
|
||||
// - in every scope, most directives and vardecls are moved to the top.
|
||||
// - in every block and module, most directives and vardecls are moved to the top. (not in subroutines!)
|
||||
// - the 'start' subroutine is moved to the top.
|
||||
// - (syntax desugaring) a vardecl with a non-const initializer value is split into a regular vardecl and an assignment statement.
|
||||
// - (syntax desugaring) struct value assignment is expanded into several struct member assignments.
|
||||
@ -121,6 +121,28 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||
val declValue = decl.value
|
||||
if(declValue!=null && decl.type== VarDeclType.VAR && decl.datatype in NumericDatatypes) {
|
||||
val declConstValue = declValue.constValue(program)
|
||||
if(declConstValue==null) {
|
||||
// move the vardecl (without value) to the scope and replace this with a regular assignment
|
||||
// Unless we're dealing with a floating point variable because that will actually make things less efficient at the moment (because floats are mostly calcualated via the stack)
|
||||
if(decl.datatype!=DataType.FLOAT) {
|
||||
decl.value = null
|
||||
decl.allowInitializeWithZero = false
|
||||
val target = AssignTarget(IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
|
||||
val assign = Assignment(target, declValue, decl.position)
|
||||
return listOf(
|
||||
IAstModification.ReplaceNode(decl, assign, parent),
|
||||
IAstModification.InsertFirst(decl, decl.definingScope() as Node)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun before(assignment: Assignment, parent: Node): Iterable<IAstModification> {
|
||||
val valueType = assignment.value.inferType(program)
|
||||
val targetType = assignment.target.inferType(program, assignment)
|
||||
|
@ -5,6 +5,7 @@ import prog8.ast.base.*
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.processing.AstWalker
|
||||
import prog8.ast.processing.IAstVisitor
|
||||
import prog8.compiler.CompilerException
|
||||
import prog8.compiler.target.CompilationTarget
|
||||
|
||||
|
||||
@ -171,6 +172,7 @@ open class VarDecl(val type: VarDeclType,
|
||||
private set
|
||||
var structHasBeenFlattened = false // set later
|
||||
private set
|
||||
var allowInitializeWithZero = true
|
||||
|
||||
// prefix for literal values that are turned into a variable on the heap
|
||||
|
||||
@ -242,7 +244,12 @@ open class VarDecl(val type: VarDeclType,
|
||||
return "VarDecl(name=$name, vartype=$type, datatype=$datatype, struct=$structName, value=$value, pos=$position)"
|
||||
}
|
||||
|
||||
fun zeroElementValue() = defaultZero(declaredDatatype, position)
|
||||
fun zeroElementValue(): NumericLiteralValue {
|
||||
if(allowInitializeWithZero)
|
||||
return defaultZero(declaredDatatype, position)
|
||||
else
|
||||
throw CompilerException("attempt to get zero value for vardecl that shouldn't get it")
|
||||
}
|
||||
|
||||
fun flattenStructMembers(): MutableList<Statement> {
|
||||
val result = struct!!.statements.withIndex().map {
|
||||
|
@ -19,11 +19,14 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: E
|
||||
if (decl.value == null && !decl.autogeneratedDontRemove && decl.type == VarDeclType.VAR && decl.datatype in NumericDatatypes) {
|
||||
// a numeric vardecl without an initial value is initialized with zero,
|
||||
// unless there's already an assignment below, that initializes the value
|
||||
val nextAssign = decl.definingScope().nextSibling(decl) as? Assignment
|
||||
if(nextAssign!=null && nextAssign.target.isSameAs(IdentifierReference(listOf(decl.name), Position.DUMMY)))
|
||||
decl.value = null
|
||||
else
|
||||
decl.value = decl.zeroElementValue()
|
||||
if(decl.allowInitializeWithZero)
|
||||
{
|
||||
val nextAssign = decl.definingScope().nextSibling(decl) as? Assignment
|
||||
if (nextAssign != null && nextAssign.target.isSameAs(IdentifierReference(listOf(decl.name), Position.DUMMY)))
|
||||
decl.value = null
|
||||
else
|
||||
decl.value = decl.zeroElementValue()
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
@ -7,23 +7,20 @@ main {
|
||||
|
||||
sub start() {
|
||||
|
||||
ubyte[] array = [1,2,3,4]
|
||||
uword zc
|
||||
|
||||
const ubyte ic = 2
|
||||
ubyte ib = 2
|
||||
zc = 99
|
||||
scolor2=scolor
|
||||
|
||||
; TODO WHy does this compile with stack eval:
|
||||
ubyte scolor = (zc>>13) as ubyte + 4
|
||||
|
||||
; TODO this is more optimized:
|
||||
ubyte scolor2
|
||||
scolor2 = (zc>>13) as ubyte + 4
|
||||
|
||||
scolor2=scolor
|
||||
|
||||
ib = array[ic+1]
|
||||
ib = array[ib]
|
||||
ib = array[ib+1]
|
||||
ib = array[ib+2]
|
||||
ib = array[ib-1]
|
||||
ib = array[ib-2]
|
||||
ib = array[ib*2]
|
||||
ib = array[2*ib]
|
||||
ib = array[ib*3]
|
||||
ib = array[3*ib]
|
||||
ib = array[ib*4]
|
||||
ib = array[4*ib]
|
||||
testX()
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user