This commit is contained in:
Irmen de Jong 2021-11-15 01:30:12 +01:00
parent 5fd83f2757
commit 1f60a2d8b9
7 changed files with 28 additions and 27 deletions

View File

@ -113,9 +113,9 @@ private fun optimizeUselessStackByteWrites(linesByFour: List<List<IndexedValue<S
private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<String>>>): List<Modification> { private fun optimizeSameAssignments(linesByFourteen: List<List<IndexedValue<String>>>): List<Modification> {
// optimize sequential assignments of the isSameAs value to various targets (bytes, words, floats) // Optimize sequential assignments of the isSameAs value to various targets (bytes, words, floats)
// the float one is the one that requires 2*7=14 lines of code to check... // the float one is the one that requires 2*7=14 lines of code to check...
// @todo a better place to do this is in the Compiler instead and transform the Ast, or the AsmGen, and never even create the inefficient asm in the first place... // The better place to do this is in the Compiler instead and never create these types of assembly, but hey
val mods = mutableListOf<Modification>() val mods = mutableListOf<Modification>()
for (lines in linesByFourteen) { for (lines in linesByFourteen) {

View File

@ -270,7 +270,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
// Everything else just evaluate via the stack. // Everything else just evaluate via the stack.
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here, // (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
// because the code here is the implementation of exactly that...) // because the code here is the implementation of exactly that...)
// TODO FIX THIS... by using a temp var? so that it becomes augmentable assignment expression? // TODO DON'T STACK-EVAL THIS... by using a temp var? so that it becomes augmentable assignment expression?
asmgen.translateExpression(value) asmgen.translateExpression(value)
if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes) if (assign.target.datatype in WordDatatypes && assign.source.datatype in ByteDatatypes)
asmgen.signExtendStackLsb(assign.source.datatype) asmgen.signExtendStackLsb(assign.source.datatype)

View File

@ -301,8 +301,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
} }
} }
} }
TargetStorageKind.REGISTER -> throw AssemblyError("missing codegen for reg in-place modification") TargetStorageKind.REGISTER -> throw AssemblyError("no asm gen for reg in-place modification")
TargetStorageKind.STACK -> throw AssemblyError("missing codegen for stack in-place modification") TargetStorageKind.STACK -> throw AssemblyError("no asm gen for stack in-place modification")
} }
} }
@ -1802,8 +1802,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
else -> throw AssemblyError("invalid reg dt for byte not") else -> throw AssemblyError("invalid reg dt for byte not")
} }
} }
TargetStorageKind.STACK -> TODO("missing codegen for byte stack not") TargetStorageKind.STACK -> TODO("no asm gen for byte stack not")
else -> throw AssemblyError("missing codegen for in-place not of ubyte ${target.kind}") else -> throw AssemblyError("no asm gen for in-place not of ubyte ${target.kind}")
} }
} }
DataType.UWORD -> { DataType.UWORD -> {
@ -1860,8 +1860,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
} }
} }
TargetStorageKind.MEMORY -> TODO("no asm gen for uword-memory not") TargetStorageKind.MEMORY -> TODO("no asm gen for uword-memory not")
TargetStorageKind.STACK -> TODO("missing codegen for word stack not") TargetStorageKind.STACK -> TODO("no asm gen for word stack not")
else -> throw AssemblyError("missing codegen for in-place not of uword for ${target.kind}") else -> throw AssemblyError("no asm gen for in-place not of uword for ${target.kind}")
} }
} }
else -> throw AssemblyError("boolean-not of invalid type") else -> throw AssemblyError("boolean-not of invalid type")
@ -1911,8 +1911,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
else -> throw AssemblyError("invalid reg dt for byte invert") else -> throw AssemblyError("invalid reg dt for byte invert")
} }
} }
TargetStorageKind.STACK -> TODO("missing codegen for byte stack invert") TargetStorageKind.STACK -> TODO("no asm gen for byte stack invert")
else -> throw AssemblyError("missing codegen for in-place invert ubyte for ${target.kind}") else -> throw AssemblyError("no asm gen for in-place invert ubyte for ${target.kind}")
} }
} }
DataType.UWORD -> { DataType.UWORD -> {
@ -1931,15 +1931,13 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
RegisterOrPair.AX -> asmgen.out(" pha | txa | eor #255 | tax | pla | eor #255") RegisterOrPair.AX -> asmgen.out(" pha | txa | eor #255 | tax | pla | eor #255")
RegisterOrPair.AY -> asmgen.out(" pha | tya | eor #255 | tay | pla | eor #255") RegisterOrPair.AY -> asmgen.out(" pha | tya | eor #255 | tay | pla | eor #255")
RegisterOrPair.XY -> asmgen.out(" txa | eor #255 | tax | tya | eor #255 | tay") RegisterOrPair.XY -> asmgen.out(" txa | eor #255 | tax | tya | eor #255 | tay")
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> TODO("no asm gen for cx16 word register invert")
TODO("codegen for cx16 word register invert")
}
else -> throw AssemblyError("invalid reg dt for word invert") else -> throw AssemblyError("invalid reg dt for word invert")
} }
} }
TargetStorageKind.MEMORY -> TODO("no asm gen for uword-memory invert") TargetStorageKind.MEMORY -> TODO("no asm gen for uword-memory invert")
TargetStorageKind.STACK -> TODO("missing codegen for word stack invert") TargetStorageKind.STACK -> TODO("no asm gen for word stack invert")
else -> throw AssemblyError("missing codegen for in-place invert uword for ${target.kind}") else -> throw AssemblyError("no asm gen for in-place invert uword for ${target.kind}")
} }
} }
else -> throw AssemblyError("invert of invalid type") else -> throw AssemblyError("invert of invalid type")
@ -1966,8 +1964,8 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
} }
} }
TargetStorageKind.MEMORY -> TODO("can't in-place negate memory ubyte") TargetStorageKind.MEMORY -> TODO("can't in-place negate memory ubyte")
TargetStorageKind.STACK -> TODO("missing codegen for byte stack negate") TargetStorageKind.STACK -> TODO("no asm gen for byte stack negate")
else -> throw AssemblyError("missing codegen for in-place negate byte array") else -> throw AssemblyError("no asm gen for in-place negate byte array")
} }
} }
DataType.WORD -> { DataType.WORD -> {
@ -2022,15 +2020,13 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sbc P8ZP_SCRATCH_REG+1 sbc P8ZP_SCRATCH_REG+1
tay""") tay""")
} }
in Cx16VirtualRegisters -> { in Cx16VirtualRegisters -> TODO("no asm gen for cx16 word register negate")
TODO("codegen for cx16 word register negate")
}
else -> throw AssemblyError("invalid reg dt for word neg") else -> throw AssemblyError("invalid reg dt for word neg")
} }
} }
TargetStorageKind.MEMORY -> TODO("no asm gen for word memory negate") TargetStorageKind.MEMORY -> TODO("no asm gen for word memory negate")
TargetStorageKind.STACK -> TODO("missing codegen for word stack negate") TargetStorageKind.STACK -> TODO("no asm gen for word stack negate")
else -> throw AssemblyError("missing codegen for in-place negate word array") else -> throw AssemblyError("no asm gen for in-place negate word array")
} }
} }
DataType.FLOAT -> { DataType.FLOAT -> {
@ -2043,9 +2039,9 @@ internal class AugmentableAssignmentAsmGen(private val program: Program,
sta ${target.asmVarname}+1 sta ${target.asmVarname}+1
""") """)
} }
TargetStorageKind.REGISTER -> TODO("missing codegen for float reg negate") TargetStorageKind.REGISTER -> TODO("no asm gen for float reg negate")
TargetStorageKind.MEMORY -> TODO("missing codegen for float memory negate") TargetStorageKind.MEMORY -> TODO("no asm gen for float memory negate")
TargetStorageKind.STACK -> TODO("missing codegen for stack float negate") TargetStorageKind.STACK -> TODO("no asm gen for stack float 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}")
} }
} }

