move IR optimizer to IR Codegen module

This commit is contained in:
Irmen de Jong 2022-09-19 19:41:43 +02:00
parent b4352ad38b
commit ab00822764
8 changed files with 21 additions and 17 deletions

View File

@ -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.

View File

@ -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)

View File

@ -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) {

View File

@ -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)

View File

@ -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,

View File

@ -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
}

View File

@ -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({

View File

@ -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