mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
fixed 'unroll CONSTANTEXPR' compiler errors
This commit is contained in:
parent
9fca978725
commit
c15c10a94e
@ -628,5 +628,4 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -384,7 +384,8 @@ class StatementOptimizer(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun before(unrollLoop: UnrollLoop, parent: Node): Iterable<IAstModification> {
|
override fun before(unrollLoop: UnrollLoop, parent: Node): Iterable<IAstModification> {
|
||||||
return if(unrollLoop.iterations<1)
|
val iterations = unrollLoop.iterations.constValue(program)?.number?.toInt()
|
||||||
|
return if(iterations!=null && iterations<1)
|
||||||
listOf(IAstModification.Remove(unrollLoop, parent as IStatementContainer))
|
listOf(IAstModification.Remove(unrollLoop, parent as IStatementContainer))
|
||||||
else
|
else
|
||||||
noModifications
|
noModifications
|
||||||
|
@ -76,14 +76,19 @@ internal class AstChecker(private val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(unrollLoop: UnrollLoop) {
|
override fun visit(unrollLoop: UnrollLoop) {
|
||||||
if(unrollLoop.iterations<0 || unrollLoop.iterations>65535)
|
val iterations = unrollLoop.iterations.constValue(program)?.number?.toInt()
|
||||||
errors.err("invalid number of unrolls", unrollLoop.position)
|
if(iterations==null) {
|
||||||
unrollLoop.body.statements.forEach {
|
errors.err("unroll needs constant number of iterations", unrollLoop.position)
|
||||||
if(it !is InlineAssembly && it !is Assignment && it !is BuiltinFunctionCallStatement && it !is FunctionCallStatement && it !is PostIncrDecr)
|
} else {
|
||||||
errors.err("invalid statement in unroll loop", it.position)
|
if (iterations < 0 || iterations > 65535)
|
||||||
}
|
errors.err("invalid number of unrolls", unrollLoop.position)
|
||||||
if(unrollLoop.iterations * unrollLoop.body.statements.size > 256) {
|
unrollLoop.body.statements.forEach {
|
||||||
errors.warn("large number of unrolls, potential code size issue", unrollLoop.position)
|
if (it !is InlineAssembly && it !is Assignment && it !is BuiltinFunctionCallStatement && it !is FunctionCallStatement && it !is PostIncrDecr)
|
||||||
|
errors.err("invalid statement in unroll loop", it.position)
|
||||||
|
}
|
||||||
|
if (iterations * unrollLoop.body.statements.size > 256) {
|
||||||
|
errors.warn("large number of unrolls, potential code size issue", unrollLoop.position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
super.visit(unrollLoop)
|
super.visit(unrollLoop)
|
||||||
}
|
}
|
||||||
|
@ -326,7 +326,7 @@ class IntermediateAstMaker(private val program: Program) {
|
|||||||
|
|
||||||
private fun transform(srcUnroll: UnrollLoop): PtNodeGroup {
|
private fun transform(srcUnroll: UnrollLoop): PtNodeGroup {
|
||||||
val result = PtNodeGroup()
|
val result = PtNodeGroup()
|
||||||
repeat(srcUnroll.iterations) {
|
repeat(srcUnroll.iterations.constValue(program)!!.number.toInt()) {
|
||||||
srcUnroll.body.statements.forEach {
|
srcUnroll.body.statements.forEach {
|
||||||
result.add(transformStatement(it))
|
result.add(transformStatement(it))
|
||||||
}
|
}
|
||||||
|
@ -583,7 +583,7 @@ private fun Prog8ANTLRParser.RepeatloopContext.toAst(): RepeatLoop {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun Prog8ANTLRParser.UnrollloopContext.toAst(): UnrollLoop {
|
private fun Prog8ANTLRParser.UnrollloopContext.toAst(): UnrollLoop {
|
||||||
val iterations = integerliteral().toAst().number.toInt()
|
val iterations = expression().toAst()
|
||||||
val statements = statement_block()?.toAst() ?: mutableListOf(statement().toAst())
|
val statements = statement_block()?.toAst() ?: mutableListOf(statement().toAst())
|
||||||
val scope = AnonymousScope(statements, statement_block()?.toPosition()
|
val scope = AnonymousScope(statements, statement_block()?.toPosition()
|
||||||
?: statement().toPosition())
|
?: statement().toPosition())
|
||||||
|
@ -931,11 +931,13 @@ class RepeatLoop(var iterations: Expression?, var body: AnonymousScope, override
|
|||||||
iterations?.referencesIdentifier(nameInSource)==true || body.referencesIdentifier(nameInSource)
|
iterations?.referencesIdentifier(nameInSource)==true || body.referencesIdentifier(nameInSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
class UnrollLoop(val iterations: Int, var body: AnonymousScope, override val position: Position) : Statement() {
|
class UnrollLoop(var iterations: Expression, var body: AnonymousScope, override val position: Position) : Statement() {
|
||||||
|
// note: the iterations needs to evaluate to a constant number once parsed.
|
||||||
override lateinit var parent: Node
|
override lateinit var parent: Node
|
||||||
|
|
||||||
override fun linkParents(parent: Node) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
|
iterations.linkParents(this)
|
||||||
body.linkParents(this)
|
body.linkParents(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -943,13 +945,14 @@ class UnrollLoop(val iterations: Int, var body: AnonymousScope, override val pos
|
|||||||
|
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
if (node===body) body = replacement as AnonymousScope
|
if (node===body) body = replacement as AnonymousScope
|
||||||
|
else if (node===iterations) iterations = replacement as Expression
|
||||||
else throw FatalAstException("invalid replace")
|
else throw FatalAstException("invalid replace")
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||||
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
|
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
|
||||||
override fun referencesIdentifier(nameInSource: List<String>): Boolean = body.referencesIdentifier(nameInSource)
|
override fun referencesIdentifier(nameInSource: List<String>): Boolean = iterations.referencesIdentifier(nameInSource) || body.referencesIdentifier(nameInSource)
|
||||||
}
|
}
|
||||||
|
|
||||||
class UntilLoop(var body: AnonymousScope,
|
class UntilLoop(var body: AnonymousScope,
|
||||||
|
@ -398,6 +398,7 @@ abstract class AstWalker {
|
|||||||
|
|
||||||
fun visit(unrollLoop: UnrollLoop, parent: Node) {
|
fun visit(unrollLoop: UnrollLoop, parent: Node) {
|
||||||
track(before(unrollLoop, parent), unrollLoop, parent)
|
track(before(unrollLoop, parent), unrollLoop, parent)
|
||||||
|
unrollLoop.iterations.accept(this, unrollLoop)
|
||||||
unrollLoop.body.accept(this, unrollLoop)
|
unrollLoop.body.accept(this, unrollLoop)
|
||||||
track(after(unrollLoop, parent), unrollLoop, parent)
|
track(after(unrollLoop, parent), unrollLoop, parent)
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
- fix compiler crash on "unroll for x in 0 to txt.DEFAULT_WIDTH-1"
|
|
||||||
- fix compiler error on "unroll txt.DEFAULT_WIDTH"
|
|
||||||
|
|
||||||
- prefix prog8 subroutines with p8s_ instead of p8_ to not let them clash with variables in the asm??
|
- prefix prog8 subroutines with p8s_ instead of p8_ to not let them clash with variables in the asm??
|
||||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||||
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
- IR: reduce the number of branch instructions such as BEQ, BEQR, etc (gradually), replace with CMP(I) + status branch instruction
|
||||||
|
@ -1,22 +1,15 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage dontuse
|
||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
|
const ubyte CONSTANT=80
|
||||||
|
cx16.r0 = 0
|
||||||
|
unroll CONSTANT-10 {
|
||||||
|
cx16.r0++
|
||||||
|
}
|
||||||
|
txt.print_uw(cx16.r0)
|
||||||
|
|
||||||
ubyte[5] xx = [11,22,33,44,55]
|
|
||||||
ubyte[5] yy = [101,102,103,104,105]
|
|
||||||
ubyte i=3
|
|
||||||
ubyte j = 4
|
|
||||||
uword screen
|
|
||||||
|
|
||||||
ubyte result = xx[i] + yy[j]
|
|
||||||
txt.print_ub(result) ; 149
|
|
||||||
txt.nl()
|
|
||||||
result = xx[i] + yy[i]
|
|
||||||
txt.print_ub(result) ; 148
|
|
||||||
txt.nl()
|
|
||||||
@(screen+i) = xx[i] + yy[i]
|
|
||||||
|
|
||||||
; ubyte index = 100
|
; ubyte index = 100
|
||||||
; ubyte[] t_index = [1,2,3,4,5]
|
; ubyte[] t_index = [1,2,3,4,5]
|
||||||
|
@ -299,7 +299,7 @@ untilloop: 'do' (statement | statement_block) EOL? 'until' expression ;
|
|||||||
|
|
||||||
repeatloop: 'repeat' expression? EOL? (statement | statement_block) ;
|
repeatloop: 'repeat' expression? EOL? (statement | statement_block) ;
|
||||||
|
|
||||||
unrollloop: 'unroll' integerliteral? EOL? (statement | statement_block) ;
|
unrollloop: 'unroll' expression EOL? (statement | statement_block) ; // note: expression must evaluate to a constant
|
||||||
|
|
||||||
whenstmt: 'when' expression EOL? '{' EOL? (when_choice | EOL) * '}' EOL? ;
|
whenstmt: 'when' expression EOL? '{' EOL? (when_choice | EOL) * '}' EOL? ;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user