mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
comments
This commit is contained in:
parent
5fd83f2757
commit
1f60a2d8b9
@ -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) {
|
||||||
|
@ -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)
|
||||||
|
@ -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}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
|
@ -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 {
|
||||||
|
@ -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()
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user