This commit is contained in:
Irmen de Jong 2021-12-09 21:13:13 +01:00
parent a52699717c
commit d8d56b195f
9 changed files with 84 additions and 13 deletions

View File

@ -235,7 +235,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
}
}
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.out(" jsr prog8_lib.read_byte_from_address_on_stack | sta P8ZP_SCRATCH_B1")
when {
@ -2081,7 +2081,7 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
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}")
}
}

View File

@ -73,7 +73,6 @@ X = BinExpr X = LeftExpr
// )
}
// TODO breaks imageviewer EHB palette
if(binExpr.right.isSimple) {
val firstAssign = Assignment(assignment.target.copy(), binExpr.left, binExpr.left.position)
val targetExpr = assignment.target.toExpression()

View File

@ -198,6 +198,22 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() {
val leftBinExpr = expr.left as? BinaryExpression
val rightBinExpr = expr.right as? BinaryExpression
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) {
val c1 = leftBinExpr.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
// 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) {
// both operators are the same.

View File

@ -71,7 +71,7 @@ fun Program.splitBinaryExpressions(options: CompilationOptions, compTarget: ICom
fun getTempVarName(dt: InferredTypes.InferredType): List<String> {
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.BYTE) -> listOf("cx16", "r9sL")
dt.istype(DataType.UWORD) -> listOf("cx16", "r9")

View File

@ -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 $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
romsub $ff20 = GRAPH_init(uword vectors @R0) clobbers(A,X,Y)

View File

@ -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,
// 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)
// it WILL result in larger code.
// TODO: do NOT move this to an earler ast transform phase (such as StatementReorderer or StatementOptimizer) - it WILL result in larger code.
// 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

View File

@ -106,6 +106,57 @@ class TestOptimization: FunSpec({
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") {
val sourcecode = """
main {

View File

@ -3,6 +3,8 @@ TODO
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)
but the result should not produce larger code ofcourse!
- 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'
- 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

View File

@ -3,10 +3,11 @@
main {
sub start() {
str name = "irmen"
txt.print(name)
}
sub func(uword[22] thing) {
; TODO other variants of this const folding
uword load_location = $6000
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)
}
}