mirror of
https://github.com/irmen/prog8.git
synced 2024-10-07 15:57:03 +00:00
comments
This commit is contained in:
parent
a52699717c
commit
d8d56b195f
@ -235,7 +235,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
// TODO OTHER EVALUATION HERE, don't use the estack to transfer the address to read/write from
|
// TODO use some other evaluation here; don't use the estack to transfer the address to read/write from
|
||||||
asmgen.assignExpressionTo(memory.addressExpression, AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, DataType.UWORD, memory.definingSubroutine))
|
asmgen.assignExpressionTo(memory.addressExpression, AsmAssignTarget(TargetStorageKind.STACK, program, asmgen, DataType.UWORD, memory.definingSubroutine))
|
||||||
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta P8ZP_SCRATCH_B1")
|
asmgen.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta P8ZP_SCRATCH_B1")
|
||||||
when {
|
when {
|
||||||
@ -2081,7 +2081,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
|
|||||||
sta ${target.asmVarname}+1
|
sta ${target.asmVarname}+1
|
||||||
""")
|
""")
|
||||||
}
|
}
|
||||||
TargetStorageKind.STACK -> TODO("no asm gen for stack float negate")
|
TargetStorageKind.STACK -> TODO("no asm gen for float stack negate")
|
||||||
else -> throw AssemblyError("weird target kind for inplace negate float ${target.kind}")
|
else -> throw AssemblyError("weird target kind for inplace negate float ${target.kind}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -73,7 +73,6 @@ X = BinExpr X = LeftExpr
|
|||||||
// )
|
// )
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO breaks imageviewer EHB palette
|
|
||||||
if(binExpr.right.isSimple) {
|
if(binExpr.right.isSimple) {
|
||||||
val firstAssign = Assignment(assignment.target.copy(), binExpr.left, binExpr.left.position)
|
val firstAssign = Assignment(assignment.target.copy(), binExpr.left, binExpr.left.position)
|
||||||
val targetExpr = assignment.target.toExpression()
|
val targetExpr = assignment.target.toExpression()
|
||||||
|
@ -198,6 +198,22 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
|||||||
val leftBinExpr = expr.left as? BinaryExpression
|
val leftBinExpr = expr.left as? BinaryExpression
|
||||||
val rightBinExpr = expr.right as? BinaryExpression
|
val rightBinExpr = expr.right as? BinaryExpression
|
||||||
if(expr.operator=="+" || expr.operator=="-") {
|
if(expr.operator=="+" || expr.operator=="-") {
|
||||||
|
|
||||||
|
if(leftBinExpr!=null && rightconst!=null) {
|
||||||
|
if(leftBinExpr.operator=="+") {
|
||||||
|
val c2 = leftBinExpr.right.constValue(program)
|
||||||
|
if(c2!=null) {
|
||||||
|
// (X + C2) +/- rightConst --> X + (C2 +/- rightConst)
|
||||||
|
// TODO SAME FOR (X - C1) +/- C2 --> X - (C1+C2) mind the operator flip?
|
||||||
|
// TODO SAME FOR (X * C1) * C2 --> X * (C1*C2)
|
||||||
|
// TODO SAME FOR (X / C1) / C2 --> X / (C1*C2)
|
||||||
|
val constants = BinaryExpression(c2, expr.operator, rightconst, c2.position)
|
||||||
|
val newExpr = BinaryExpression(leftBinExpr.left, "+", constants, expr.position)
|
||||||
|
return listOf(IAstModification.ReplaceNode(expr, newExpr, parent))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if(leftBinExpr!=null && rightBinExpr!=null) {
|
if(leftBinExpr!=null && rightBinExpr!=null) {
|
||||||
val c1 = leftBinExpr.right.constValue(program)
|
val c1 = leftBinExpr.right.constValue(program)
|
||||||
val c2 = rightBinExpr.right.constValue(program)
|
val c2 = rightBinExpr.right.constValue(program)
|
||||||
@ -378,7 +394,7 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
|
|||||||
{
|
{
|
||||||
// NOTE: THIS IS ONLY VALID ON FLOATING POINT CONSTANTS
|
// NOTE: THIS IS ONLY VALID ON FLOATING POINT CONSTANTS
|
||||||
|
|
||||||
// todo: this implements only a small set of possible reorderings at this time
|
// todo: this implements only a small set of possible reorderings at this time, we could think of more
|
||||||
if(expr.operator==subExpr.operator) {
|
if(expr.operator==subExpr.operator) {
|
||||||
// both operators are the same.
|
// both operators are the same.
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@ fun Program.splitBinaryExpressions(options: CompilationOptions, compTarget: ICom
|
|||||||
|
|
||||||
fun getTempVarName(dt: InferredTypes.InferredType): List<String> {
|
fun getTempVarName(dt: InferredTypes.InferredType): List<String> {
|
||||||
return when {
|
return when {
|
||||||
// TODO assume (hope) cx16.r9 isn't used for anything else...
|
// TODO assume (hope) cx16.r9 isn't used for anything else during the use of this temporary variable...
|
||||||
dt.istype(DataType.UBYTE) -> listOf("cx16", "r9L")
|
dt.istype(DataType.UBYTE) -> listOf("cx16", "r9L")
|
||||||
dt.istype(DataType.BYTE) -> listOf("cx16", "r9sL")
|
dt.istype(DataType.BYTE) -> listOf("cx16", "r9sL")
|
||||||
dt.istype(DataType.UWORD) -> listOf("cx16", "r9")
|
dt.istype(DataType.UWORD) -> listOf("cx16", "r9")
|
||||||
|
@ -312,7 +312,8 @@ romsub $ff56 = joystick_get(ubyte joynr @A) -> ubyte @A, ubyte @X, ubyte @Y
|
|||||||
romsub $ff4d = clock_set_date_time(uword yearmonth @R0, uword dayhours @R1, uword minsecs @R2, ubyte jiffies @R3) clobbers(A, X, Y)
|
romsub $ff4d = clock_set_date_time(uword yearmonth @R0, uword dayhours @R1, uword minsecs @R2, ubyte jiffies @R3) clobbers(A, X, Y)
|
||||||
romsub $ff50 = clock_get_date_time() clobbers(A, X, Y) -> uword @R0, uword @R1, uword @R2, ubyte @R3 ; result registers see clock_set_date_time()
|
romsub $ff50 = clock_get_date_time() clobbers(A, X, Y) -> uword @R0, uword @R1, uword @R2, ubyte @R3 ; result registers see clock_set_date_time()
|
||||||
|
|
||||||
; TODO specify the correct clobbers for all functions below, we now assume all 3 regs are clobbered
|
|
||||||
|
; It's not documented what registers are clobbered, so we assume the worst for all following kernal routines...:
|
||||||
|
|
||||||
; high level graphics & fonts
|
; high level graphics & fonts
|
||||||
romsub $ff20 = GRAPH_init(uword vectors @R0) clobbers(A,X,Y)
|
romsub $ff20 = GRAPH_init(uword vectors @R0) clobbers(A,X,Y)
|
||||||
|
@ -229,8 +229,7 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o
|
|||||||
|
|
||||||
// TODO: somehow figure out if the expr will result in stack-evaluation STILL after being split off,
|
// TODO: somehow figure out if the expr will result in stack-evaluation STILL after being split off,
|
||||||
// in that case: do *not* split it off but just keep it as it is (otherwise code size increases)
|
// in that case: do *not* split it off but just keep it as it is (otherwise code size increases)
|
||||||
// TODO: do NOT move this to an earler ast transform phase (such as StatementReorderer or StatementOptimizer)
|
// TODO: do NOT move this to an earler ast transform phase (such as StatementReorderer or StatementOptimizer) - it WILL result in larger code.
|
||||||
// it WILL result in larger code.
|
|
||||||
// TODO: this should be replaced by a general expression-evaluation optimization step.
|
// TODO: this should be replaced by a general expression-evaluation optimization step.
|
||||||
// the actual conditional expression in the statement should be no more than VARIABLE <COMPARISON-OPERATOR> SIMPLE-EXPRESSION
|
// the actual conditional expression in the statement should be no more than VARIABLE <COMPARISON-OPERATOR> SIMPLE-EXPRESSION
|
||||||
|
|
||||||
|
@ -106,6 +106,57 @@ class TestOptimization: FunSpec({
|
|||||||
constvalue.parent shouldBeSameInstanceAs pfx.parent
|
constvalue.parent shouldBeSameInstanceAs pfx.parent
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("const folding multiple scenarios +/-") {
|
||||||
|
val source = """
|
||||||
|
main {
|
||||||
|
const ubyte boardHeightC = 20
|
||||||
|
const ubyte boardOffsetC = 3
|
||||||
|
|
||||||
|
sub start() {
|
||||||
|
uword load_location = 12345
|
||||||
|
cx16.r0 = load_location + 8000 + 1000 + 1000
|
||||||
|
cx16.r1L = @(load_location + 8000 + 1000 + 1000)
|
||||||
|
cx16.r2 = 8000 + 1000 + 1000 + load_location
|
||||||
|
cx16.r3L = @(8000 + 1000 + 1000 + load_location)
|
||||||
|
cx16.r4 = load_location + boardOffsetC + boardHeightC - 1
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val result = compileText(C64Target, true, source, writeAssembly = false).assertSuccess()
|
||||||
|
// expected:
|
||||||
|
// uword load_location
|
||||||
|
// load_location = 12345
|
||||||
|
// cx16.r0 = load_location
|
||||||
|
// cx16.r0 += 10000
|
||||||
|
// cx16.r1L = @((load_location+10000))
|
||||||
|
// cx16.r2 = load_location
|
||||||
|
// cx16.r2 += 10000
|
||||||
|
// cx16.r3L = @((load_location+10000))
|
||||||
|
// cx16.r4 = load_location
|
||||||
|
// cx16.r4 += 22
|
||||||
|
val stmts = result.program.entrypoint.statements
|
||||||
|
stmts.size shouldBe 10
|
||||||
|
|
||||||
|
val addR0value = (stmts[3] as Assignment).value
|
||||||
|
val binexpr0 = addR0value as BinaryExpression
|
||||||
|
binexpr0.right shouldBe NumericLiteralValue(DataType.UWORD, 10000.0, Position.DUMMY)
|
||||||
|
val valueR1L = (stmts[4] as Assignment).value
|
||||||
|
val addrExpr1 = ((valueR1L as DirectMemoryRead).addressExpression as BinaryExpression)
|
||||||
|
addrExpr1.left shouldBe IdentifierReference(listOf("load_location"), Position.DUMMY)
|
||||||
|
addrExpr1.right shouldBe NumericLiteralValue(DataType.UWORD, 10000.0, Position.DUMMY)
|
||||||
|
|
||||||
|
val addR2value = (stmts[6] as Assignment).value
|
||||||
|
var binexpr2 = addR2value as BinaryExpression
|
||||||
|
binexpr2.right shouldBe NumericLiteralValue(DataType.UWORD, 10000.0, Position.DUMMY)
|
||||||
|
val valueR3L = (stmts[7] as Assignment).value
|
||||||
|
val addrExpr3 = ((valueR3L as DirectMemoryRead).addressExpression as BinaryExpression)
|
||||||
|
addrExpr3.left shouldBe IdentifierReference(listOf("load_location"), Position.DUMMY)
|
||||||
|
addrExpr3.right shouldBe NumericLiteralValue(DataType.UWORD, 10000.0, Position.DUMMY)
|
||||||
|
|
||||||
|
val addR4value = (stmts[9] as Assignment).value
|
||||||
|
val binexpr4 = addR4value as BinaryExpression
|
||||||
|
binexpr4.right shouldBe NumericLiteralValue(DataType.UWORD, 22.0, Position.DUMMY)
|
||||||
|
}
|
||||||
|
|
||||||
test("constantfolded and silently typecasted for initializervalues") {
|
test("constantfolded and silently typecasted for initializervalues") {
|
||||||
val sourcecode = """
|
val sourcecode = """
|
||||||
main {
|
main {
|
||||||
|
@ -3,6 +3,8 @@ TODO
|
|||||||
|
|
||||||
For next compiler release (7.5)
|
For next compiler release (7.5)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
more const-foldings
|
||||||
|
check correctness of inplaceModification_byte_value_to_pointer()
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
@ -41,6 +43,8 @@ More code optimization ideas
|
|||||||
by rewriting while and until expressions into if+jump (just consider them syntactic sugar)
|
by rewriting while and until expressions into if+jump (just consider them syntactic sugar)
|
||||||
but the result should not produce larger code ofcourse!
|
but the result should not produce larger code ofcourse!
|
||||||
- while-expression should now also get the simplifyConditionalExpression() treatment
|
- while-expression should now also get the simplifyConditionalExpression() treatment
|
||||||
|
- byte typed expressions should be evaluated in the accumulator where possible, without (temp)var
|
||||||
|
for instance value = otherbyte >> 1 --> lda otherbite ; lsr a; sta value
|
||||||
- rewrite expression tree evaluation such that it doesn't use an eval stack but flatten the tree into linear code that uses a fixed number of predetermined value 'variables'
|
- rewrite expression tree evaluation such that it doesn't use an eval stack but flatten the tree into linear code that uses a fixed number of predetermined value 'variables'
|
||||||
- this removes the need for the BinExprSplitter? (which is problematic and very limited now)
|
- this removes the need for the BinExprSplitter? (which is problematic and very limited now)
|
||||||
- introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4
|
- introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4
|
||||||
|
@ -3,10 +3,11 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
str name = "irmen"
|
; TODO other variants of this const folding
|
||||||
txt.print(name)
|
uword load_location = $6000
|
||||||
}
|
cx16.r0 = load_location + 8000 + 1000 + 1000
|
||||||
|
cx16.r1L = @(load_location + 8000 + 1000 + 1000)
|
||||||
sub func(uword[22] thing) {
|
cx16.r2 = 8000 + 1000 + 1000 + load_location
|
||||||
|
cx16.r3L = @(8000 + 1000 + 1000 + load_location)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user