View File

@ -19,12 +19,16 @@ import kotlin.math.pow
Investigate what optimizations binaryen has, also see https://egorbo.com/peephole-optimizations.html Investigate what optimizations binaryen has, also see https://egorbo.com/peephole-optimizations.html
some of these may already be present:
*(&X) => X *(&X) => X
X % 1 => 0 X % 1 => 0
X / 1 => X X / 1 => X
X ^ -1 => ~x X ^ -1 => ~x
X >= 1 => X > 0 X >= 1 => X > 0
X < 1 => X <= 0 X < 1 => X <= 0
and some const foldings (that may already be done as well):
X + С1 == C2 => X == C2 - C1 X + С1 == C2 => X == C2 - C1
((X + C1) + C2) => (X + (C1 + C2)) ((X + C1) + C2) => (X + (C1 + C2))
((X + C1) + (Y + C2)) => ((X + Y) + (C1 + C2)) ((X + C1) + (Y + C2)) => ((X + Y) + (C1 + C2))

View File

@ -124,7 +124,6 @@ class UnusedCodeRemover(private val program: Program,
it.isInRegularRAMof(compTarget.machine) it.isInRegularRAMof(compTarget.machine)
} }
if(assignTargets.size==usages.size) { if(assignTargets.size==usages.size) {
// TODO FIX THAT A MEMREAD OF THE VARIABLE ISN'T RECOGNISED AS A USE (imageviewer iff_module.p8 pixptr)
errors.warn("removing unused variable '${decl.name}'", decl.position) errors.warn("removing unused variable '${decl.name}'", decl.position)
val assignmentsToRemove = assignTargets.map { it.parent to it.parent.parent as IStatementContainer}.toSet() val assignmentsToRemove = assignTargets.map { it.parent to it.parent.parent as IStatementContainer}.toSet()
return assignmentsToRemove.map { return assignmentsToRemove.map {

View File

@ -261,6 +261,7 @@ private fun processAst(program: Program, errors: IErrorReporter, compilerOptions
// TODO: turning char literals into UBYTEs via an encoding should really happen in code gen - but for that we'd need DataType.CHAR // TODO: turning char literals into UBYTEs via an encoding should really happen in code gen - but for that we'd need DataType.CHAR
// ...but what do we gain from this? We can leave it as it is now: where a char literal is no more than syntactic sugar for an UBYTE value. // ...but what do we gain from this? We can leave it as it is now: where a char literal is no more than syntactic sugar for an UBYTE value.
// By introduction a CHAR dt, we will also lose the opportunity to do constant-folding on any expression containing a char literal. // By introduction a CHAR dt, we will also lose the opportunity to do constant-folding on any expression containing a char literal.
// Yes this is different from strings that are only encoded in the code gen phase.
program.charLiteralsToUByteLiterals(compilerOptions.compTarget) program.charLiteralsToUByteLiterals(compilerOptions.compTarget)
program.constantFold(errors, compilerOptions.compTarget) program.constantFold(errors, compilerOptions.compTarget)
errors.report() errors.report()

View File

@ -21,6 +21,7 @@ Future
- while-expression should now also get the simplifyConditionalExpression() treatment - while-expression should now also get the simplifyConditionalExpression() treatment
- fix the asm-labels problem (github issue #62) - fix the asm-labels problem (github issue #62)
- find a way to optimize asm-subroutine param passing where it now sometimes uses the evalstack? - find a way to optimize asm-subroutine param passing where it now sometimes uses the evalstack?
- find a way to let registerArgsViaStackEvaluation not use the stack anymore
- document the various compiler command line options in more detail. See "Compiling program code" in the docs - document the various compiler command line options in more detail. See "Compiling program code" in the docs
- get rid of all TODO's in the code - get rid of all TODO's in the code
- improve testability further, add more tests - improve testability further, add more tests