From ab00822764b25aac5006d52ace1c0f29acb83e89 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 19 Sep 2022 19:41:43 +0200 Subject: [PATCH] move IR optimizer to IR Codegen module --- .../src/prog8/codegen/experimental/CodeGen.kt | 4 ++-- .../codegen/intermediate/AssignmentGen.kt | 2 +- .../codegen/intermediate/BuiltinFuncGen.kt | 2 +- .../codegen/intermediate/ExpressionGen.kt | 2 +- .../{IntermediateCodeGen.kt => IRCodeGen.kt} | 2 +- .../intermediate/IRPeepholeOptimizer.kt | 21 +++++++++++-------- codeGenIntermediate/test/TestIRPeepholeOpt.kt | 1 + .../src/prog8/codegen/virtual/VmCodeGen.kt | 4 ++-- 8 files changed, 21 insertions(+), 17 deletions(-) rename codeGenIntermediate/src/prog8/codegen/intermediate/{IntermediateCodeGen.kt => IRCodeGen.kt} (99%) rename {intermediate/src/prog8 => codeGenIntermediate/src/prog8/codegen}/intermediate/IRPeepholeOptimizer.kt (91%) diff --git a/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt index f0f43ecb5..9a8804aa7 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/CodeGen.kt @@ -6,7 +6,7 @@ import prog8.code.core.CompilationOptions import prog8.code.core.IAssemblyGenerator import prog8.code.core.IAssemblyProgram import prog8.code.core.IErrorReporter -import prog8.codegen.intermediate.IntermediateCodeGen +import prog8.codegen.intermediate.IRCodeGen import prog8.intermediate.IRFileWriter class CodeGen(private val program: PtProgram, @@ -18,7 +18,7 @@ class CodeGen(private val program: PtProgram, // you could write a code generator directly on the PtProgram AST, // but you can also use the Intermediate Representation to build a codegen on: - val irCodeGen = IntermediateCodeGen(program, symbolTable, options, errors) + val irCodeGen = IRCodeGen(program, symbolTable, options, errors) val irProgram = irCodeGen.generate() // this stub only writes the IR program to disk but doesn't generate anything else. diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index 9aece89a0..1162154bb 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -10,7 +10,7 @@ import prog8.intermediate.IRCodeInstruction import prog8.intermediate.Opcode import prog8.intermediate.VmDataType -internal class AssignmentGen(private val codeGen: IntermediateCodeGen, private val expressionEval: ExpressionGen) { +internal class AssignmentGen(private val codeGen: IRCodeGen, private val expressionEval: ExpressionGen) { internal fun translate(assignment: PtAssignment): IRCodeChunk { if(assignment.target.children.single() is PtMachineRegister) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index e743e1da3..c1dbdebb1 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -9,7 +9,7 @@ import prog8.intermediate.* import prog8.vm.Syscall -internal class BuiltinFuncGen(private val codeGen: IntermediateCodeGen, private val exprGen: ExpressionGen) { +internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGen: ExpressionGen) { fun translate(call: PtBuiltinFunctionCall, resultRegister: Int): IRCodeChunk { return when(call.name) { diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index 476d2d26c..611c0009d 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -8,7 +8,7 @@ import prog8.code.core.* import prog8.intermediate.* -internal class ExpressionGen(private val codeGen: IntermediateCodeGen) { +internal class ExpressionGen(private val codeGen: IRCodeGen) { fun translateExpression(expr: PtExpression, resultRegister: Int, resultFpRegister: Int): IRCodeChunk { require(codeGen.vmRegisters.peekNext() > resultRegister) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IntermediateCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt similarity index 99% rename from codeGenIntermediate/src/prog8/codegen/intermediate/IntermediateCodeGen.kt rename to codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 64ef7f536..2c21cd2ec 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IntermediateCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -11,7 +11,7 @@ import kotlin.io.path.readBytes import kotlin.math.pow -class IntermediateCodeGen( +class IRCodeGen( internal val program: PtProgram, internal val symbolTable: SymbolTable, internal val options: CompilationOptions, diff --git a/intermediate/src/prog8/intermediate/IRPeepholeOptimizer.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt similarity index 91% rename from intermediate/src/prog8/intermediate/IRPeepholeOptimizer.kt rename to codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt index d9cb441ef..659e26115 100644 --- a/intermediate/src/prog8/intermediate/IRPeepholeOptimizer.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt @@ -1,6 +1,8 @@ -package prog8.intermediate +package prog8.codegen.intermediate -class IRPeepholeOptimizer(private val irprog: IRProgram) { +import prog8.intermediate.* + +internal class IRPeepholeOptimizer(private val irprog: IRProgram) { fun optimize() { irprog.blocks.asSequence().flatMap { it.subroutines }.forEach { sub -> sub.chunks.forEach { chunk -> @@ -28,10 +30,10 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) { // push followed by pop to same target, or different target->replace with load var changed = false indexedInstructions.reversed().forEach { (idx, ins) -> - if(ins.opcode==Opcode.PUSH) { + if(ins.opcode== Opcode.PUSH) { if(idx < chunk.lines.size-1) { val insAfter = chunk.lines[idx+1] as? IRCodeInstruction - if(insAfter!=null && insAfter.ins.opcode ==Opcode.POP) { + if(insAfter!=null && insAfter.ins.opcode == Opcode.POP) { if(ins.reg1==insAfter.ins.reg1) { chunk.lines.removeAt(idx) chunk.lines.removeAt(idx) @@ -52,18 +54,18 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) { // sec+clc or clc+sec var changed = false indexedInstructions.reversed().forEach { (idx, ins) -> - if(ins.opcode==Opcode.SEC || ins.opcode==Opcode.CLC) { + if(ins.opcode== Opcode.SEC || ins.opcode== Opcode.CLC) { if(idx < chunk.lines.size-1) { val insAfter = chunk.lines[idx+1] as? IRCodeInstruction if(insAfter?.ins?.opcode == ins.opcode) { chunk.lines.removeAt(idx) changed = true } - else if(ins.opcode==Opcode.SEC && insAfter?.ins?.opcode==Opcode.CLC) { + else if(ins.opcode== Opcode.SEC && insAfter?.ins?.opcode== Opcode.CLC) { chunk.lines.removeAt(idx) changed = true } - else if(ins.opcode==Opcode.CLC && insAfter?.ins?.opcode==Opcode.SEC) { + else if(ins.opcode== Opcode.CLC && insAfter?.ins?.opcode== Opcode.SEC) { chunk.lines.removeAt(idx) changed = true } @@ -77,11 +79,12 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) { // jump/branch to label immediately below var changed = false indexedInstructions.reversed().forEach { (idx, ins) -> - if(ins.opcode==Opcode.JUMP && ins.labelSymbol!=null) { + val labelSymbol = ins.labelSymbol + if(ins.opcode== Opcode.JUMP && labelSymbol!=null) { // if jumping to label immediately following this if(idx < chunk.lines.size-1) { val label = chunk.lines[idx+1] as? IRCodeLabel - if(ins.labelSymbol.size==1 && label?.name == ins.labelSymbol[0]) { + if(labelSymbol.size==1 && label?.name == labelSymbol[0]) { chunk.lines.removeAt(idx) changed = true } diff --git a/codeGenIntermediate/test/TestIRPeepholeOpt.kt b/codeGenIntermediate/test/TestIRPeepholeOpt.kt index 9a1869484..14a1e5dfe 100644 --- a/codeGenIntermediate/test/TestIRPeepholeOpt.kt +++ b/codeGenIntermediate/test/TestIRPeepholeOpt.kt @@ -3,6 +3,7 @@ import io.kotest.matchers.shouldBe import prog8.code.SymbolTable import prog8.code.core.* import prog8.code.target.VMTarget +import prog8.codegen.intermediate.IRPeepholeOptimizer import prog8.intermediate.* class TestIRPeepholeOpt: FunSpec({ diff --git a/codeGenVirtual/src/prog8/codegen/virtual/VmCodeGen.kt b/codeGenVirtual/src/prog8/codegen/virtual/VmCodeGen.kt index b38de54ba..931c22da0 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/VmCodeGen.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/VmCodeGen.kt @@ -6,7 +6,7 @@ import prog8.code.core.CompilationOptions import prog8.code.core.IAssemblyGenerator import prog8.code.core.IAssemblyProgram import prog8.code.core.IErrorReporter -import prog8.codegen.intermediate.IntermediateCodeGen +import prog8.codegen.intermediate.IRCodeGen import prog8.intermediate.IRFileReader import prog8.intermediate.IRFileWriter @@ -17,7 +17,7 @@ class VmCodeGen(private val program: PtProgram, ): IAssemblyGenerator { override fun compileToAssembly(): IAssemblyProgram? { - val irCodeGen = IntermediateCodeGen(program, symbolTable, options, errors) + val irCodeGen = IRCodeGen(program, symbolTable, options, errors) val irProgram = irCodeGen.generate() // TODO only write IR file if option is set to do so