mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +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
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -384,7 +384,8 @@ class StatementOptimizer(private val program: Program,
|
||||
}
|
||||
|
||||
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))
|
||||
else
|
||||
noModifications
|
||||
|
@ -76,14 +76,19 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(unrollLoop: UnrollLoop) {
|
||||
if(unrollLoop.iterations<0 || unrollLoop.iterations>65535)
|
||||
errors.err("invalid number of unrolls", unrollLoop.position)
|
||||
unrollLoop.body.statements.forEach {
|
||||
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(unrollLoop.iterations * unrollLoop.body.statements.size > 256) {
|
||||
errors.warn("large number of unrolls, potential code size issue", unrollLoop.position)
|
||||
val iterations = unrollLoop.iterations.constValue(program)?.number?.toInt()
|
||||
if(iterations==null) {
|
||||
errors.err("unroll needs constant number of iterations", unrollLoop.position)
|
||||
} else {
|
||||
if (iterations < 0 || iterations > 65535)
|
||||
errors.err("invalid number of unrolls", unrollLoop.position)
|
||||
unrollLoop.body.statements.forEach {
|
||||
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)
|
||||
}
|
||||
|
@ -326,7 +326,7 @@ class IntermediateAstMaker(private val program: Program) {
|
||||
|
||||
private fun transform(srcUnroll: UnrollLoop): PtNodeGroup {
|
||||
val result = PtNodeGroup()
|
||||
repeat(srcUnroll.iterations) {
|
||||
repeat(srcUnroll.iterations.constValue(program)!!.number.toInt()) {
|
||||
srcUnroll.body.statements.forEach {
|
||||
result.add(transformStatement(it))
|
||||
}
|
||||
|
@ -583,7 +583,7 @@ private fun Prog8ANTLRParser.RepeatloopContext.toAst(): RepeatLoop {
|
||||
}
|
||||
|
||||
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 scope = AnonymousScope(statements, statement_block()?.toPosition()
|
||||
?: statement().toPosition())
|
||||
|
@ -931,11 +931,13 @@ class RepeatLoop(var iterations: Expression?, var body: AnonymousScope, override
|
||||
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 fun linkParents(parent: Node) {
|
||||
this.parent = parent
|
||||
iterations.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) {
|
||||
if (node===body) body = replacement as AnonymousScope
|
||||
else if (node===iterations) iterations = replacement as Expression
|
||||
else throw FatalAstException("invalid replace")
|
||||
replacement.parent = this
|
||||
}
|
||||
|
||||
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||
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,
|
||||
|
@ -398,6 +398,7 @@ abstract class AstWalker {
|
||||
|
||||
fun visit(unrollLoop: UnrollLoop, parent: Node) {
|
||||
track(before(unrollLoop, parent), unrollLoop, parent)
|
||||
unrollLoop.iterations.accept(this, unrollLoop)
|
||||
unrollLoop.body.accept(this, unrollLoop)
|
||||
track(after(unrollLoop, parent), unrollLoop, parent)
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
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??
|
||||
- [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
|
||||
|
@ -1,22 +1,15 @@
|
||||
%import textio
|
||||
%zeropage basicsafe
|
||||
%zeropage dontuse
|
||||
|
||||
main {
|
||||
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[] 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) ;
|
||||
|
||||
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? ;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user